Large commit which restructures the local password storage API.
[mimir/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         SAM_ACCOUNT     *sampass = NULL;
268         BYTE            *pass = NULL;
269
270 #if 0
271     /*
272      * Currently this code is redundent as we already have a filter
273      * by hostname list. What this code really needs to do is to 
274      * get a hosts allowed/hosts denied list from the SAM database
275      * on a per user basis, and make the access decision there.
276      * I will leave this code here for now as a reminder to implement
277      * this at a later date. JRA.
278      */
279
280         if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
281                           client_name(), client_addr()))
282         {
283                 DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct));
284                 return False;
285         }
286 #endif /* 0 */
287
288         become_root();
289         sampass = pdb_getsampwnam(mach_acct);
290         unbecome_root();
291
292         if ((sampass) != NULL && !(pdb_get_acct_ctrl(sampass) & ACB_DISABLED) &&
293         ((pass=pdb_get_nt_passwd(sampass)) != NULL))
294         {
295                 memcpy(md4pw, pass, 16);
296                 dump_data(5, md4pw, 16);
297
298                 return True;
299         }
300         DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
301         return False;
302 }
303
304 /*************************************************************************
305  api_net_req_chal:
306  *************************************************************************/
307
308 static BOOL api_net_req_chal(pipes_struct *p)
309 {
310         NET_Q_REQ_CHAL q_r;
311         uint32 status = 0x0;
312         uint16 vuid = p->vuid;
313         prs_struct *data = &p->in_data.data;
314         prs_struct *rdata = &p->out_data.rdata;
315
316         fstring mach_acct;
317         fstring mach_name;
318
319         user_struct *vuser;
320
321         DEBUG(5,("api_net_req_chal(%d): vuid %d\n", __LINE__, (int)vuid));
322
323         if ((vuser = get_valid_user_struct(vuid)) == NULL)
324                 return False;
325
326         /* grab the challenge... */
327         if(!net_io_q_req_chal("", &q_r, data, 0)) {
328                 DEBUG(0,("api_net_req_chal: Failed to unmarshall NET_Q_REQ_CHAL.\n"));
329                 return False;
330         }
331
332         fstrcpy(mach_acct, dos_unistrn2(q_r.uni_logon_clnt.buffer,
333                                     q_r.uni_logon_clnt.uni_str_len));
334
335         fstrcpy(mach_name, mach_acct);
336         strlower(mach_name);
337
338         fstrcat(mach_acct, "$");
339
340         if (get_md4pw((char *)vuser->dc.md4pw, mach_name, mach_acct)) {
341                 /* copy the client credentials */
342                 memcpy(vuser->dc.clnt_chal.data          , q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
343                 memcpy(vuser->dc.clnt_cred.challenge.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
344
345                 /* create a server challenge for the client */
346                 /* Set these to random values. */
347                 generate_random_buffer(vuser->dc.srv_chal.data, 8, False);
348
349                 memcpy(vuser->dc.srv_cred.challenge.data, vuser->dc.srv_chal.data, 8);
350
351                 memset((char *)vuser->dc.sess_key, '\0', sizeof(vuser->dc.sess_key));
352
353                 /* from client / server challenges and md4 password, generate sess key */
354                 cred_session_key(&(vuser->dc.clnt_chal), &(vuser->dc.srv_chal),
355                                  (char *)vuser->dc.md4pw, vuser->dc.sess_key);
356         } else {
357                 /* lkclXXXX take a guess at a good error message to return :-) */
358                 status = NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
359         }
360
361         /* construct reply. */
362         if(!net_reply_req_chal(&q_r, rdata, &vuser->dc.srv_chal, status))
363                 return False;
364
365         return True;
366 }
367
368 /*************************************************************************
369  api_net_auth_2:
370  *************************************************************************/
371
372 static BOOL api_net_auth_2(pipes_struct *p)
373 {
374         uint16 vuid = p->vuid;
375         NET_Q_AUTH_2 q_a;
376         uint32 status = 0x0;
377         prs_struct *data = &p->in_data.data;
378         prs_struct *rdata = &p->out_data.rdata;
379
380         DOM_CHAL srv_cred;
381         UTIME srv_time;
382
383         user_struct *vuser;
384
385         if ((vuser = get_valid_user_struct(vuid)) == NULL)
386                 return False;
387
388         srv_time.time = 0;
389
390         /* grab the challenge... */
391         if(!net_io_q_auth_2("", &q_a, data, 0)) {
392                 DEBUG(0,("api_net_auth_2: Failed to unmarshall NET_Q_AUTH_2.\n"));
393                 return False;
394         }
395
396         /* check that the client credentials are valid */
397         if (cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key,
398                     &(vuser->dc.clnt_cred.challenge), srv_time)) {
399
400                 /* create server challenge for inclusion in the reply */
401                 cred_create(vuser->dc.sess_key, &(vuser->dc.srv_cred.challenge), srv_time, &srv_cred);
402
403                 /* copy the received client credentials for use next time */
404                 memcpy(vuser->dc.clnt_cred.challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
405                 memcpy(vuser->dc.srv_cred .challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
406         } else {
407                 status = NT_STATUS_ACCESS_DENIED;
408         }
409
410         /* construct reply. */
411         if(!net_reply_auth_2(&q_a, rdata, &srv_cred, status))
412                 return False;
413
414         return True;
415 }
416
417
418 /*************************************************************************
419  api_net_srv_pwset:
420  *************************************************************************/
421
422 static BOOL api_net_srv_pwset(pipes_struct *p)
423 {
424         uint16 vuid = p->vuid;
425         NET_Q_SRV_PWSET q_a;
426         uint32 status = NT_STATUS_WRONG_PASSWORD;
427         DOM_CRED srv_cred;
428         pstring mach_acct;
429         SAM_ACCOUNT *sampass;
430         BOOL ret;
431         user_struct *vuser;
432         prs_struct *data = &p->in_data.data;
433         prs_struct *rdata = &p->out_data.rdata;
434
435         if ((vuser = get_valid_user_struct(vuid)) == NULL)
436                 return False;
437
438         /* grab the challenge and encrypted password ... */
439         if(!net_io_q_srv_pwset("", &q_a, data, 0)) {
440                 DEBUG(0,("api_net_srv_pwset: Failed to unmarshall NET_Q_SRV_PWSET.\n"));
441                 return False;
442         }
443
444         /* checks and updates credentials.  creates reply credentials */
445         if (deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred), 
446                             &(q_a.clnt_id.cred), &srv_cred))
447         {
448                 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
449
450                 DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
451
452                 pstrcpy(mach_acct, dos_unistrn2(q_a.clnt_id.login.uni_acct_name.buffer,
453                                             q_a.clnt_id.login.uni_acct_name.uni_str_len));
454
455                 DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
456
457                 become_root();
458                 sampass = pdb_getsampwnam(mach_acct);
459                 unbecome_root();
460
461                 if (sampass != NULL) {
462                         unsigned char pwd[16];
463                         int i;
464
465                         DEBUG(100,("Server password set : new given value was :\n"));
466                         for(i = 0; i < 16; i++)
467                                 DEBUG(100,("%02X ", q_a.pwd[i]));
468                         DEBUG(100,("\n"));
469
470                         cred_hash3( pwd, q_a.pwd, vuser->dc.sess_key, 0);
471
472                         /* lies!  nt and lm passwords are _not_ the same: don't care */
473                         pdb_set_lanman_passwd (sampass, pwd);
474                         pdb_set_nt_passwd     (sampass, pwd);
475                         pdb_set_acct_ctrl     (sampass, ACB_WSTRUST);
476
477                         become_root();                  
478                         ret = pdb_update_sam_account (sampass,False);
479                         unbecome_root();
480
481                         if (ret) {
482                                 /* hooray! */
483                                 status = 0x0;
484                         }
485                 }
486
487                 DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
488
489         } else {
490                 /* lkclXXXX take a guess at a sensible error code to return... */
491                 status = NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
492         }
493
494         /* Construct reply. */
495         if(!net_reply_srv_pwset(&q_a, rdata, &srv_cred, status))
496                 return False;
497
498         return True;
499 }
500
501
502 /*************************************************************************
503  api_net_sam_logoff:
504  *************************************************************************/
505
506 static BOOL api_net_sam_logoff(pipes_struct *p)
507 {
508         uint16 vuid = p->vuid;
509         NET_Q_SAM_LOGOFF q_l;
510         NET_ID_INFO_CTR ctr;    
511         DOM_CRED srv_cred;
512         prs_struct *data = &p->in_data.data;
513         prs_struct *rdata = &p->out_data.rdata;
514
515         user_struct *vuser;
516
517         if ((vuser = get_valid_user_struct(vuid)) == NULL)
518                 return False;
519
520         /* the DOM_ID_INFO_1 structure is a bit big.  plus we might want to
521            dynamically allocate it inside net_io_q_sam_logon, at some point */
522         q_l.sam_id.ctr = &ctr;
523
524         /* grab the challenge... */
525         if(!net_io_q_sam_logoff("", &q_l, data, 0)) {
526                 DEBUG(0,("api_net_sam_logoff: Failed to unmarshall NET_Q_SAM_LOGOFF.\n"));
527                 return False;
528         }
529
530         /* checks and updates credentials.  creates reply credentials */
531         deal_with_creds(vuser->dc.sess_key, &vuser->dc.clnt_cred, 
532                         &q_l.sam_id.client.cred, &srv_cred);
533         memcpy(&vuser->dc.srv_cred, &vuser->dc.clnt_cred, sizeof(vuser->dc.clnt_cred));
534
535         /* construct reply.  always indicate success */
536         if(!net_reply_sam_logoff(&q_l, rdata, &srv_cred, 0x0))
537                 return False;
538
539         return True;
540 }
541
542 /*************************************************************************
543  net_login_interactive:
544  *************************************************************************/
545
546 static uint32 net_login_interactive(NET_ID_INFO_1 *id1, SAM_ACCOUNT *sampass,
547                                     user_struct *vuser)
548 {
549         uint32 status = 0x0;
550
551         char nt_pwd[16];
552         char lm_pwd[16];
553         unsigned char key[16];
554
555         memset(key, 0, 16);
556         memcpy(key, vuser->dc.sess_key, 8);
557
558         memcpy(lm_pwd, id1->lm_owf.data, 16);
559         memcpy(nt_pwd, id1->nt_owf.data, 16);
560
561 #ifdef DEBUG_PASSWORD
562         DEBUG(100,("key:"));
563         dump_data(100, (char *)key, 16);
564
565         DEBUG(100,("lm owf password:"));
566         dump_data(100, lm_pwd, 16);
567
568         DEBUG(100,("nt owf password:"));
569         dump_data(100, nt_pwd, 16);
570 #endif
571
572         SamOEMhash((uchar *)lm_pwd, key, False);
573         SamOEMhash((uchar *)nt_pwd, key, False);
574
575 #ifdef DEBUG_PASSWORD
576         DEBUG(100,("decrypt of lm owf password:"));
577         dump_data(100, lm_pwd, 16);
578
579         DEBUG(100,("decrypt of nt owf password:"));
580         dump_data(100, nt_pwd, 16);
581 #endif
582
583         if (memcmp(pdb_get_lanman_passwd(sampass)  ,lm_pwd, 16) != 0 ||
584             memcmp(pdb_get_nt_passwd(sampass)      ,nt_pwd, 16) != 0)
585         {
586                 status = NT_STATUS_WRONG_PASSWORD;
587         }
588
589         return status;
590 }
591
592 /*************************************************************************
593  net_login_network:
594  *************************************************************************/
595
596 static uint32 net_login_network(NET_ID_INFO_2 *id2, SAM_ACCOUNT *sampass)
597 {
598         BYTE    *nt_pwd, *lanman_pwd;
599         
600         DEBUG(5,("net_login_network: lm_len: %d nt_len: %d\n",
601                 id2->hdr_lm_chal_resp.str_str_len, 
602                 id2->hdr_nt_chal_resp.str_str_len));
603
604         /* JRA. Check the NT password first if it exists - this is a higher quality 
605            password, if it exists and it doesn't match - fail. */
606
607         nt_pwd     = pdb_get_nt_passwd     (sampass); 
608         lanman_pwd = pdb_get_lanman_passwd (sampass);
609         if (id2->hdr_nt_chal_resp.str_str_len == 24 && 
610                 nt_pwd != NULL)
611         {
612                 if(smb_password_check((char *)id2->nt_chal_resp.buffer, nt_pwd,
613                            id2->lm_chal)) 
614                         return 0x0;
615                 else
616                         return NT_STATUS_WRONG_PASSWORD;
617         }
618
619         /* lkclXXXX this is not a good place to put disabling of LM hashes in.
620            if that is to be done, first move this entire function into a
621            library routine that calls the two smb_password_check() functions.
622            if disabling LM hashes (which nt can do for security reasons) then
623            an attempt should be made to disable them everywhere (which nt does
624            not do, for various security-hole reasons).
625          */
626
627         if (id2->hdr_lm_chal_resp.str_str_len == 24 &&
628                 smb_password_check((char *)id2->lm_chal_resp.buffer,
629                                    lanman_pwd, id2->lm_chal))
630         {
631                 return 0x0;
632         }
633
634
635         /* oops! neither password check succeeded */
636
637         return NT_STATUS_WRONG_PASSWORD;
638 }
639
640 /*************************************************************************
641  api_net_sam_logon:
642  *************************************************************************/
643
644 static BOOL api_net_sam_logon(pipes_struct *p)
645 {
646     uint16 vuid = p->vuid;
647     NET_Q_SAM_LOGON q_l;
648     NET_ID_INFO_CTR ctr;        
649     NET_USER_INFO_3 usr_info;
650     uint32 status = 0x0;
651     DOM_CRED srv_cred;
652     SAM_ACCOUNT *sampass = NULL;
653     uint16 acct_ctrl;
654     UNISTR2 *uni_samlogon_user = NULL;
655     fstring nt_username;
656     prs_struct *data = &p->in_data.data;
657     prs_struct *rdata = &p->out_data.rdata;
658     user_struct *vuser = NULL;
659     
660     if ((vuser = get_valid_user_struct(vuid)) == NULL)
661         return False;
662     
663     ZERO_STRUCT(q_l);
664     ZERO_STRUCT(ctr);
665     ZERO_STRUCT(usr_info);
666     
667     q_l.sam_id.ctr = &ctr;
668     
669     if(!net_io_q_sam_logon("", &q_l, data, 0)) {
670         DEBUG(0, ("api_net_sam_logon: Failed to unmarshall NET_Q_SAM_LOGON.\n"));
671         return False;
672     }
673     
674     /* checks and updates credentials.  creates reply credentials */
675     if (!deal_with_creds(vuser->dc.sess_key, &vuser->dc.clnt_cred, &q_l.sam_id.client.cred, &srv_cred))
676         status = NT_STATUS_INVALID_HANDLE;
677     else
678         memcpy(&vuser->dc.srv_cred, &vuser->dc.clnt_cred, sizeof(vuser->dc.clnt_cred));
679     
680     /* find the username */
681     
682     if (status == 0) {
683         switch (q_l.sam_id.logon_level) {
684         case INTERACTIVE_LOGON_TYPE:
685             uni_samlogon_user = &q_l.sam_id.ctr->auth.id1.uni_user_name;
686             
687             DEBUG(3,("SAM Logon (Interactive). Domain:[%s].  ", lp_workgroup()));
688             break;
689         case NET_LOGON_TYPE:
690             uni_samlogon_user = &q_l.sam_id.ctr->auth.id2.uni_user_name;
691             
692             DEBUG(3,("SAM Logon (Network). Domain:[%s].  ", lp_workgroup()));
693             break;
694         default:
695             DEBUG(2,("SAM Logon: unsupported switch value\n"));
696             status = NT_STATUS_INVALID_INFO_CLASS;
697             break;
698         } /* end switch */
699     } /* end if status == 0 */
700
701   /* check username exists */
702
703     if (status == 0) 
704     {
705         pstrcpy(nt_username, dos_unistrn2(uni_samlogon_user->buffer,
706                                           uni_samlogon_user->uni_str_len));
707
708         DEBUG(3,("User:[%s]\n", nt_username));
709         
710         /*
711          * Convert to a UNIX username.
712          */
713         map_username(nt_username);
714         
715         /* get the account information */
716         become_root();
717         sampass = pdb_getsampwnam(nt_username);
718         unbecome_root();
719         
720         acct_ctrl = pdb_get_acct_ctrl(sampass);
721         if (sampass == NULL)
722             status = NT_STATUS_NO_SUCH_USER;
723         else if (acct_ctrl & ACB_PWNOTREQ)
724             status = 0;
725         else if (acct_ctrl & ACB_DISABLED)
726             status =  NT_STATUS_ACCOUNT_DISABLED;
727     }
728     
729     /* Validate password - if required. */
730     
731     if ((status == 0) && !(acct_ctrl & ACB_PWNOTREQ)) {
732         switch (q_l.sam_id.logon_level) {
733         case INTERACTIVE_LOGON_TYPE:
734             /* interactive login. */
735             status = net_login_interactive(&q_l.sam_id.ctr->auth.id1, 
736                                            sampass, vuser);
737             break;
738         case NET_LOGON_TYPE:
739             /* network login.  lm challenge and 24 byte responses */
740             status = net_login_network(&q_l.sam_id.ctr->auth.id2, sampass);
741             break;
742         }
743     }
744
745     /* lkclXXXX this is the point at which, if the login was
746        successful, that the SAM Local Security Authority should
747        record that the user is logged in to the domain.
748     */
749     
750     /* return the profile plus other bits :-) */
751     
752     if (status == 0) {
753         DOM_GID *gids = NULL;
754         int num_gids = 0;
755         pstring my_name;
756         pstring my_workgroup;
757         pstring domain_groups;
758         
759         /* set up pointer indicating user/password failed to be found */
760         usr_info.ptr_user_info = 0;
761                 
762         /* XXXX hack to get standard_sub_basic() to use sam logon username */
763         /* possibly a better way would be to do a become_user() call */
764         
765         /*
766          * All this information should be filled in from the 
767          * passdb information
768          */
769         sam_logon_in_ssb = True;
770         pstrcpy(samlogon_user, nt_username);
771
772 #if 0
773         gid = pdb_get_gid(sampass);
774         
775         pstrcpy(str, pdb_get_logon_script(sampass));
776         standard_sub_advanced(-1, nt_username, "", gid, str);
777         pdb_set_logon_script(sampass, str);
778         
779         pstrcpy(str, pdb_get_profile_path(sampass));
780         standard_sub_advanced(-1, nt_username, "", gid, str);
781         pdb_set_profile_path(sampass, str);
782                 
783         pstrcpy(str, pdb_get_homedir(sampass));
784         standard_sub_advanced(-1, nt_username, "", gid, str);
785         pdb_set_homedir(sampass, str);
786         
787         fstrcpy(full_name, "<Full Name>");
788         if (lp_unix_realname())
789                 fstrcpy(full_name, pdb_get_fullname(sampass));
790 #endif
791
792         pstrcpy(my_workgroup, lp_workgroup());
793         pstrcpy(my_name, global_myname);
794         strupper(my_name);
795
796         
797         /*
798          * This is the point at which we get the group
799          * database - we should be getting the gid_t list
800          * from /etc/group and then turning the uids into
801          * rids and then into machine sids for this user.
802          * JRA.
803          */
804         
805         get_domain_user_groups(domain_groups, nt_username);
806         
807         /*
808          * make_dom_gids allocates the gids array. JRA.
809          */
810         gids = NULL;
811         num_gids = make_dom_gids(domain_groups, &gids);
812         
813         sam_logon_in_ssb = False;
814         
815         /* 
816          * This next call is where the 'domain admin users' parameter
817          * gets mapped.  I'm leaving it out for now.  The user and group rid
818          * has already been mapped into the SAM_ACCOUNT struct.  I don't
819          * think this should be overridden here.  The correct solution
820          * is proper group memberships and mapping.       --jerry
821          */
822 #if 0
823         if (pdb_name_to_rid(nt_username, &r_uid, &r_gid))
824 #endif
825         init_net_user_info3(&usr_info, sampass,                                
826                                 0, /* logon_count */
827                                 0, /* bad_pw_count */
828                                 num_gids,    /* uint32 num_groups */
829                                 gids    , /* DOM_GID *gids */
830                                 0x20    , /* uint32 user_flgs (?) */
831                                 NULL, /* char sess_key[16] */
832                                 my_name     , /* char *logon_srv */
833                                 my_workgroup, /* char *logon_dom */
834                                 &global_sam_sid,     /* DOM_SID *dom_sid */
835                                 NULL); /* char *other_sids */
836
837 #if 0
838         else
839             status = NT_STATUS_NO_SUCH_USER;
840 #endif
841         
842         /* Free any allocated groups array. */
843         if(gids)
844             free((char *)gids);
845     }
846     
847     if(!net_reply_sam_logon(&q_l, rdata, &srv_cred, &usr_info, status)) {
848                 free_user_info3(&usr_info);
849         return False;
850         }
851
852         free_user_info3(&usr_info); 
853
854     return True;
855 }
856
857
858 /*************************************************************************
859  api_net_trust_dom_list:
860  *************************************************************************/
861
862 static BOOL api_net_trust_dom_list(pipes_struct *p)
863 {
864         NET_Q_TRUST_DOM_LIST q_t;
865         prs_struct *data = &p->in_data.data;
866         prs_struct *rdata = &p->out_data.rdata;
867
868         char *trusted_domain = "test_domain";
869
870         DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
871
872         /* grab the lsa trusted domain list query... */
873         if(!net_io_q_trust_dom("", &q_t, data, 0)) {
874                 DEBUG(0,("api_net_trust_dom_list: Failed to unmarshall NET_Q_TRUST_DOM_LIST.\n"));
875                 return False;
876         }
877
878         /* construct reply. */
879         if(!net_reply_trust_dom_list(&q_t, rdata, 1, trusted_domain))
880                 return False;
881
882         DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
883
884         return True;
885 }
886
887
888 /*************************************************************************
889  error messages cropping up when using nltest.exe...
890  *************************************************************************/
891 #define ERROR_NO_SUCH_DOMAIN   0x54b
892 #define ERROR_NO_LOGON_SERVERS 0x51f
893
894 /*************************************************************************
895  api_net_logon_ctrl2:
896  *************************************************************************/
897
898 static BOOL api_net_logon_ctrl2(pipes_struct *p)
899 {
900         NET_Q_LOGON_CTRL2 q_l;
901         prs_struct *data = &p->in_data.data;
902         prs_struct *rdata = &p->out_data.rdata;
903
904         /* lkclXXXX - guess what - absolutely no idea what these are! */
905         uint32 flags = 0x0;
906         uint32 pdc_connection_status = 0x0;
907         uint32 logon_attempts = 0x0;
908         uint32 tc_status = ERROR_NO_LOGON_SERVERS;
909         char *trusted_domain = "test_domain";
910
911         DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
912
913         /* grab the lsa netlogon ctrl2 query... */
914         if(!net_io_q_logon_ctrl2("", &q_l, data, 0)) {
915                 DEBUG(0,("api_net_logon_ctrl2: Failed to unmarshall NET_Q_LOGON_CTRL2.\n"));
916                 return False;
917         }
918
919         /* construct reply. */
920         if(!net_reply_logon_ctrl2(&q_l, rdata,
921                                 flags, pdc_connection_status, logon_attempts,
922                                 tc_status, trusted_domain))
923                 return False;
924
925         DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
926
927         return True;
928 }
929
930 /*******************************************************************
931  array of \PIPE\NETLOGON operations
932  ********************************************************************/
933 static struct api_struct api_net_cmds [] =
934 {
935         { "NET_REQCHAL"       , NET_REQCHAL       , api_net_req_chal       }, 
936         { "NET_AUTH2"         , NET_AUTH2         , api_net_auth_2         }, 
937         { "NET_SRVPWSET"      , NET_SRVPWSET      , api_net_srv_pwset      }, 
938         { "NET_SAMLOGON"      , NET_SAMLOGON      , api_net_sam_logon      }, 
939         { "NET_SAMLOGOFF"     , NET_SAMLOGOFF     , api_net_sam_logoff     }, 
940         { "NET_LOGON_CTRL2"   , NET_LOGON_CTRL2   , api_net_logon_ctrl2    }, 
941         { "NET_TRUST_DOM_LIST", NET_TRUST_DOM_LIST, api_net_trust_dom_list },
942         {  NULL               , 0                 , NULL                   }
943 };
944
945 /*******************************************************************
946  receives a netlogon pipe and responds.
947  ********************************************************************/
948
949 BOOL api_netlog_rpc(pipes_struct *p)
950 {
951         return api_rpcTNP(p, "api_netlog_rpc", api_net_cmds);
952 }
953 #undef OLD_NTDOMAIN