2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-1997,
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
7 * Copyright (C) Paul Ashton 1997.
8 * Copyright (C) Jeremy Allison 1998.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 extern int DEBUGLEVEL;
31 extern pstring global_myname;
32 extern DOM_SID global_sam_sid;
33 extern fstring global_sam_name;
35 /*************************************************************************
37 *************************************************************************/
38 static void make_net_r_req_chal(NET_R_REQ_CHAL *r_c,
39 DOM_CHAL *srv_chal, int status)
41 DEBUG(6,("make_net_r_req_chal: %d\n", __LINE__));
42 memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data));
46 /*************************************************************************
48 *************************************************************************/
49 static void net_reply_req_chal(NET_Q_REQ_CHAL *q_c, prs_struct *rdata,
50 DOM_CHAL *srv_chal, uint32 srv_time)
54 DEBUG(6,("net_reply_req_chal: %d\n", __LINE__));
56 /* set up the LSA REQUEST CHALLENGE response */
57 make_net_r_req_chal(&r_c, srv_chal, srv_time);
59 /* store the response in the SMB stream */
60 net_io_r_req_chal("", &r_c, rdata, 0);
62 DEBUG(6,("net_reply_req_chal: %d\n", __LINE__));
66 /*************************************************************************
67 net_reply_logon_ctrl2:
68 *************************************************************************/
69 static void net_reply_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, prs_struct *rdata,
70 uint32 flags, uint32 pdc_status, uint32 logon_attempts,
71 uint32 tc_status, char *trust_domain_name)
73 NET_R_LOGON_CTRL2 r_l;
75 DEBUG(6,("net_reply_logon_ctrl2: %d\n", __LINE__));
77 /* set up the Logon Control2 response */
78 make_r_logon_ctrl2(&r_l, q_l->query_level,
79 flags, pdc_status, logon_attempts,
80 tc_status, trust_domain_name);
82 /* store the response in the SMB stream */
83 net_io_r_logon_ctrl2("", &r_l, rdata, 0);
85 DEBUG(6,("net_reply_logon_ctrl2: %d\n", __LINE__));
89 /*************************************************************************
90 net_reply_trust_dom_list:
91 *************************************************************************/
92 static void net_reply_trust_dom_list(NET_Q_TRUST_DOM_LIST *q_t, prs_struct *rdata,
93 uint32 num_trust_domains, char **trust_domain_name)
95 NET_R_TRUST_DOM_LIST r_t;
97 DEBUG(6,("net_reply_trust_dom_list: %d\n", __LINE__));
99 /* set up the Trusted Domain List response */
100 make_r_trust_dom(&r_t, num_trust_domains, trust_domain_name);
102 /* store the response in the SMB stream */
103 net_io_r_trust_dom("", &r_t, rdata, 0);
105 DEBUG(6,("net_reply_trust_dom_list: %d\n", __LINE__));
110 /*************************************************************************
112 *************************************************************************/
113 static void make_net_r_auth(NET_R_AUTH *r_a,
114 DOM_CHAL *resp_cred, int status)
116 memcpy( r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
117 r_a->status = status;
120 /*************************************************************************
122 *************************************************************************/
123 static void net_reply_auth(NET_Q_AUTH *q_a, prs_struct *rdata,
124 DOM_CHAL *resp_cred, int status)
128 /* set up the LSA AUTH 2 response */
130 make_net_r_auth(&r_a, resp_cred, status);
132 /* store the response in the SMB stream */
133 net_io_r_auth("", &r_a, rdata, 0);
137 /*************************************************************************
139 *************************************************************************/
140 static void make_net_r_auth_2(NET_R_AUTH_2 *r_a,
141 DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status)
143 memcpy( r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
144 memcpy(&(r_a->srv_flgs) , flgs , sizeof(r_a->srv_flgs));
145 r_a->status = status;
148 /*************************************************************************
150 *************************************************************************/
151 static void net_reply_auth_2(NET_Q_AUTH_2 *q_a, prs_struct *rdata,
152 DOM_CHAL *resp_cred, int status)
157 srv_flgs.neg_flags = 0x000001ff;
159 /* set up the LSA AUTH 2 response */
161 make_net_r_auth_2(&r_a, resp_cred, &srv_flgs, status);
163 /* store the response in the SMB stream */
164 net_io_r_auth_2("", &r_a, rdata, 0);
168 /***********************************************************************************
169 make_net_r_srv_pwset:
170 ***********************************************************************************/
171 static void make_net_r_srv_pwset(NET_R_SRV_PWSET *r_s,
172 DOM_CRED *srv_cred, int status)
174 DEBUG(5,("make_net_r_srv_pwset: %d\n", __LINE__));
176 memcpy(&(r_s->srv_cred), srv_cred, sizeof(r_s->srv_cred));
177 r_s->status = status;
179 DEBUG(5,("make_net_r_srv_pwset: %d\n", __LINE__));
182 /*************************************************************************
184 *************************************************************************/
185 static void net_reply_srv_pwset(NET_Q_SRV_PWSET *q_s, prs_struct *rdata,
186 DOM_CRED *srv_cred, int status)
190 DEBUG(5,("net_srv_pwset: %d\n", __LINE__));
192 /* set up the LSA Server Password Set response */
193 make_net_r_srv_pwset(&r_s, srv_cred, status);
195 /* store the response in the SMB stream */
196 net_io_r_srv_pwset("", &r_s, rdata, 0);
198 DEBUG(5,("net_srv_pwset: %d\n", __LINE__));
202 /*************************************************************************
204 *************************************************************************/
205 static void net_reply_sam_logon(NET_Q_SAM_LOGON *q_s, prs_struct *rdata,
206 DOM_CRED *srv_cred, NET_USER_INFO_3 *user_info,
211 /* XXXX maybe we want to say 'no', reject the client's credentials */
212 r_s.buffer_creds = 1; /* yes, we have valid server credentials */
213 memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
215 /* store the user information, if there is any. */
216 r_s.user = user_info;
217 if (status == 0x0 && user_info != NULL && user_info->ptr_user_info != 0)
219 r_s.switch_value = 3; /* indicates type of validation user info */
223 r_s.switch_value = 0; /* indicates no info */
227 r_s.auth_resp = 1; /* authoritative response */
229 /* store the response in the SMB stream */
230 net_io_r_sam_logon("", &r_s, rdata, 0);
235 /*************************************************************************
236 net_reply_sam_logoff:
237 *************************************************************************/
238 static void net_reply_sam_logoff(NET_Q_SAM_LOGOFF *q_s, prs_struct *rdata,
242 NET_R_SAM_LOGOFF r_s;
244 /* XXXX maybe we want to say 'no', reject the client's credentials */
245 r_s.buffer_creds = 1; /* yes, we have valid server credentials */
246 memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
250 /* store the response in the SMB stream */
251 net_io_r_sam_logoff("", &r_s, rdata, 0);
255 /*************************************************************************
257 *************************************************************************/
258 static void net_reply_sam_sync(NET_Q_SAM_SYNC *q_s, prs_struct *rdata,
260 DOM_CRED *srv_creds, uint32 status)
264 struct sam_passwd *pwd;
267 memcpy(&(r_s.srv_creds), srv_creds, sizeof(r_s.srv_creds));
268 r_s.sync_context = 1;
271 if ((status == 0x0) && ((vp = startsmbpwent(False)) != NULL))
273 /* Give the poor BDC some accounts */
275 while (((pwd = getsam21pwent(vp)) != NULL) && (i < MAX_SAM_DELTAS))
277 make_sam_delta_hdr(&r_s.hdr_deltas[i], 5, pwd->user_rid);
278 make_sam_account_info(&r_s.deltas[i].account_info,
279 pwd->nt_name, pwd->full_name, pwd->user_rid,
280 pwd->group_rid, pwd->home_dir, pwd->dir_drive,
281 pwd->logon_script, pwd->acct_desc,
282 pwd->acct_ctrl, pwd->profile_path);
289 r_s.ptr_deltas = r_s.ptr_deltas2 = 1;
290 r_s.num_deltas = r_s.num_deltas2 = i;
295 /* store the response in the SMB stream */
296 net_io_r_sam_sync("", sess_key, &r_s, rdata, 0);
300 /******************************************************************
301 gets a machine password entry. checks access rights of the host.
302 ******************************************************************/
303 static BOOL get_md4pw(char *md4pw, char *mach_name, char *mach_acct)
305 struct smb_passwd *smb_pass;
309 * Currently this code is redundent as we already have a filter
310 * by hostname list. What this code really needs to do is to
311 * get a hosts allowed/hosts denied list from the SAM database
312 * on a per user basis, and make the access decision there.
313 * I will leave this code here for now as a reminder to implement
314 * this at a later date. JRA.
317 if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
318 client_name(Client), client_addr(Client)))
320 DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct));
326 smb_pass = getsmbpwnam(mach_acct);
329 if ((smb_pass) != NULL && !(smb_pass->acct_ctrl & ACB_DISABLED) &&
330 (smb_pass->smb_nt_passwd != NULL))
332 memcpy(md4pw, smb_pass->smb_nt_passwd, 16);
333 dump_data(5, md4pw, 16);
337 DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
341 /*************************************************************************
343 *************************************************************************/
344 static void api_net_req_chal( pipes_struct *p,
356 DEBUG(5,("api_net_req_chal(%d): vuid %d\n", __LINE__, (int)p->vuid));
358 if ((vuser = get_valid_user_struct(p->vuid)) == NULL)
361 /* grab the challenge... */
362 net_io_q_req_chal("", &q_r, data, 0);
364 unistr2_to_ascii(mach_acct, &q_r.uni_logon_clnt, sizeof(mach_acct)-1);
366 fstrcpy(mach_name, mach_acct);
369 fstrcat(mach_acct, "$");
371 if (get_md4pw((char *)vuser->dc.md4pw, mach_name, mach_acct))
373 /* copy the client credentials */
374 memcpy(vuser->dc.clnt_chal.data , q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
375 memcpy(vuser->dc.clnt_cred.challenge.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
377 /* create a server challenge for the client */
378 /* Set these to random values. */
379 generate_random_buffer(vuser->dc.srv_chal.data, 8, False);
381 memcpy(vuser->dc.srv_cred.challenge.data, vuser->dc.srv_chal.data, 8);
383 bzero(vuser->dc.sess_key, sizeof(vuser->dc.sess_key));
385 /* from client / server challenges and md4 password, generate sess key */
386 cred_session_key(&(vuser->dc.clnt_chal), &(vuser->dc.srv_chal),
387 (char *)vuser->dc.md4pw, vuser->dc.sess_key);
391 /* lkclXXXX take a guess at a good error message to return :-) */
392 status = 0xC0000000 | NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
395 /* construct reply. */
396 net_reply_req_chal(&q_r, rdata,
397 &(vuser->dc.srv_chal), status);
401 /*************************************************************************
403 *************************************************************************/
404 static void api_net_auth( pipes_struct *p,
416 if ((vuser = get_valid_user_struct(p->vuid)) == NULL)
421 /* grab the challenge... */
422 net_io_q_auth("", &q_a, data, 0);
424 /* check that the client credentials are valid */
425 if (cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key,
426 &(vuser->dc.clnt_cred.challenge), srv_time))
429 /* create server challenge for inclusion in the reply */
430 cred_create(vuser->dc.sess_key, &(vuser->dc.srv_cred.challenge), srv_time, &srv_cred);
432 /* copy the received client credentials for use next time */
433 memcpy(vuser->dc.clnt_cred.challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
434 memcpy(vuser->dc.srv_cred .challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
438 status = NT_STATUS_ACCESS_DENIED | 0xC0000000;
441 /* construct reply. */
442 net_reply_auth(&q_a, rdata, &srv_cred, status);
445 /*************************************************************************
447 *************************************************************************/
448 static void api_net_auth_2( pipes_struct *p,
460 if ((vuser = get_valid_user_struct(p->vuid)) == NULL)
465 /* grab the challenge... */
466 net_io_q_auth_2("", &q_a, data, 0);
468 /* check that the client credentials are valid */
469 if (cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key,
470 &(vuser->dc.clnt_cred.challenge), srv_time))
473 /* create server challenge for inclusion in the reply */
474 cred_create(vuser->dc.sess_key, &(vuser->dc.srv_cred.challenge), srv_time, &srv_cred);
476 /* copy the received client credentials for use next time */
477 memcpy(vuser->dc.clnt_cred.challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
478 memcpy(vuser->dc.srv_cred .challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
482 status = NT_STATUS_ACCESS_DENIED | 0xC0000000;
485 /* construct reply. */
486 net_reply_auth_2(&q_a, rdata, &srv_cred, status);
489 /*************************************************************************
491 *************************************************************************/
492 static void api_net_srv_pwset( pipes_struct *p,
497 uint32 status = NT_STATUS_WRONG_PASSWORD|0xC0000000;
500 struct smb_passwd *smb_pass;
504 if ((vuser = get_valid_user_struct(p->vuid)) == NULL)
507 /* grab the challenge and encrypted password ... */
508 net_io_q_srv_pwset("", &q_a, data, 0);
510 /* checks and updates credentials. creates reply credentials */
511 if (deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
512 &(q_a.clnt_id.cred), &srv_cred))
514 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
516 DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
518 unistr2_to_ascii(mach_acct, &q_a.clnt_id.login.uni_acct_name,
519 sizeof(mach_acct)-1);
521 DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
524 smb_pass = getsmbpwnam(mach_acct);
527 if (smb_pass != NULL)
529 unsigned char pwd[16];
532 DEBUG(100,("Server password set : new given value was :\n"));
533 for(i = 0; i < 16; i++)
535 DEBUG(100,("%02X ", q_a.pwd[i]));
539 cred_hash3( pwd, q_a.pwd, vuser->dc.sess_key, 0);
541 /* lies! nt and lm passwords are _not_ the same: don't care */
542 smb_pass->smb_passwd = pwd;
543 smb_pass->smb_nt_passwd = pwd;
544 smb_pass->acct_ctrl = ACB_WSTRUST;
547 ret = mod_smbpwd_entry(smb_pass,False);
557 DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
562 /* lkclXXXX take a guess at a sensible error code to return... */
563 status = 0xC0000000 | NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
566 /* Construct reply. */
567 net_reply_srv_pwset(&q_a, rdata, &srv_cred, status);
571 /*************************************************************************
573 *************************************************************************/
574 static void api_net_sam_logoff( pipes_struct *p,
578 NET_Q_SAM_LOGOFF q_l;
585 if ((vuser = get_valid_user_struct(p->vuid)) == NULL)
588 /* the DOM_ID_INFO_1 structure is a bit big. plus we might want to
589 dynamically allocate it inside net_io_q_sam_logon, at some point */
590 q_l.sam_id.ctr = &ctr;
592 /* grab the challenge... */
593 net_io_q_sam_logoff("", &q_l, data, 0);
595 /* checks and updates credentials. creates reply credentials */
596 deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
597 &(q_l.sam_id.client.cred), &srv_cred);
598 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
600 /* construct reply. always indicate success */
601 net_reply_sam_logoff(&q_l, rdata, &srv_cred, 0x0);
604 /*************************************************************************
606 *************************************************************************/
607 static void api_net_sam_sync( pipes_struct *p,
616 if ((vuser = get_valid_user_struct(p->vuid)) == NULL)
619 /* grab the challenge... */
620 net_io_q_sam_sync("", &q_s, data, 0);
622 /* checks and updates credentials. creates reply credentials */
623 if (deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
624 &(q_s.cli_creds), &srv_creds))
626 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred),
627 sizeof(vuser->dc.clnt_cred));
631 status = 0xC0000000 | NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
634 /* construct reply. */
635 net_reply_sam_sync(&q_s, rdata, vuser->dc.sess_key, &srv_creds, status);
639 /*************************************************************************
640 net_login_interactive:
641 *************************************************************************/
642 static uint32 net_login_interactive(NET_ID_INFO_1 *id1,
643 struct sam_passwd *smb_pass,
650 unsigned char key[16];
653 memcpy(key, vuser->dc.sess_key, 8);
655 memcpy(lm_pwd, id1->lm_owf.data, 16);
656 memcpy(nt_pwd, id1->nt_owf.data, 16);
658 #ifdef DEBUG_PASSWORD
660 dump_data(100, key, 16);
662 DEBUG(100,("lm owf password:"));
663 dump_data(100, lm_pwd, 16);
665 DEBUG(100,("nt owf password:"));
666 dump_data(100, nt_pwd, 16);
669 SamOEMhash((uchar *)lm_pwd, key, False);
670 SamOEMhash((uchar *)nt_pwd, key, False);
672 #ifdef DEBUG_PASSWORD
673 DEBUG(100,("decrypt of lm owf password:"));
674 dump_data(100, lm_pwd, 16);
676 DEBUG(100,("decrypt of nt owf password:"));
677 dump_data(100, nt_pwd, 16);
680 if (smb_pass->smb_nt_passwd == NULL)
682 DEBUG(5,("warning: NETLOGON user %s only has an LM password\n",
683 smb_pass->unix_name));
686 if (memcmp(smb_pass->smb_passwd , lm_pwd, 16) != 0 ||
687 smb_pass->smb_nt_passwd == NULL ||
688 memcmp(smb_pass->smb_nt_passwd, nt_pwd, 16) != 0)
690 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
696 /*************************************************************************
698 *************************************************************************/
699 static uint32 net_login_network(NET_ID_INFO_2 *id2,
700 struct sam_passwd *smb_pass,
706 int nt_pw_len = id2->hdr_nt_chal_resp.str_str_len;
707 int lm_pw_len = id2->hdr_lm_chal_resp.str_str_len;
709 unistr2_to_ascii(user , &id2->uni_user_name, sizeof(user)-1);
710 unistr2_to_ascii(domain, &id2->uni_domain_name, sizeof(domain)-1);
712 DEBUG(5,("net_login_network: lm_len:%d nt_len:%d user:%s domain:%s\n",
713 lm_pw_len, nt_pw_len, user, domain));
715 if (smb_password_ok(pwdb_sam_to_smb(smb_pass), id2->lm_chal,
717 (uchar *)id2->lm_chal_resp.buffer, lm_pw_len,
718 (uchar *)id2->nt_chal_resp.buffer, nt_pw_len))
723 return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
726 /*************************************************************************
728 *************************************************************************/
729 static uint32 reply_net_sam_logon( NET_Q_SAM_LOGON *q_l, user_struct *vuser,
730 DOM_CRED *srv_cred, NET_USER_INFO_3 *usr_info)
732 struct sam_passwd *sam_pass = NULL;
733 UNISTR2 *uni_samusr = NULL;
734 UNISTR2 *uni_domain = NULL;
739 NTTIME kickoff_time ;
740 NTTIME pass_last_set_time ;
741 NTTIME pass_can_change_time ;
742 NTTIME pass_must_change_time;
746 fstring logon_script;
747 fstring profile_path;
755 DOMAIN_GRP *grp_mem = NULL;
756 DOM_GID *gids = NULL;
758 /* checks and updates credentials. creates reply credentials */
759 if (!deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
760 &(q_l->sam_id.client.cred), srv_cred))
762 return 0xC0000000 | NT_STATUS_INVALID_HANDLE;
765 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
767 /* find the username */
769 switch (q_l->sam_id.logon_level)
771 case INTERACTIVE_LOGON_TYPE:
773 uni_samusr = &(q_l->sam_id.ctr->auth.id1.uni_user_name);
774 uni_domain = &(q_l->sam_id.ctr->auth.id1.uni_domain_name);
776 DEBUG(3,("SAM Logon (Interactive). Domain:[%s]. ", global_sam_name));
781 uni_samusr = &(q_l->sam_id.ctr->auth.id2.uni_user_name);
782 uni_domain = &(q_l->sam_id.ctr->auth.id2.uni_domain_name);
784 DEBUG(3,("SAM Logon (Network). Domain:[%s]. ", global_sam_name));
789 DEBUG(2,("SAM Logon: unsupported switch value\n"));
790 return 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
794 /* check username exists */
796 unistr2_to_ascii(nt_username, uni_samusr,
797 sizeof(nt_username)-1);
799 DEBUG(3,("User:[%s]\n", nt_username));
802 sam_pass = getsam21pwntnam(nt_username);
805 if (sam_pass == NULL)
807 return 0xC0000000 | NT_STATUS_NO_SUCH_USER;
809 else if (IS_BITS_SET_ALL(sam_pass->acct_ctrl, ACB_DISABLED) &&
810 IS_BITS_CLR_ALL(sam_pass->acct_ctrl, ACB_PWNOTREQ))
812 return 0xC0000000 | NT_STATUS_ACCOUNT_DISABLED;
815 logon_time = sam_pass->logon_time;
816 logoff_time = sam_pass->logoff_time;
817 kickoff_time = sam_pass->kickoff_time;
818 pass_last_set_time = sam_pass->pass_last_set_time;
819 pass_can_change_time = sam_pass->pass_can_change_time;
820 pass_must_change_time = sam_pass->pass_must_change_time;
822 fstrcpy(nt_name , sam_pass->nt_name);
823 fstrcpy(full_name , sam_pass->full_name);
824 fstrcpy(logon_script, sam_pass->logon_script);
825 fstrcpy(profile_path, sam_pass->profile_path);
826 fstrcpy(home_dir , sam_pass->home_dir);
827 fstrcpy(dir_drive , sam_pass->dir_drive);
829 user_rid = sam_pass->user_rid;
830 group_rid = sam_pass->group_rid;
832 /* validate password - if required */
834 if (!(IS_BITS_SET_ALL(sam_pass->acct_ctrl, ACB_PWNOTREQ)))
837 switch (q_l->sam_id.logon_level)
839 case INTERACTIVE_LOGON_TYPE:
841 /* interactive login. */
842 status = net_login_interactive(&q_l->sam_id.ctr->auth.id1, sam_pass, vuser);
847 /* network login. lm challenge and 24 byte responses */
848 status = net_login_network(&q_l->sam_id.ctr->auth.id2, sam_pass, vuser);
858 /* lkclXXXX this is the point at which, if the login was
859 successful, that the SAM Local Security Authority should
860 record that the user is logged in to the domain.
863 /* return the profile plus other bits :-) */
865 /* set up pointer indicating user/password failed to be found */
866 usr_info->ptr_user_info = 0;
868 if (!getusergroupsntnam(nt_username, &grp_mem, &num_gids))
870 return 0xC0000000 | NT_STATUS_INVALID_PRIMARY_GROUP;
873 num_gids = make_dom_gids(grp_mem, num_gids, &gids);
875 make_net_user_info3(usr_info,
880 &pass_can_change_time,
881 &pass_must_change_time,
883 nt_name , /* user_name */
884 full_name , /* full_name */
885 logon_script , /* logon_script */
886 profile_path , /* profile_path */
887 home_dir , /* home_dir */
888 dir_drive , /* dir_drive */
891 0, /* bad_pw_count */
893 user_rid , /* RID user_id */
894 group_rid , /* RID group_id */
895 num_gids, /* uint32 num_groups */
896 gids , /* DOM_GID *gids */
897 0x20 , /* uint32 user_flgs (?) */
899 NULL, /* char sess_key[16] */
901 global_myname , /* char *logon_srv */
902 global_sam_name, /* char *logon_dom */
903 &global_sam_sid, /* DOM_SID *dom_sid */
904 NULL); /* char *other_sids */
906 /* Free any allocated groups array. */
915 /*************************************************************************
917 *************************************************************************/
918 static void api_net_sam_logon( pipes_struct *p,
924 NET_USER_INFO_3 usr_info;
928 user_struct *vuser = get_valid_user_struct(p->vuid);
935 q_l.sam_id.ctr = &ctr;
936 net_io_q_sam_logon("", &q_l, data, 0);
938 status = reply_net_sam_logon(&q_l, vuser, &srv_cred, &usr_info);
939 net_reply_sam_logon(&q_l, rdata, &srv_cred, &usr_info, status);
943 /*************************************************************************
944 api_net_trust_dom_list:
945 *************************************************************************/
946 static void api_net_trust_dom_list( pipes_struct *p,
950 NET_Q_TRUST_DOM_LIST q_t;
954 enumtrustdoms(&doms, &num_doms);
956 DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
958 /* grab the lsa trusted domain list query... */
959 net_io_q_trust_dom("", &q_t, data, 0);
961 /* construct reply. */
962 net_reply_trust_dom_list(&q_t, rdata,
965 free_char_array(num_doms, doms);
967 DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
971 /*************************************************************************
972 error messages cropping up when using nltest.exe...
973 *************************************************************************/
974 #define ERROR_NO_SUCH_DOMAIN 0x54b
975 #define ERROR_NO_LOGON_SERVERS 0x51f
977 /*************************************************************************
979 *************************************************************************/
980 static void api_net_logon_ctrl2( pipes_struct *p,
984 NET_Q_LOGON_CTRL2 q_l;
986 /* lkclXXXX - guess what - absolutely no idea what these are! */
988 uint32 pdc_connection_status = 0x0;
989 uint32 logon_attempts = 0x0;
990 uint32 tc_status = ERROR_NO_LOGON_SERVERS;
991 char *trusted_domain = "test_domain";
993 DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
995 /* grab the lsa netlogon ctrl2 query... */
996 net_io_q_logon_ctrl2("", &q_l, data, 0);
998 /* construct reply. */
999 net_reply_logon_ctrl2(&q_l, rdata,
1000 flags, pdc_connection_status, logon_attempts,
1001 tc_status, trusted_domain);
1003 DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
1006 /*******************************************************************
1007 array of \PIPE\NETLOGON operations
1008 ********************************************************************/
1009 static struct api_struct api_net_cmds [] =
1011 { "NET_REQCHAL" , NET_REQCHAL , api_net_req_chal },
1012 { "NET_AUTH" , NET_AUTH , api_net_auth },
1013 { "NET_AUTH2" , NET_AUTH2 , api_net_auth_2 },
1014 { "NET_SRVPWSET" , NET_SRVPWSET , api_net_srv_pwset },
1015 { "NET_SAMLOGON" , NET_SAMLOGON , api_net_sam_logon },
1016 { "NET_SAMLOGOFF" , NET_SAMLOGOFF , api_net_sam_logoff },
1017 { "NET_LOGON_CTRL2" , NET_LOGON_CTRL2 , api_net_logon_ctrl2 },
1018 { "NET_TRUST_DOM_LIST", NET_TRUST_DOM_LIST, api_net_trust_dom_list },
1019 { "NET_SAM_SYNC" , NET_SAM_SYNC , api_net_sam_sync },
1023 /*******************************************************************
1024 receives a netlogon pipe and responds.
1025 ********************************************************************/
1026 BOOL api_netlog_rpc(pipes_struct *p, prs_struct *data)
1028 return api_rpcTNP(p, "api_netlog_rpc", api_net_cmds, data);