3 * Unix SMB/Netbios implementation.
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.
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.
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.
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.
30 extern int DEBUGLEVEL;
32 extern BOOL sam_logon_in_ssb;
33 extern pstring samlogon_user;
34 extern pstring global_myname;
35 extern DOM_SID global_sam_sid;
37 /*************************************************************************
39 *************************************************************************/
41 static void init_net_r_req_chal(NET_R_REQ_CHAL *r_c,
42 DOM_CHAL *srv_chal, int status)
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));
49 /*************************************************************************
51 *************************************************************************/
53 static BOOL net_reply_req_chal(NET_Q_REQ_CHAL *q_c, prs_struct *rdata,
54 DOM_CHAL *srv_chal, uint32 srv_time)
58 DEBUG(6,("net_reply_req_chal: %d\n", __LINE__));
60 /* set up the LSA REQUEST CHALLENGE response */
61 init_net_r_req_chal(&r_c, srv_chal, srv_time);
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"));
69 DEBUG(6,("net_reply_req_chal: %d\n", __LINE__));
74 /*************************************************************************
75 net_reply_logon_ctrl2:
76 *************************************************************************/
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)
82 NET_R_LOGON_CTRL2 r_l;
84 DEBUG(6,("net_reply_logon_ctrl2: %d\n", __LINE__));
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);
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"));
97 DEBUG(6,("net_reply_logon_ctrl2: %d\n", __LINE__));
102 /*************************************************************************
103 net_reply_trust_dom_list:
104 *************************************************************************/
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)
109 NET_R_TRUST_DOM_LIST r_t;
111 DEBUG(6,("net_reply_trust_dom_list: %d\n", __LINE__));
113 /* set up the Trusted Domain List response */
114 init_r_trust_dom(&r_t, num_trust_domains, trust_domain_name);
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"));
122 DEBUG(6,("net_reply_trust_dom_listlogon_ctrl2: %d\n", __LINE__));
127 /*************************************************************************
129 *************************************************************************/
131 static void init_net_r_auth_2(NET_R_AUTH_2 *r_a,
132 DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status)
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;
139 /************************************************************************
141 *************************************************************************/
143 static BOOL net_reply_auth_2(NET_Q_AUTH_2 *q_a, prs_struct *rdata,
144 DOM_CHAL *resp_cred, int status)
149 srv_flgs.neg_flags = 0x000001ff;
151 /* set up the LSA AUTH 2 response */
153 init_net_r_auth_2(&r_a, resp_cred, &srv_flgs, status);
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"));
164 /***********************************************************************************
165 init_net_r_srv_pwset:
166 ***********************************************************************************/
168 static void init_net_r_srv_pwset(NET_R_SRV_PWSET *r_s,
169 DOM_CRED *srv_cred, int status)
171 DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__));
173 memcpy(&r_s->srv_cred, srv_cred, sizeof(r_s->srv_cred));
174 r_s->status = status;
176 DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__));
179 /*************************************************************************
181 *************************************************************************/
183 static BOOL net_reply_srv_pwset(NET_Q_SRV_PWSET *q_s, prs_struct *rdata,
184 DOM_CRED *srv_cred, int status)
188 DEBUG(5,("net_srv_pwset: %d\n", __LINE__));
190 /* set up the LSA Server Password Set response */
191 init_net_r_srv_pwset(&r_s, srv_cred, status);
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"));
199 DEBUG(5,("net_srv_pwset: %d\n", __LINE__));
204 /*************************************************************************
206 *************************************************************************/
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,
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));
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 */
223 r_s.switch_value = 0; /* indicates no info */
226 r_s.auth_resp = 1; /* authoritative response */
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"));
238 /*************************************************************************
239 net_reply_sam_logoff:
240 *************************************************************************/
242 static BOOL net_reply_sam_logoff(NET_Q_SAM_LOGOFF *q_s, prs_struct *rdata,
246 NET_R_SAM_LOGOFF r_s;
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));
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"));
263 /******************************************************************
264 gets a machine password entry. checks access rights of the host.
265 ******************************************************************/
267 static BOOL get_md4pw(char *md4pw, char *mach_name, char *mach_acct)
269 struct smb_passwd *smb_pass;
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.
281 if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
282 client_name(Client), client_addr(Client)))
284 DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct));
290 smb_pass = getsmbpwnam(mach_acct);
293 if ((smb_pass) != NULL && !(smb_pass->acct_ctrl & ACB_DISABLED) &&
294 (smb_pass->smb_nt_passwd != NULL))
296 memcpy(md4pw, smb_pass->smb_nt_passwd, 16);
297 dump_data(5, md4pw, 16);
301 DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
305 /*************************************************************************
307 *************************************************************************/
309 static BOOL api_net_req_chal( uint16 vuid, prs_struct *data, prs_struct *rdata)
319 DEBUG(5,("api_net_req_chal(%d): vuid %d\n", __LINE__, (int)vuid));
321 if ((vuser = get_valid_user_struct(vuid)) == NULL)
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"));
330 fstrcpy(mach_acct, dos_unistrn2(q_r.uni_logon_clnt.buffer,
331 q_r.uni_logon_clnt.uni_str_len));
333 fstrcpy(mach_name, mach_acct);
336 fstrcat(mach_acct, "$");
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));
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);
347 memcpy(vuser->dc.srv_cred.challenge.data, vuser->dc.srv_chal.data, 8);
349 memset((char *)vuser->dc.sess_key, '\0', sizeof(vuser->dc.sess_key));
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);
355 /* lkclXXXX take a guess at a good error message to return :-) */
356 status = 0xC0000000 | NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
359 /* construct reply. */
360 if(!net_reply_req_chal(&q_r, rdata, &vuser->dc.srv_chal, status))
366 /*************************************************************************
368 *************************************************************************/
370 static BOOL api_net_auth_2( uint16 vuid, prs_struct *data, prs_struct *rdata)
380 if ((vuser = get_valid_user_struct(vuid)) == NULL)
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"));
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)) {
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);
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));
402 status = NT_STATUS_ACCESS_DENIED | 0xC0000000;
405 /* construct reply. */
406 if(!net_reply_auth_2(&q_a, rdata, &srv_cred, status))
413 /*************************************************************************
415 *************************************************************************/
417 static BOOL api_net_srv_pwset( uint16 vuid, prs_struct *data, prs_struct *rdata)
420 uint32 status = NT_STATUS_WRONG_PASSWORD|0xC0000000;
423 struct smb_passwd *smb_pass;
427 if ((vuser = get_valid_user_struct(vuid)) == NULL)
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"));
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))
440 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
442 DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
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));
447 DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
450 smb_pass = getsmbpwnam(mach_acct);
453 if (smb_pass != NULL) {
454 unsigned char pwd[16];
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]));
462 cred_hash3( pwd, q_a.pwd, vuser->dc.sess_key, 0);
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;
470 ret = mod_smbpwd_entry(smb_pass,False);
479 DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
482 /* lkclXXXX take a guess at a sensible error code to return... */
483 status = 0xC0000000 | NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
486 /* Construct reply. */
487 if(!net_reply_srv_pwset(&q_a, rdata, &srv_cred, status))
494 /*************************************************************************
496 *************************************************************************/
498 static BOOL api_net_sam_logoff( uint16 vuid, prs_struct *data, prs_struct *rdata)
500 NET_Q_SAM_LOGOFF q_l;
507 if ((vuser = get_valid_user_struct(vuid)) == NULL)
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;
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"));
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));
525 /* construct reply. always indicate success */
526 if(!net_reply_sam_logoff(&q_l, rdata, &srv_cred, 0x0))
532 /*************************************************************************
533 net_login_interactive:
534 *************************************************************************/
536 static uint32 net_login_interactive(NET_ID_INFO_1 *id1, struct smb_passwd *smb_pass,
543 unsigned char key[16];
546 memcpy(key, vuser->dc.sess_key, 8);
548 memcpy(lm_pwd, id1->lm_owf.data, 16);
549 memcpy(nt_pwd, id1->nt_owf.data, 16);
551 #ifdef DEBUG_PASSWORD
553 dump_data(100, (char *)key, 16);
555 DEBUG(100,("lm owf password:"));
556 dump_data(100, lm_pwd, 16);
558 DEBUG(100,("nt owf password:"));
559 dump_data(100, nt_pwd, 16);
562 SamOEMhash((uchar *)lm_pwd, key, False);
563 SamOEMhash((uchar *)nt_pwd, key, False);
565 #ifdef DEBUG_PASSWORD
566 DEBUG(100,("decrypt of lm owf password:"));
567 dump_data(100, lm_pwd, 16);
569 DEBUG(100,("decrypt of nt owf password:"));
570 dump_data(100, nt_pwd, 16);
573 if (memcmp(smb_pass->smb_passwd , lm_pwd, 16) != 0 ||
574 memcmp(smb_pass->smb_nt_passwd, nt_pwd, 16) != 0)
576 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
582 /*************************************************************************
584 *************************************************************************/
586 static uint32 net_login_network(NET_ID_INFO_2 *id2, struct smb_passwd *smb_pass)
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));
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. */
595 if (id2->hdr_nt_chal_resp.str_str_len == 24 &&
596 smb_pass->smb_nt_passwd != NULL)
598 if(smb_password_check((char *)id2->nt_chal_resp.buffer,
599 smb_pass->smb_nt_passwd,
603 return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
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).
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,
623 /* oops! neither password check succeeded */
625 return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
628 /*************************************************************************
630 *************************************************************************/
632 static BOOL api_net_sam_logon( uint16 vuid, prs_struct *data, prs_struct *rdata)
636 NET_USER_INFO_3 usr_info;
639 struct smb_passwd *smb_pass = NULL;
640 UNISTR2 *uni_samlogon_user = NULL;
643 user_struct *vuser = NULL;
645 if ((vuser = get_valid_user_struct(vuid)) == NULL)
648 memset(&q_l, '\0', sizeof(q_l));
649 memset(&ctr, '\0', sizeof(ctr));
650 memset(&usr_info, '\0', sizeof(usr_info));
652 q_l.sam_id.ctr = &ctr;
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"));
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;
664 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
666 /* find the username */
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;
673 DEBUG(3,("SAM Logon (Interactive). Domain:[%s]. ", lp_workgroup()));
676 uni_samlogon_user = &q_l.sam_id.ctr->auth.id2.uni_user_name;
678 DEBUG(3,("SAM Logon (Network). Domain:[%s]. ", lp_workgroup()));
681 DEBUG(2,("SAM Logon: unsupported switch value\n"));
682 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
685 } /* end if status == 0 */
687 /* check username exists */
690 pstrcpy(nt_username, dos_unistrn2(uni_samlogon_user->buffer,
691 uni_samlogon_user->uni_str_len));
693 DEBUG(3,("User:[%s]\n", nt_username));
696 * Convert to a UNIX username.
698 map_username(nt_username);
701 * Do any case conversions.
703 (void)Get_Pwnam(nt_username, True);
706 smb_pass = getsmbpwnam(nt_username);
709 if (smb_pass == NULL)
710 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
711 else if (smb_pass->acct_ctrl & ACB_PWNOTREQ)
713 else if (smb_pass->acct_ctrl & ACB_DISABLED)
714 status = 0xC0000000 | NT_STATUS_ACCOUNT_DISABLED;
717 /* Validate password - if required. */
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);
726 /* network login. lm challenge and 24 byte responses */
727 status = net_login_network(&q_l.sam_id.ctr->auth.id2, smb_pass);
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.
737 /* return the profile plus other bits :-) */
740 DOM_GID *gids = NULL;
743 pstring logon_script;
744 pstring profile_path;
748 pstring my_workgroup;
749 pstring domain_groups;
753 /* set up pointer indicating user/password failed to be found */
754 usr_info.ptr_user_info = 0;
756 dummy_time.low = 0xffffffff;
757 dummy_time.high = 0x7fffffff;
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);
764 pstrcpy(logon_script, lp_logon_script());
765 pstrcpy(profile_path, lp_logon_path());
767 pstrcpy(my_workgroup, lp_workgroup());
769 pstrcpy(home_drive, lp_logon_drive());
770 pstrcpy(home_dir, lp_logon_home());
772 pstrcpy(my_name, global_myname);
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.
783 get_domain_user_groups(domain_groups, nt_username);
786 * make_dom_gids allocates the gids array. JRA.
789 num_gids = make_dom_gids(domain_groups, &gids);
791 sam_logon_in_ssb = False;
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 */
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 */
810 0, /* bad_pw_count */
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 (?) */
818 NULL, /* char sess_key[16] */
820 my_name , /* char *logon_srv */
821 my_workgroup, /* char *logon_dom */
823 &global_sam_sid, /* DOM_SID *dom_sid */
824 NULL); /* char *other_sids */
826 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
828 /* Free any allocated groups array. */
833 if(!net_reply_sam_logon(&q_l, rdata, &srv_cred, &usr_info, status))
840 /*************************************************************************
841 api_net_trust_dom_list:
842 *************************************************************************/
844 static BOOL api_net_trust_dom_list( uint16 vuid,
848 NET_Q_TRUST_DOM_LIST q_t;
850 char *trusted_domain = "test_domain";
852 DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
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"));
860 /* construct reply. */
861 if(!net_reply_trust_dom_list(&q_t, rdata, 1, trusted_domain))
864 DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
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
876 /*************************************************************************
878 *************************************************************************/
880 static BOOL api_net_logon_ctrl2( uint16 vuid,
884 NET_Q_LOGON_CTRL2 q_l;
886 /* lkclXXXX - guess what - absolutely no idea what these are! */
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";
893 DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
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"));
901 /* construct reply. */
902 if(!net_reply_logon_ctrl2(&q_l, rdata,
903 flags, pdc_connection_status, logon_attempts,
904 tc_status, trusted_domain))
907 DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
912 /*******************************************************************
913 array of \PIPE\NETLOGON operations
914 ********************************************************************/
915 static struct api_struct api_net_cmds [] =
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 },
927 /*******************************************************************
928 receives a netlogon pipe and responds.
929 ********************************************************************/
931 BOOL api_netlog_rpc(pipes_struct *p, prs_struct *data)
933 return api_rpcTNP(p, "api_netlog_rpc", api_net_cmds, data);