7fe89f90b63575b612c053eb53489cda5e77d789
[samba.git] / source3 / rpc_server / srv_netlog.c
1 #define OLD_NTDOMAIN 1
2 /* 
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-1997,
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
8  *  Copyright (C) Paul Ashton                       1997.
9  *  Copyright (C) Jeremy Allison                    1998.
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *  
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *  
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  */
25
26 #include "includes.h"
27
28 extern int DEBUGLEVEL;
29
30 extern BOOL sam_logon_in_ssb;
31 extern pstring samlogon_user;
32 extern pstring global_myname;
33 extern DOM_SID global_sam_sid;
34
35 /*************************************************************************
36  init_net_r_req_chal:
37  *************************************************************************/
38
39 static void init_net_r_req_chal(NET_R_REQ_CHAL *r_c,
40                                 DOM_CHAL *srv_chal, int status)
41 {
42         DEBUG(6,("init_net_r_req_chal: %d\n", __LINE__));
43         memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data));
44         r_c->status = status;
45 }
46
47 /*************************************************************************
48  net_reply_req_chal:
49  *************************************************************************/
50
51 static BOOL net_reply_req_chal(NET_Q_REQ_CHAL *q_c, prs_struct *rdata,
52                                         DOM_CHAL *srv_chal, uint32 srv_time)
53 {
54         NET_R_REQ_CHAL r_c;
55
56         DEBUG(6,("net_reply_req_chal: %d\n", __LINE__));
57
58         /* set up the LSA REQUEST CHALLENGE response */
59         init_net_r_req_chal(&r_c, srv_chal, srv_time);
60
61         /* store the response in the SMB stream */
62         if(!net_io_r_req_chal("", &r_c, rdata, 0)) {
63                 DEBUG(0,("net_reply_req_chal: Failed to marshall NET_R_REQ_CHAL.\n"));
64                 return False;
65         }
66
67         DEBUG(6,("net_reply_req_chal: %d\n", __LINE__));
68
69         return True;
70 }
71
72 /*************************************************************************
73  net_reply_logon_ctrl2:
74  *************************************************************************/
75
76 static BOOL net_reply_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, prs_struct *rdata,
77                         uint32 flags, uint32 pdc_status, uint32 logon_attempts,
78                         uint32 tc_status, char *trust_domain_name)
79 {
80         NET_R_LOGON_CTRL2 r_l;
81
82         DEBUG(6,("net_reply_logon_ctrl2: %d\n", __LINE__));
83
84         /* set up the Logon Control2 response */
85         init_r_logon_ctrl2(&r_l, q_l->query_level,
86                            flags, pdc_status, logon_attempts,
87                            tc_status, trust_domain_name);
88
89         /* store the response in the SMB stream */
90         if(!net_io_r_logon_ctrl2("", &r_l, rdata, 0)) {
91                 DEBUG(0,("net_reply_logon_ctrl2: Failed to marshall NET_R_LOGON_CTRL2.\n"));
92                 return False;
93         }
94
95         DEBUG(6,("net_reply_logon_ctrl2: %d\n", __LINE__));
96
97         return True;
98 }
99
100 /*************************************************************************
101  net_reply_trust_dom_list:
102  *************************************************************************/
103
104 static BOOL net_reply_trust_dom_list(NET_Q_TRUST_DOM_LIST *q_t, prs_struct *rdata,
105                         uint32 num_trust_domains, char *trust_domain_name)
106 {
107         NET_R_TRUST_DOM_LIST r_t;
108
109         DEBUG(6,("net_reply_trust_dom_list: %d\n", __LINE__));
110
111         /* set up the Trusted Domain List response */
112         init_r_trust_dom(&r_t, num_trust_domains, trust_domain_name);
113
114         /* store the response in the SMB stream */
115         if(!net_io_r_trust_dom("", &r_t, rdata, 0)) {
116                 DEBUG(0,("net_reply_trust_dom_list: Failed to marshall NET_R_TRUST_DOM_LIST.\n"));
117                 return False;
118         }
119
120         DEBUG(6,("net_reply_trust_dom_listlogon_ctrl2: %d\n", __LINE__));
121
122         return True;
123 }
124
125 /*************************************************************************
126  init_net_r_auth_2:
127  *************************************************************************/
128
129 static void init_net_r_auth_2(NET_R_AUTH_2 *r_a,
130                               DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status)
131 {
132         memcpy(r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
133         memcpy(&r_a->srv_flgs, flgs, sizeof(r_a->srv_flgs));
134         r_a->status = status;
135 }
136
137 /************************************************************************
138  net_reply_auth_2:
139  *************************************************************************/
140
141 static BOOL net_reply_auth_2(NET_Q_AUTH_2 *q_a, prs_struct *rdata,
142                                 DOM_CHAL *resp_cred, int status)
143 {
144         NET_R_AUTH_2 r_a;
145         NEG_FLAGS srv_flgs;
146
147         srv_flgs.neg_flags = 0x000001ff;
148
149         /* set up the LSA AUTH 2 response */
150
151         init_net_r_auth_2(&r_a, resp_cred, &srv_flgs, status);
152
153         /* store the response in the SMB stream */
154         if(!net_io_r_auth_2("", &r_a, rdata, 0)) {
155                 DEBUG(0,("net_reply_auth_2: Failed to marshall NET_R_AUTH_2.\n"));
156                 return False;
157         }
158
159         return True;
160 }
161
162 /***********************************************************************************
163  init_net_r_srv_pwset:
164  ***********************************************************************************/
165
166 static void init_net_r_srv_pwset(NET_R_SRV_PWSET *r_s,
167                              DOM_CRED *srv_cred, int status)  
168 {
169         DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__));
170
171         memcpy(&r_s->srv_cred, srv_cred, sizeof(r_s->srv_cred));
172         r_s->status = status;
173
174         DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__));
175 }
176
177 /*************************************************************************
178  net_reply_srv_pwset:
179  *************************************************************************/
180
181 static BOOL net_reply_srv_pwset(NET_Q_SRV_PWSET *q_s, prs_struct *rdata,
182                                 DOM_CRED *srv_cred, int status)
183 {
184         NET_R_SRV_PWSET r_s;
185
186         DEBUG(5,("net_srv_pwset: %d\n", __LINE__));
187
188         /* set up the LSA Server Password Set response */
189         init_net_r_srv_pwset(&r_s, srv_cred, status);
190
191         /* store the response in the SMB stream */
192         if(!net_io_r_srv_pwset("", &r_s, rdata, 0)) {
193                 DEBUG(0,("net_reply_srv_pwset: Failed to marshall NET_R_SRV_PWSET.\n"));
194                 return False;
195         }
196
197         DEBUG(5,("net_srv_pwset: %d\n", __LINE__));
198
199         return True;
200 }
201
202 /*************************************************************************
203  net_reply_sam_logon:
204  *************************************************************************/
205
206 static BOOL net_reply_sam_logon(NET_Q_SAM_LOGON *q_s, prs_struct *rdata,
207                                 DOM_CRED *srv_cred, NET_USER_INFO_3 *user_info,
208                                 uint32 status)
209 {
210         NET_R_SAM_LOGON r_s;
211
212         /* XXXX maybe we want to say 'no', reject the client's credentials */
213         r_s.buffer_creds = 1; /* yes, we have valid server credentials */
214         memcpy(&r_s.srv_creds, srv_cred, sizeof(r_s.srv_creds));
215
216         /* store the user information, if there is any. */
217         r_s.user = user_info;
218         if (status == 0x0 && user_info != NULL && user_info->ptr_user_info != 0)
219                 r_s.switch_value = 3; /* indicates type of validation user info */
220         else
221                 r_s.switch_value = 0; /* indicates no info */
222
223         r_s.status = status;
224         r_s.auth_resp = 1; /* authoritative response */
225
226         /* store the response in the SMB stream */
227         if(!net_io_r_sam_logon("", &r_s, rdata, 0)) {
228                 DEBUG(0,("net_reply_sam_logon: Failed to marshall NET_R_SAM_LOGON.\n"));
229                 return False;
230         }
231
232         return True;
233 }
234
235
236 /*************************************************************************
237  net_reply_sam_logoff:
238  *************************************************************************/
239
240 static BOOL net_reply_sam_logoff(NET_Q_SAM_LOGOFF *q_s, prs_struct *rdata,
241                                 DOM_CRED *srv_cred, 
242                                 uint32 status)
243 {
244         NET_R_SAM_LOGOFF r_s;
245
246         /* XXXX maybe we want to say 'no', reject the client's credentials */
247         r_s.buffer_creds = 1; /* yes, we have valid server credentials */
248         memcpy(&r_s.srv_creds, srv_cred, sizeof(r_s.srv_creds));
249
250         r_s.status = status;
251
252         /* store the response in the SMB stream */
253         if(!net_io_r_sam_logoff("", &r_s, rdata, 0)) {
254                 DEBUG(0,("net_reply_sam_logoff: Failed to marshall NET_R_SAM_LOGOFF.\n"));
255                 return False;
256         }
257
258         return True;
259 }
260
261 /******************************************************************
262  gets a machine password entry.  checks access rights of the host.
263  ******************************************************************/
264
265 static BOOL get_md4pw(char *md4pw, char *mach_name, char *mach_acct)
266 {
267         struct smb_passwd *smb_pass;
268
269 #if 0
270     /*
271      * Currently this code is redundent as we already have a filter
272      * by hostname list. What this code really needs to do is to 
273      * get a hosts allowed/hosts denied list from the SAM database
274      * on a per user basis, and make the access decision there.
275      * I will leave this code here for now as a reminder to implement
276      * this at a later date. JRA.
277      */
278
279         if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
280                           client_name(), client_addr()))
281         {
282                 DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct));
283                 return False;
284         }
285 #endif /* 0 */
286
287         become_root();
288         smb_pass = getsmbpwnam(mach_acct);
289         unbecome_root();
290
291         if ((smb_pass) != NULL && !(smb_pass->acct_ctrl & ACB_DISABLED) &&
292         (smb_pass->smb_nt_passwd != NULL))
293         {
294                 memcpy(md4pw, smb_pass->smb_nt_passwd, 16);
295                 dump_data(5, md4pw, 16);
296
297                 return True;
298         }
299         DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
300         return False;
301 }
302
303 /*************************************************************************
304  api_net_req_chal:
305  *************************************************************************/
306
307 static BOOL api_net_req_chal(pipes_struct *p)
308 {
309         NET_Q_REQ_CHAL q_r;
310         uint32 status = 0x0;
311         uint16 vuid = p->vuid;
312         prs_struct *data = &p->in_data.data;
313         prs_struct *rdata = &p->out_data.rdata;
314
315         fstring mach_acct;
316         fstring mach_name;
317
318         user_struct *vuser;
319
320         DEBUG(5,("api_net_req_chal(%d): vuid %d\n", __LINE__, (int)vuid));
321
322         if ((vuser = get_valid_user_struct(vuid)) == NULL)
323                 return False;
324
325         /* grab the challenge... */
326         if(!net_io_q_req_chal("", &q_r, data, 0)) {
327                 DEBUG(0,("api_net_req_chal: Failed to unmarshall NET_Q_REQ_CHAL.\n"));
328                 return False;
329         }
330
331         fstrcpy(mach_acct, dos_unistrn2(q_r.uni_logon_clnt.buffer,
332                                     q_r.uni_logon_clnt.uni_str_len));
333
334         fstrcpy(mach_name, mach_acct);
335         strlower(mach_name);
336
337         fstrcat(mach_acct, "$");
338
339         if (get_md4pw((char *)vuser->dc.md4pw, mach_name, mach_acct)) {
340                 /* copy the client credentials */
341                 memcpy(vuser->dc.clnt_chal.data          , q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
342                 memcpy(vuser->dc.clnt_cred.challenge.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
343
344                 /* create a server challenge for the client */
345                 /* Set these to random values. */
346                 generate_random_buffer(vuser->dc.srv_chal.data, 8, False);
347
348                 memcpy(vuser->dc.srv_cred.challenge.data, vuser->dc.srv_chal.data, 8);
349
350                 memset((char *)vuser->dc.sess_key, '\0', sizeof(vuser->dc.sess_key));
351
352                 /* from client / server challenges and md4 password, generate sess key */
353                 cred_session_key(&(vuser->dc.clnt_chal), &(vuser->dc.srv_chal),
354                                  (char *)vuser->dc.md4pw, vuser->dc.sess_key);
355         } else {
356                 /* lkclXXXX take a guess at a good error message to return :-) */
357                 status = 0xC0000000 | NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
358         }
359
360         /* construct reply. */
361         if(!net_reply_req_chal(&q_r, rdata, &vuser->dc.srv_chal, status))
362                 return False;
363
364         return True;
365 }
366
367 /*************************************************************************
368  api_net_auth_2:
369  *************************************************************************/
370
371 static BOOL api_net_auth_2(pipes_struct *p)
372 {
373         uint16 vuid = p->vuid;
374         NET_Q_AUTH_2 q_a;
375         uint32 status = 0x0;
376         prs_struct *data = &p->in_data.data;
377         prs_struct *rdata = &p->out_data.rdata;
378
379         DOM_CHAL srv_cred;
380         UTIME srv_time;
381
382         user_struct *vuser;
383
384         if ((vuser = get_valid_user_struct(vuid)) == NULL)
385                 return False;
386
387         srv_time.time = 0;
388
389         /* grab the challenge... */
390         if(!net_io_q_auth_2("", &q_a, data, 0)) {
391                 DEBUG(0,("api_net_auth_2: Failed to unmarshall NET_Q_AUTH_2.\n"));
392                 return False;
393         }
394
395         /* check that the client credentials are valid */
396         if (cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key,
397                     &(vuser->dc.clnt_cred.challenge), srv_time)) {
398
399                 /* create server challenge for inclusion in the reply */
400                 cred_create(vuser->dc.sess_key, &(vuser->dc.srv_cred.challenge), srv_time, &srv_cred);
401
402                 /* copy the received client credentials for use next time */
403                 memcpy(vuser->dc.clnt_cred.challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
404                 memcpy(vuser->dc.srv_cred .challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
405         } else {
406                 status = NT_STATUS_ACCESS_DENIED | 0xC0000000;
407         }
408
409         /* construct reply. */
410         if(!net_reply_auth_2(&q_a, rdata, &srv_cred, status))
411                 return False;
412
413         return True;
414 }
415
416
417 /*************************************************************************
418  api_net_srv_pwset:
419  *************************************************************************/
420
421 static BOOL api_net_srv_pwset(pipes_struct *p)
422 {
423         uint16 vuid = p->vuid;
424         NET_Q_SRV_PWSET q_a;
425         uint32 status = NT_STATUS_WRONG_PASSWORD|0xC0000000;
426         DOM_CRED srv_cred;
427         pstring mach_acct;
428         struct smb_passwd *smb_pass;
429         BOOL ret;
430         user_struct *vuser;
431         prs_struct *data = &p->in_data.data;
432         prs_struct *rdata = &p->out_data.rdata;
433
434         if ((vuser = get_valid_user_struct(vuid)) == NULL)
435                 return False;
436
437         /* grab the challenge and encrypted password ... */
438         if(!net_io_q_srv_pwset("", &q_a, data, 0)) {
439                 DEBUG(0,("api_net_srv_pwset: Failed to unmarshall NET_Q_SRV_PWSET.\n"));
440                 return False;
441         }
442
443         /* checks and updates credentials.  creates reply credentials */
444         if (deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred), 
445                             &(q_a.clnt_id.cred), &srv_cred))
446         {
447                 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
448
449                 DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
450
451                 pstrcpy(mach_acct, dos_unistrn2(q_a.clnt_id.login.uni_acct_name.buffer,
452                                             q_a.clnt_id.login.uni_acct_name.uni_str_len));
453
454                 DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
455
456                 become_root();
457                 smb_pass = getsmbpwnam(mach_acct);
458                 unbecome_root();
459
460                 if (smb_pass != NULL) {
461                         unsigned char pwd[16];
462                         int i;
463
464                         DEBUG(100,("Server password set : new given value was :\n"));
465                         for(i = 0; i < 16; i++)
466                                 DEBUG(100,("%02X ", q_a.pwd[i]));
467                         DEBUG(100,("\n"));
468
469                         cred_hash3( pwd, q_a.pwd, vuser->dc.sess_key, 0);
470
471                         /* lies!  nt and lm passwords are _not_ the same: don't care */
472                         smb_pass->smb_passwd    = pwd;
473                         smb_pass->smb_nt_passwd = pwd;
474                         smb_pass->acct_ctrl     = ACB_WSTRUST;
475
476                         become_root();
477                         ret = mod_smbpwd_entry(smb_pass,False);
478                         unbecome_root();
479
480                         if (ret) {
481                                 /* hooray! */
482                                 status = 0x0;
483                         }
484                 }
485
486                 DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
487
488         } else {
489                 /* lkclXXXX take a guess at a sensible error code to return... */
490                 status = 0xC0000000 | NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
491         }
492
493         /* Construct reply. */
494         if(!net_reply_srv_pwset(&q_a, rdata, &srv_cred, status))
495                 return False;
496
497         return True;
498 }
499
500
501 /*************************************************************************
502  api_net_sam_logoff:
503  *************************************************************************/
504
505 static BOOL api_net_sam_logoff(pipes_struct *p)
506 {
507         uint16 vuid = p->vuid;
508         NET_Q_SAM_LOGOFF q_l;
509         NET_ID_INFO_CTR ctr;    
510         DOM_CRED srv_cred;
511         prs_struct *data = &p->in_data.data;
512         prs_struct *rdata = &p->out_data.rdata;
513
514         user_struct *vuser;
515
516         if ((vuser = get_valid_user_struct(vuid)) == NULL)
517                 return False;
518
519         /* the DOM_ID_INFO_1 structure is a bit big.  plus we might want to
520            dynamically allocate it inside net_io_q_sam_logon, at some point */
521         q_l.sam_id.ctr = &ctr;
522
523         /* grab the challenge... */
524         if(!net_io_q_sam_logoff("", &q_l, data, 0)) {
525                 DEBUG(0,("api_net_sam_logoff: Failed to unmarshall NET_Q_SAM_LOGOFF.\n"));
526                 return False;
527         }
528
529         /* checks and updates credentials.  creates reply credentials */
530         deal_with_creds(vuser->dc.sess_key, &vuser->dc.clnt_cred, 
531                         &q_l.sam_id.client.cred, &srv_cred);
532         memcpy(&vuser->dc.srv_cred, &vuser->dc.clnt_cred, sizeof(vuser->dc.clnt_cred));
533
534         /* construct reply.  always indicate success */
535         if(!net_reply_sam_logoff(&q_l, rdata, &srv_cred, 0x0))
536                 return False;
537
538         return True;
539 }
540
541 /*************************************************************************
542  net_login_interactive:
543  *************************************************************************/
544
545 static uint32 net_login_interactive(NET_ID_INFO_1 *id1, struct smb_passwd *smb_pass,
546                                 user_struct *vuser)
547 {
548         uint32 status = 0x0;
549
550         char nt_pwd[16];
551         char lm_pwd[16];
552         unsigned char key[16];
553
554         memset(key, 0, 16);
555         memcpy(key, vuser->dc.sess_key, 8);
556
557         memcpy(lm_pwd, id1->lm_owf.data, 16);
558         memcpy(nt_pwd, id1->nt_owf.data, 16);
559
560 #ifdef DEBUG_PASSWORD
561         DEBUG(100,("key:"));
562         dump_data(100, (char *)key, 16);
563
564         DEBUG(100,("lm owf password:"));
565         dump_data(100, lm_pwd, 16);
566
567         DEBUG(100,("nt owf password:"));
568         dump_data(100, nt_pwd, 16);
569 #endif
570
571         SamOEMhash((uchar *)lm_pwd, key, False);
572         SamOEMhash((uchar *)nt_pwd, key, False);
573
574 #ifdef DEBUG_PASSWORD
575         DEBUG(100,("decrypt of lm owf password:"));
576         dump_data(100, lm_pwd, 16);
577
578         DEBUG(100,("decrypt of nt owf password:"));
579         dump_data(100, nt_pwd, 16);
580 #endif
581
582         if (memcmp(smb_pass->smb_passwd   , lm_pwd, 16) != 0 ||
583             memcmp(smb_pass->smb_nt_passwd, nt_pwd, 16) != 0)
584         {
585                 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
586         }
587
588         return status;
589 }
590
591 /*************************************************************************
592  net_login_network:
593  *************************************************************************/
594
595 static uint32 net_login_network(NET_ID_INFO_2 *id2, struct smb_passwd *smb_pass)
596 {
597         DEBUG(5,("net_login_network: lm_len: %d nt_len: %d\n",
598                 id2->hdr_lm_chal_resp.str_str_len, 
599                 id2->hdr_nt_chal_resp.str_str_len));
600
601         /* JRA. Check the NT password first if it exists - this is a higher quality 
602            password, if it exists and it doesn't match - fail. */
603
604         if (id2->hdr_nt_chal_resp.str_str_len == 24 && 
605                 smb_pass->smb_nt_passwd != NULL)
606         {
607                 if(smb_password_check((char *)id2->nt_chal_resp.buffer,
608                                    smb_pass->smb_nt_passwd,
609                            id2->lm_chal)) 
610                         return 0x0;
611                 else
612                         return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
613         }
614
615         /* lkclXXXX this is not a good place to put disabling of LM hashes in.
616            if that is to be done, first move this entire function into a
617            library routine that calls the two smb_password_check() functions.
618            if disabling LM hashes (which nt can do for security reasons) then
619            an attempt should be made to disable them everywhere (which nt does
620            not do, for various security-hole reasons).
621          */
622
623         if (id2->hdr_lm_chal_resp.str_str_len == 24 &&
624                 smb_password_check((char *)id2->lm_chal_resp.buffer,
625                                    smb_pass->smb_passwd,
626                                    id2->lm_chal))
627         {
628                 return 0x0;
629         }
630
631
632         /* oops! neither password check succeeded */
633
634         return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
635 }
636
637 /*************************************************************************
638  api_net_sam_logon:
639  *************************************************************************/
640
641 static BOOL api_net_sam_logon(pipes_struct *p)
642 {
643     uint16 vuid = p->vuid;
644     NET_Q_SAM_LOGON q_l;
645     NET_ID_INFO_CTR ctr;        
646     NET_USER_INFO_3 usr_info;
647     uint32 status = 0x0;
648     DOM_CRED srv_cred;
649     struct smb_passwd *smb_pass = NULL;
650     UNISTR2 *uni_samlogon_user = NULL;
651     fstring nt_username;
652     struct passwd *pw;
653         prs_struct *data = &p->in_data.data;
654         prs_struct *rdata = &p->out_data.rdata;
655     
656     user_struct *vuser = NULL;
657     
658     if ((vuser = get_valid_user_struct(vuid)) == NULL)
659         return False;
660     
661     memset(&q_l, '\0', sizeof(q_l));
662     memset(&ctr, '\0', sizeof(ctr));
663     memset(&usr_info, '\0', sizeof(usr_info));
664     
665     q_l.sam_id.ctr = &ctr;
666     
667     if(!net_io_q_sam_logon("", &q_l, data, 0)) {
668         DEBUG(0,
669               ("api_net_sam_logon: Failed to unmarshall NET_Q_SAM_LOGON.\n"));
670         return False;
671     }
672     
673     /* checks and updates credentials.  creates reply credentials */
674     if (!deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred), 
675                          &(q_l.sam_id.client.cred), &srv_cred))
676         status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
677     else
678         memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), 
679                sizeof(vuser->dc.clnt_cred));
680     
681     /* find the username */
682     
683     if (status == 0) {
684         switch (q_l.sam_id.logon_level) {
685         case INTERACTIVE_LOGON_TYPE:
686             uni_samlogon_user = &q_l.sam_id.ctr->auth.id1.uni_user_name;
687             
688             DEBUG(3,("SAM Logon (Interactive). Domain:[%s].  ", 
689                      lp_workgroup()));
690             break;
691         case NET_LOGON_TYPE:
692             uni_samlogon_user = &q_l.sam_id.ctr->auth.id2.uni_user_name;
693             
694             DEBUG(3,("SAM Logon (Network). Domain:[%s].  ", lp_workgroup()));
695             break;
696         default:
697             DEBUG(2,("SAM Logon: unsupported switch value\n"));
698             status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
699             break;
700         } /* end switch */
701     } /* end if status == 0 */
702
703   /* check username exists */
704
705     if (status == 0) {
706         pstrcpy(nt_username, dos_unistrn2(uni_samlogon_user->buffer,
707                                           uni_samlogon_user->uni_str_len));
708
709         DEBUG(3,("User:[%s]\n", nt_username));
710         
711         /*
712          * Convert to a UNIX username.
713          */
714         map_username(nt_username);
715
716         /*
717          * Do any case conversions.
718          */
719         pw=Get_Pwnam(nt_username, True);
720         
721         become_root();
722         smb_pass = getsmbpwnam(nt_username);
723         unbecome_root();
724         
725         if (smb_pass == NULL)
726             status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
727         else if (smb_pass->acct_ctrl & ACB_PWNOTREQ)
728             status = 0;
729         else if (smb_pass->acct_ctrl & ACB_DISABLED)
730             status =  0xC0000000 | NT_STATUS_ACCOUNT_DISABLED;
731     }
732     
733     /* Validate password - if required. */
734     
735     if ((status == 0) && !(smb_pass->acct_ctrl & ACB_PWNOTREQ)) {
736         switch (q_l.sam_id.logon_level) {
737         case INTERACTIVE_LOGON_TYPE:
738             /* interactive login. */
739             status = net_login_interactive(&q_l.sam_id.ctr->auth.id1, 
740                                            smb_pass, vuser);
741             break;
742         case NET_LOGON_TYPE:
743             /* network login.  lm challenge and 24 byte responses */
744             status = net_login_network(&q_l.sam_id.ctr->auth.id2, smb_pass);
745             break;
746         }
747     }
748     
749     /* lkclXXXX this is the point at which, if the login was
750        successful, that the SAM Local Security Authority should
751        record that the user is logged in to the domain.
752     */
753     
754     /* return the profile plus other bits :-) */
755     
756     if (status == 0) {
757         DOM_GID *gids = NULL;
758         int num_gids = 0;
759         NTTIME dummy_time;
760         pstring logon_script;
761         pstring profile_path;
762         pstring home_dir;
763         pstring home_drive;
764         pstring my_name;
765         pstring my_workgroup;
766         pstring domain_groups;
767         uint32 r_uid;
768         uint32 r_gid;
769         fstring full_name;
770         
771         /* set up pointer indicating user/password failed to be found */
772         usr_info.ptr_user_info = 0;
773         
774         dummy_time.low  = 0xffffffff;
775         dummy_time.high = 0x7fffffff;
776         
777         /* XXXX hack to get standard_sub_basic() to use sam logon username */
778         /* possibly a better way would be to do a become_user() call */
779         sam_logon_in_ssb = True;
780         pstrcpy(samlogon_user, nt_username);
781
782         pstrcpy(logon_script, lp_logon_script());
783         standard_sub_advanced(-1, nt_username, "", pw->pw_gid, logon_script);
784         
785         pstrcpy(profile_path, lp_logon_path());
786         standard_sub_advanced(-1, nt_username, "", pw->pw_gid, profile_path);
787         
788         pstrcpy(my_workgroup, lp_workgroup());
789         
790         pstrcpy(home_drive, lp_logon_drive());
791         standard_sub_advanced(-1, nt_username, "", pw->pw_gid, home_drive);
792
793         pstrcpy(home_dir, lp_logon_home());
794         standard_sub_advanced(-1, nt_username, "", pw->pw_gid, home_dir);
795         
796         pstrcpy(my_name, global_myname);
797         strupper(my_name);
798
799         fstrcpy(full_name, "<Full Name>");
800         if (lp_unix_realname())
801                 fstrcpy(full_name, pw->pw_gecos);
802         
803         /*
804          * This is the point at which we get the group
805          * database - we should be getting the gid_t list
806          * from /etc/group and then turning the uids into
807          * rids and then into machine sids for this user.
808          * JRA.
809          */
810         
811         get_domain_user_groups(domain_groups, nt_username);
812         
813         /*
814          * make_dom_gids allocates the gids array. JRA.
815          */
816         gids = NULL;
817         num_gids = make_dom_gids(domain_groups, &gids);
818         
819         sam_logon_in_ssb = False;
820         
821         if (pdb_name_to_rid(nt_username, &r_uid, &r_gid))
822             init_net_user_info3(&usr_info,
823                                 &dummy_time, /* logon_time */
824                                 &dummy_time, /* logoff_time */
825                                 &dummy_time, /* kickoff_time */
826                                 &dummy_time, /* pass_last_set_time */
827                                 &dummy_time, /* pass_can_change_time */
828                                 &dummy_time, /* pass_must_change_time */
829                                 
830                                 nt_username   , /* user_name */
831                                 full_name,      /* full_name */
832                                 logon_script    , /* logon_script */
833                                 profile_path    , /* profile_path */
834                                 home_dir        , /* home_dir */
835                                 home_drive      , /* dir_drive */
836                                 
837                                 0, /* logon_count */
838                                 0, /* bad_pw_count */
839                                 
840                                 r_uid   , /* RID user_id */
841                                 r_gid   , /* RID group_id */
842                                 num_gids,    /* uint32 num_groups */
843                                 gids    , /* DOM_GID *gids */
844                                 0x20    , /* uint32 user_flgs (?) */
845                                 
846                                 NULL, /* char sess_key[16] */
847                                 
848                                 my_name     , /* char *logon_srv */
849                                 my_workgroup, /* char *logon_dom */
850                                 
851                                 &global_sam_sid,     /* DOM_SID *dom_sid */
852                                 NULL); /* char *other_sids */
853         else
854             status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
855         
856         /* Free any allocated groups array. */
857         if(gids)
858             free((char *)gids);
859     }
860     
861     if(!net_reply_sam_logon(&q_l, rdata, &srv_cred, &usr_info, status))
862         return False;
863     
864     return True;
865 }
866
867
868 /*************************************************************************
869  api_net_trust_dom_list:
870  *************************************************************************/
871
872 static BOOL api_net_trust_dom_list(pipes_struct *p)
873 {
874         NET_Q_TRUST_DOM_LIST q_t;
875         prs_struct *data = &p->in_data.data;
876         prs_struct *rdata = &p->out_data.rdata;
877
878         char *trusted_domain = "test_domain";
879
880         DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
881
882         /* grab the lsa trusted domain list query... */
883         if(!net_io_q_trust_dom("", &q_t, data, 0)) {
884                 DEBUG(0,("api_net_trust_dom_list: Failed to unmarshall NET_Q_TRUST_DOM_LIST.\n"));
885                 return False;
886         }
887
888         /* construct reply. */
889         if(!net_reply_trust_dom_list(&q_t, rdata, 1, trusted_domain))
890                 return False;
891
892         DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
893
894         return True;
895 }
896
897
898 /*************************************************************************
899  error messages cropping up when using nltest.exe...
900  *************************************************************************/
901 #define ERROR_NO_SUCH_DOMAIN   0x54b
902 #define ERROR_NO_LOGON_SERVERS 0x51f
903
904 /*************************************************************************
905  api_net_logon_ctrl2:
906  *************************************************************************/
907
908 static BOOL api_net_logon_ctrl2(pipes_struct *p)
909 {
910         NET_Q_LOGON_CTRL2 q_l;
911         prs_struct *data = &p->in_data.data;
912         prs_struct *rdata = &p->out_data.rdata;
913
914         /* lkclXXXX - guess what - absolutely no idea what these are! */
915         uint32 flags = 0x0;
916         uint32 pdc_connection_status = 0x0;
917         uint32 logon_attempts = 0x0;
918         uint32 tc_status = ERROR_NO_LOGON_SERVERS;
919         char *trusted_domain = "test_domain";
920
921         DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
922
923         /* grab the lsa netlogon ctrl2 query... */
924         if(!net_io_q_logon_ctrl2("", &q_l, data, 0)) {
925                 DEBUG(0,("api_net_logon_ctrl2: Failed to unmarshall NET_Q_LOGON_CTRL2.\n"));
926                 return False;
927         }
928
929         /* construct reply. */
930         if(!net_reply_logon_ctrl2(&q_l, rdata,
931                                 flags, pdc_connection_status, logon_attempts,
932                                 tc_status, trusted_domain))
933                 return False;
934
935         DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
936
937         return True;
938 }
939
940 /*******************************************************************
941  array of \PIPE\NETLOGON operations
942  ********************************************************************/
943 static struct api_struct api_net_cmds [] =
944 {
945         { "NET_REQCHAL"       , NET_REQCHAL       , api_net_req_chal       }, 
946         { "NET_AUTH2"         , NET_AUTH2         , api_net_auth_2         }, 
947         { "NET_SRVPWSET"      , NET_SRVPWSET      , api_net_srv_pwset      }, 
948         { "NET_SAMLOGON"      , NET_SAMLOGON      , api_net_sam_logon      }, 
949         { "NET_SAMLOGOFF"     , NET_SAMLOGOFF     , api_net_sam_logoff     }, 
950         { "NET_LOGON_CTRL2"   , NET_LOGON_CTRL2   , api_net_logon_ctrl2    }, 
951         { "NET_TRUST_DOM_LIST", NET_TRUST_DOM_LIST, api_net_trust_dom_list },
952         {  NULL               , 0                 , NULL                   }
953 };
954
955 /*******************************************************************
956  receives a netlogon pipe and responds.
957  ********************************************************************/
958
959 BOOL api_netlog_rpc(pipes_struct *p)
960 {
961         return api_rpcTNP(p, "api_netlog_rpc", api_net_cmds);
962 }
963 #undef OLD_NTDOMAIN