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