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_listlogon_ctrl2: %d\n", __LINE__));
109 /*************************************************************************
111 *************************************************************************/
112 static void make_net_r_auth_2(NET_R_AUTH_2 *r_a,
113 DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status)
115 memcpy( r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
116 memcpy(&(r_a->srv_flgs) , flgs , sizeof(r_a->srv_flgs));
117 r_a->status = status;
120 /*************************************************************************
122 *************************************************************************/
123 static void net_reply_auth_2(NET_Q_AUTH_2 *q_a, prs_struct *rdata,
124 DOM_CHAL *resp_cred, int status)
129 srv_flgs.neg_flags = 0x000001ff;
131 /* set up the LSA AUTH 2 response */
133 make_net_r_auth_2(&r_a, resp_cred, &srv_flgs, status);
135 /* store the response in the SMB stream */
136 net_io_r_auth_2("", &r_a, rdata, 0);
140 /***********************************************************************************
141 make_net_r_srv_pwset:
142 ***********************************************************************************/
143 static void make_net_r_srv_pwset(NET_R_SRV_PWSET *r_s,
144 DOM_CRED *srv_cred, int status)
146 DEBUG(5,("make_net_r_srv_pwset: %d\n", __LINE__));
148 memcpy(&(r_s->srv_cred), srv_cred, sizeof(r_s->srv_cred));
149 r_s->status = status;
151 DEBUG(5,("make_net_r_srv_pwset: %d\n", __LINE__));
154 /*************************************************************************
156 *************************************************************************/
157 static void net_reply_srv_pwset(NET_Q_SRV_PWSET *q_s, prs_struct *rdata,
158 DOM_CRED *srv_cred, int status)
162 DEBUG(5,("net_srv_pwset: %d\n", __LINE__));
164 /* set up the LSA Server Password Set response */
165 make_net_r_srv_pwset(&r_s, srv_cred, status);
167 /* store the response in the SMB stream */
168 net_io_r_srv_pwset("", &r_s, rdata, 0);
170 DEBUG(5,("net_srv_pwset: %d\n", __LINE__));
174 /*************************************************************************
176 *************************************************************************/
177 static void net_reply_sam_logon(NET_Q_SAM_LOGON *q_s, prs_struct *rdata,
178 DOM_CRED *srv_cred, NET_USER_INFO_3 *user_info,
183 /* XXXX maybe we want to say 'no', reject the client's credentials */
184 r_s.buffer_creds = 1; /* yes, we have valid server credentials */
185 memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
187 /* store the user information, if there is any. */
188 r_s.user = user_info;
189 if (status == 0x0 && user_info != NULL && user_info->ptr_user_info != 0)
191 r_s.switch_value = 3; /* indicates type of validation user info */
195 r_s.switch_value = 0; /* indicates no info */
199 r_s.auth_resp = 1; /* authoritative response */
201 /* store the response in the SMB stream */
202 net_io_r_sam_logon("", &r_s, rdata, 0);
207 /*************************************************************************
208 net_reply_sam_logoff:
209 *************************************************************************/
210 static void net_reply_sam_logoff(NET_Q_SAM_LOGOFF *q_s, prs_struct *rdata,
214 NET_R_SAM_LOGOFF r_s;
216 /* XXXX maybe we want to say 'no', reject the client's credentials */
217 r_s.buffer_creds = 1; /* yes, we have valid server credentials */
218 memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
222 /* store the response in the SMB stream */
223 net_io_r_sam_logoff("", &r_s, rdata, 0);
227 /*************************************************************************
229 *************************************************************************/
230 static void net_reply_sam_sync(NET_Q_SAM_SYNC *q_s, prs_struct *rdata,
231 DOM_CRED *srv_creds, uint32 status)
235 struct sam_passwd *pwd;
238 memcpy(&(r_s.srv_creds), srv_creds, sizeof(r_s.srv_creds));
239 r_s.sync_context = 1;
242 if ((status == 0x0) && ((vp = startsmbpwent(False)) != NULL))
244 /* Give the poor BDC some accounts */
246 while (((pwd = getsam21pwent(vp)) != NULL) && (i < MAX_SAM_DELTAS))
248 make_sam_delta_hdr(&r_s.hdr_deltas[i], 5, pwd->user_rid);
249 make_sam_account_info(&r_s.deltas[i].account_info,
250 pwd->nt_name, pwd->full_name, pwd->user_rid,
251 pwd->group_rid, pwd->home_dir, pwd->dir_drive,
252 pwd->logon_script, pwd->acct_desc,
253 pwd->acct_ctrl, pwd->profile_path);
260 r_s.ptr_deltas = r_s.ptr_deltas2 = 1;
261 r_s.num_deltas = r_s.num_deltas2 = i;
266 /* store the response in the SMB stream */
267 net_io_r_sam_sync("", &r_s, rdata, 0);
271 /******************************************************************
272 gets a machine password entry. checks access rights of the host.
273 ******************************************************************/
274 static BOOL get_md4pw(char *md4pw, char *mach_name, char *mach_acct)
276 struct smb_passwd *smb_pass;
280 * Currently this code is redundent as we already have a filter
281 * by hostname list. What this code really needs to do is to
282 * get a hosts allowed/hosts denied list from the SAM database
283 * on a per user basis, and make the access decision there.
284 * I will leave this code here for now as a reminder to implement
285 * this at a later date. JRA.
288 if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
289 client_name(Client), client_addr(Client)))
291 DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct));
297 smb_pass = getsmbpwnam(mach_acct);
300 if ((smb_pass) != NULL && !(smb_pass->acct_ctrl & ACB_DISABLED) &&
301 (smb_pass->smb_nt_passwd != NULL))
303 memcpy(md4pw, smb_pass->smb_nt_passwd, 16);
304 dump_data(5, md4pw, 16);
308 DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
312 /*************************************************************************
314 *************************************************************************/
315 static void api_net_req_chal( pipes_struct *p,
327 DEBUG(5,("api_net_req_chal(%d): vuid %d\n", __LINE__, (int)p->vuid));
329 if ((vuser = get_valid_user_struct(p->vuid)) == NULL)
332 /* grab the challenge... */
333 net_io_q_req_chal("", &q_r, data, 0);
335 unistr2_to_ascii(mach_acct, &q_r.uni_logon_clnt, sizeof(mach_acct)-1);
337 fstrcpy(mach_name, mach_acct);
340 fstrcat(mach_acct, "$");
342 if (get_md4pw((char *)vuser->dc.md4pw, mach_name, mach_acct))
344 /* copy the client credentials */
345 memcpy(vuser->dc.clnt_chal.data , q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
346 memcpy(vuser->dc.clnt_cred.challenge.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
348 /* create a server challenge for the client */
349 /* Set these to random values. */
350 generate_random_buffer(vuser->dc.srv_chal.data, 8, False);
352 memcpy(vuser->dc.srv_cred.challenge.data, vuser->dc.srv_chal.data, 8);
354 bzero(vuser->dc.sess_key, sizeof(vuser->dc.sess_key));
356 /* from client / server challenges and md4 password, generate sess key */
357 cred_session_key(&(vuser->dc.clnt_chal), &(vuser->dc.srv_chal),
358 (char *)vuser->dc.md4pw, vuser->dc.sess_key);
362 /* lkclXXXX take a guess at a good error message to return :-) */
363 status = 0xC0000000 | NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
366 /* construct reply. */
367 net_reply_req_chal(&q_r, rdata,
368 &(vuser->dc.srv_chal), status);
372 /*************************************************************************
374 *************************************************************************/
375 static void api_net_auth_2( pipes_struct *p,
387 if ((vuser = get_valid_user_struct(p->vuid)) == NULL)
392 /* grab the challenge... */
393 net_io_q_auth_2("", &q_a, data, 0);
395 /* check that the client credentials are valid */
396 if (cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key,
397 &(vuser->dc.clnt_cred.challenge), srv_time))
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);
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));
409 status = NT_STATUS_ACCESS_DENIED | 0xC0000000;
412 /* construct reply. */
413 net_reply_auth_2(&q_a, rdata, &srv_cred, status);
417 /*************************************************************************
419 *************************************************************************/
420 static void api_net_srv_pwset( pipes_struct *p,
425 uint32 status = NT_STATUS_WRONG_PASSWORD|0xC0000000;
428 struct smb_passwd *smb_pass;
432 if ((vuser = get_valid_user_struct(p->vuid)) == NULL)
435 /* grab the challenge and encrypted password ... */
436 net_io_q_srv_pwset("", &q_a, data, 0);
438 /* checks and updates credentials. creates reply credentials */
439 if (deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
440 &(q_a.clnt_id.cred), &srv_cred))
442 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
444 DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
446 unistr2_to_ascii(mach_acct, &q_a.clnt_id.login.uni_acct_name,
447 sizeof(mach_acct)-1);
449 DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
452 smb_pass = getsmbpwnam(mach_acct);
455 if (smb_pass != NULL)
457 unsigned char pwd[16];
460 DEBUG(100,("Server password set : new given value was :\n"));
461 for(i = 0; i < 16; i++)
463 DEBUG(100,("%02X ", q_a.pwd[i]));
467 cred_hash3( pwd, q_a.pwd, vuser->dc.sess_key, 0);
469 /* lies! nt and lm passwords are _not_ the same: don't care */
470 smb_pass->smb_passwd = pwd;
471 smb_pass->smb_nt_passwd = pwd;
472 smb_pass->acct_ctrl = ACB_WSTRUST;
475 ret = mod_smbpwd_entry(smb_pass,False);
485 DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
490 /* lkclXXXX take a guess at a sensible error code to return... */
491 status = 0xC0000000 | NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
494 /* Construct reply. */
495 net_reply_srv_pwset(&q_a, rdata, &srv_cred, status);
499 /*************************************************************************
501 *************************************************************************/
502 static void api_net_sam_logoff( pipes_struct *p,
506 NET_Q_SAM_LOGOFF q_l;
513 if ((vuser = get_valid_user_struct(p->vuid)) == NULL)
516 /* the DOM_ID_INFO_1 structure is a bit big. plus we might want to
517 dynamically allocate it inside net_io_q_sam_logon, at some point */
518 q_l.sam_id.ctr = &ctr;
520 /* grab the challenge... */
521 net_io_q_sam_logoff("", &q_l, data, 0);
523 /* checks and updates credentials. creates reply credentials */
524 deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
525 &(q_l.sam_id.client.cred), &srv_cred);
526 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
528 /* construct reply. always indicate success */
529 net_reply_sam_logoff(&q_l, rdata,
534 /*************************************************************************
536 *************************************************************************/
537 static void api_net_sam_sync( pipes_struct *p,
546 if ((vuser = get_valid_user_struct(p->vuid)) == NULL)
549 /* grab the challenge... */
550 net_io_q_sam_sync("", &q_s, data, 0);
552 /* checks and updates credentials. creates reply credentials */
553 if (deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
554 &(q_s.cli_creds), &srv_creds))
556 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred),
557 sizeof(vuser->dc.clnt_cred));
561 status = 0xC0000000 | NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
564 /* construct reply. */
565 net_reply_sam_sync(&q_s, rdata, &srv_creds, status);
569 /*************************************************************************
570 net_login_interactive:
571 *************************************************************************/
572 static uint32 net_login_interactive(NET_ID_INFO_1 *id1,
573 struct sam_passwd *smb_pass,
580 unsigned char key[16];
583 memcpy(key, vuser->dc.sess_key, 8);
585 memcpy(lm_pwd, id1->lm_owf.data, 16);
586 memcpy(nt_pwd, id1->nt_owf.data, 16);
588 #ifdef DEBUG_PASSWORD
590 dump_data(100, key, 16);
592 DEBUG(100,("lm owf password:"));
593 dump_data(100, lm_pwd, 16);
595 DEBUG(100,("nt owf password:"));
596 dump_data(100, nt_pwd, 16);
599 SamOEMhash((uchar *)lm_pwd, key, False);
600 SamOEMhash((uchar *)nt_pwd, key, False);
602 #ifdef DEBUG_PASSWORD
603 DEBUG(100,("decrypt of lm owf password:"));
604 dump_data(100, lm_pwd, 16);
606 DEBUG(100,("decrypt of nt owf password:"));
607 dump_data(100, nt_pwd, 16);
610 if (smb_pass->smb_nt_passwd == NULL)
612 DEBUG(5,("warning: NETLOGON user %s only has an LM password\n",
613 smb_pass->unix_name));
616 if (memcmp(smb_pass->smb_passwd , lm_pwd, 16) != 0 ||
617 smb_pass->smb_nt_passwd == NULL ||
618 memcmp(smb_pass->smb_nt_passwd, nt_pwd, 16) != 0)
620 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
626 /*************************************************************************
628 *************************************************************************/
629 static uint32 net_login_network(NET_ID_INFO_2 *id2,
630 struct sam_passwd *smb_pass,
636 int nt_pw_len = id2->hdr_nt_chal_resp.str_str_len;
637 int lm_pw_len = id2->hdr_lm_chal_resp.str_str_len;
639 unistr2_to_ascii(user , &id2->uni_user_name, sizeof(user)-1);
640 unistr2_to_ascii(domain, &id2->uni_domain_name, sizeof(domain)-1);
642 DEBUG(5,("net_login_network: lm_len:%d nt_len:%d user:%s domain:%s\n",
643 lm_pw_len, nt_pw_len, user, domain));
645 if (smb_password_ok(pwdb_sam_to_smb(smb_pass), id2->lm_chal,
647 (uchar *)id2->lm_chal_resp.buffer, lm_pw_len,
648 (uchar *)id2->nt_chal_resp.buffer, nt_pw_len))
653 return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
656 /*************************************************************************
658 *************************************************************************/
659 static void api_net_sam_logon( pipes_struct *p,
665 NET_USER_INFO_3 usr_info;
668 struct sam_passwd *sam_pass = NULL;
669 UNISTR2 *uni_samlogon_user = NULL;
670 UNISTR2 *uni_domain = NULL;
675 NTTIME kickoff_time ;
676 NTTIME pass_last_set_time ;
677 NTTIME pass_can_change_time ;
678 NTTIME pass_must_change_time;
682 fstring logon_script;
683 fstring profile_path;
690 user_struct *vuser = NULL;
692 if ((vuser = get_valid_user_struct(p->vuid)) == NULL)
695 q_l.sam_id.ctr = &ctr;
697 net_io_q_sam_logon("", &q_l, data, 0);
699 /* checks and updates credentials. creates reply credentials */
700 if (!deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
701 &(q_l.sam_id.client.cred), &srv_cred))
703 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
707 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
710 /* find the username */
714 switch (q_l.sam_id.logon_level)
716 case INTERACTIVE_LOGON_TYPE:
718 uni_samlogon_user = &(q_l.sam_id.ctr->auth.id1.uni_user_name);
719 uni_domain = &(q_l.sam_id.ctr->auth.id1.uni_domain_name);
721 DEBUG(3,("SAM Logon (Interactive). Domain:[%s]. ", global_sam_name));
726 uni_samlogon_user = &(q_l.sam_id.ctr->auth.id2.uni_user_name);
727 uni_domain = &(q_l.sam_id.ctr->auth.id2.uni_domain_name);
729 DEBUG(3,("SAM Logon (Network). Domain:[%s]. ", global_sam_name));
734 DEBUG(2,("SAM Logon: unsupported switch value\n"));
735 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
739 } /* end if status == 0 */
741 /* check username exists */
745 unistr2_to_ascii(nt_username, uni_samlogon_user,
746 sizeof(nt_username)-1);
748 DEBUG(3,("User:[%s]\n", nt_username));
751 sam_pass = getsam21pwntnam(nt_username);
754 if (sam_pass == NULL)
756 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
758 else if (IS_BITS_SET_ALL(sam_pass->acct_ctrl, ACB_DISABLED) &&
759 IS_BITS_CLR_ALL(sam_pass->acct_ctrl, ACB_PWNOTREQ))
761 status = 0xC0000000 | NT_STATUS_ACCOUNT_DISABLED;
767 logon_time = sam_pass->logon_time;
768 logoff_time = sam_pass->logoff_time;
769 kickoff_time = sam_pass->kickoff_time;
770 pass_last_set_time = sam_pass->pass_last_set_time;
771 pass_can_change_time = sam_pass->pass_can_change_time;
772 pass_must_change_time = sam_pass->pass_must_change_time;
774 fstrcpy(nt_name , sam_pass->nt_name);
775 fstrcpy(full_name , sam_pass->full_name);
776 fstrcpy(logon_script, sam_pass->logon_script);
777 fstrcpy(profile_path, sam_pass->profile_path);
778 fstrcpy(home_dir , sam_pass->home_dir);
779 fstrcpy(dir_drive , sam_pass->dir_drive);
781 user_rid = sam_pass->user_rid;
782 group_rid = sam_pass->group_rid;
785 /* validate password - if required */
787 if (status == 0 && !(IS_BITS_SET_ALL(sam_pass->acct_ctrl, ACB_PWNOTREQ)))
789 switch (q_l.sam_id.logon_level)
791 case INTERACTIVE_LOGON_TYPE:
793 /* interactive login. */
794 status = net_login_interactive(&q_l.sam_id.ctr->auth.id1, sam_pass, vuser);
799 /* network login. lm challenge and 24 byte responses */
800 status = net_login_network(&q_l.sam_id.ctr->auth.id2, sam_pass, vuser);
806 /* lkclXXXX this is the point at which, if the login was
807 successful, that the SAM Local Security Authority should
808 record that the user is logged in to the domain.
811 /* return the profile plus other bits :-) */
816 DOMAIN_GRP *grp_mem = NULL;
818 /* set up pointer indicating user/password failed to be found */
819 usr_info.ptr_user_info = 0;
821 if (!getusergroupsntnam(nt_username, &grp_mem, &num_gids))
823 status = 0xC0000000 | NT_STATUS_INVALID_PRIMARY_GROUP;
828 DOM_GID *gids = NULL;
829 num_gids = make_dom_gids(grp_mem, num_gids, &gids);
831 make_net_user_info3(&usr_info,
836 &pass_can_change_time,
837 &pass_must_change_time,
839 nt_name , /* user_name */
840 full_name , /* full_name */
841 logon_script , /* logon_script */
842 profile_path , /* profile_path */
843 home_dir , /* home_dir */
844 dir_drive , /* dir_drive */
847 0, /* bad_pw_count */
849 user_rid , /* RID user_id */
850 group_rid , /* RID group_id */
851 num_gids, /* uint32 num_groups */
852 gids , /* DOM_GID *gids */
853 0x20 , /* uint32 user_flgs (?) */
855 NULL, /* char sess_key[16] */
857 global_myname , /* char *logon_srv */
858 global_sam_name, /* char *logon_dom */
859 &global_sam_sid, /* DOM_SID *dom_sid */
860 NULL); /* char *other_sids */
862 /* Free any allocated groups array. */
871 net_reply_sam_logon(&q_l, rdata, &srv_cred, &usr_info, status);
875 /*************************************************************************
876 api_net_trust_dom_list:
877 *************************************************************************/
878 static void api_net_trust_dom_list( pipes_struct *p,
882 NET_Q_TRUST_DOM_LIST q_t;
884 char *trusted_domain = "test_domain";
886 DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
888 /* grab the lsa trusted domain list query... */
889 net_io_q_trust_dom("", &q_t, data, 0);
891 /* construct reply. */
892 net_reply_trust_dom_list(&q_t, rdata,
895 DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
899 /*************************************************************************
900 error messages cropping up when using nltest.exe...
901 *************************************************************************/
902 #define ERROR_NO_SUCH_DOMAIN 0x54b
903 #define ERROR_NO_LOGON_SERVERS 0x51f
905 /*************************************************************************
907 *************************************************************************/
908 static void api_net_logon_ctrl2( pipes_struct *p,
912 NET_Q_LOGON_CTRL2 q_l;
914 /* lkclXXXX - guess what - absolutely no idea what these are! */
916 uint32 pdc_connection_status = 0x0;
917 uint32 logon_attempts = 0x0;
918 uint32 tc_status = ERROR_NO_LOGON_SERVERS;
919 char *trusted_domain = "test_domain";
921 DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
923 /* grab the lsa netlogon ctrl2 query... */
924 net_io_q_logon_ctrl2("", &q_l, data, 0);
926 /* construct reply. */
927 net_reply_logon_ctrl2(&q_l, rdata,
928 flags, pdc_connection_status, logon_attempts,
929 tc_status, trusted_domain);
931 DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
934 /*******************************************************************
935 array of \PIPE\NETLOGON operations
936 ********************************************************************/
937 static struct api_struct api_net_cmds [] =
939 { "NET_REQCHAL" , NET_REQCHAL , api_net_req_chal },
940 { "NET_AUTH2" , NET_AUTH2 , api_net_auth_2 },
941 { "NET_SRVPWSET" , NET_SRVPWSET , api_net_srv_pwset },
942 { "NET_SAMLOGON" , NET_SAMLOGON , api_net_sam_logon },
943 { "NET_SAMLOGOFF" , NET_SAMLOGOFF , api_net_sam_logoff },
944 { "NET_LOGON_CTRL2" , NET_LOGON_CTRL2 , api_net_logon_ctrl2 },
945 { "NET_TRUST_DOM_LIST", NET_TRUST_DOM_LIST, api_net_trust_dom_list },
946 { "NET_SAM_SYNC" , NET_SAM_SYNC , api_net_sam_sync },
950 /*******************************************************************
951 receives a netlogon pipe and responds.
952 ********************************************************************/
953 BOOL api_netlog_rpc(pipes_struct *p, prs_struct *data)
955 return api_rpcTNP(p, "api_netlog_rpc", api_net_cmds, data);