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 /******************************************************************
228 gets a machine password entry. checks access rights of the host.
229 ******************************************************************/
230 static BOOL get_md4pw(char *md4pw, char *mach_name, char *mach_acct)
232 struct smb_passwd *smb_pass;
236 * Currently this code is redundent as we already have a filter
237 * by hostname list. What this code really needs to do is to
238 * get a hosts allowed/hosts denied list from the SAM database
239 * on a per user basis, and make the access decision there.
240 * I will leave this code here for now as a reminder to implement
241 * this at a later date. JRA.
244 if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
245 client_name(Client), client_addr(Client)))
247 DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct));
253 smb_pass = getsmbpwnam(mach_acct);
256 if ((smb_pass) != NULL && !(smb_pass->acct_ctrl & ACB_DISABLED) &&
257 (smb_pass->smb_nt_passwd != NULL))
259 memcpy(md4pw, smb_pass->smb_nt_passwd, 16);
260 dump_data(5, md4pw, 16);
264 DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
268 /*************************************************************************
270 *************************************************************************/
271 static void api_net_req_chal( uint16 vuid,
283 DEBUG(5,("api_net_req_chal(%d): vuid %d\n", __LINE__, (int)vuid));
285 if ((vuser = get_valid_user_struct(vuid)) == NULL)
288 /* grab the challenge... */
289 net_io_q_req_chal("", &q_r, data, 0);
291 fstrcpy(mach_acct, unistr2_to_str(&q_r.uni_logon_clnt));
293 fstrcpy(mach_name, mach_acct);
296 fstrcat(mach_acct, "$");
298 if (get_md4pw((char *)vuser->dc.md4pw, mach_name, mach_acct))
300 /* copy the client credentials */
301 memcpy(vuser->dc.clnt_chal.data , q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
302 memcpy(vuser->dc.clnt_cred.challenge.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
304 /* create a server challenge for the client */
305 /* Set these to random values. */
306 generate_random_buffer(vuser->dc.srv_chal.data, 8, False);
308 memcpy(vuser->dc.srv_cred.challenge.data, vuser->dc.srv_chal.data, 8);
310 bzero(vuser->dc.sess_key, sizeof(vuser->dc.sess_key));
312 /* from client / server challenges and md4 password, generate sess key */
313 cred_session_key(&(vuser->dc.clnt_chal), &(vuser->dc.srv_chal),
314 (char *)vuser->dc.md4pw, vuser->dc.sess_key);
318 /* lkclXXXX take a guess at a good error message to return :-) */
319 status = 0xC0000000 | NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
322 /* construct reply. */
323 net_reply_req_chal(&q_r, rdata,
324 &(vuser->dc.srv_chal), status);
328 /*************************************************************************
330 *************************************************************************/
331 static void api_net_auth_2( uint16 vuid,
343 if ((vuser = get_valid_user_struct(vuid)) == NULL)
348 /* grab the challenge... */
349 net_io_q_auth_2("", &q_a, data, 0);
351 /* check that the client credentials are valid */
352 if (cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key,
353 &(vuser->dc.clnt_cred.challenge), srv_time))
356 /* create server challenge for inclusion in the reply */
357 cred_create(vuser->dc.sess_key, &(vuser->dc.srv_cred.challenge), srv_time, &srv_cred);
359 /* copy the received client credentials for use next time */
360 memcpy(vuser->dc.clnt_cred.challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
361 memcpy(vuser->dc.srv_cred .challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
365 status = NT_STATUS_ACCESS_DENIED | 0xC0000000;
368 /* construct reply. */
369 net_reply_auth_2(&q_a, rdata, &srv_cred, status);
373 /*************************************************************************
375 *************************************************************************/
376 static void api_net_srv_pwset( uint16 vuid,
381 uint32 status = NT_STATUS_WRONG_PASSWORD|0xC0000000;
384 struct smb_passwd *smb_pass;
388 if ((vuser = get_valid_user_struct(vuid)) == NULL)
391 /* grab the challenge and encrypted password ... */
392 net_io_q_srv_pwset("", &q_a, data, 0);
394 /* checks and updates credentials. creates reply credentials */
395 if (deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
396 &(q_a.clnt_id.cred), &srv_cred))
398 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
400 DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
402 fstrcpy(mach_acct, unistr2_to_str(&q_a.clnt_id.login.uni_acct_name));
404 DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
407 smb_pass = getsmbpwnam(mach_acct);
410 if (smb_pass != NULL)
412 unsigned char pwd[16];
415 DEBUG(100,("Server password set : new given value was :\n"));
416 for(i = 0; i < 16; i++)
418 DEBUG(100,("%02X ", q_a.pwd[i]));
422 cred_hash3( pwd, q_a.pwd, vuser->dc.sess_key, 0);
424 /* lies! nt and lm passwords are _not_ the same: don't care */
425 smb_pass->smb_passwd = pwd;
426 smb_pass->smb_nt_passwd = pwd;
427 smb_pass->acct_ctrl = ACB_WSTRUST;
430 ret = mod_smbpwd_entry(smb_pass,False);
440 DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
445 /* lkclXXXX take a guess at a sensible error code to return... */
446 status = 0xC0000000 | NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
449 /* Construct reply. */
450 net_reply_srv_pwset(&q_a, rdata, &srv_cred, status);
454 /*************************************************************************
456 *************************************************************************/
457 static void api_net_sam_logoff( uint16 vuid,
461 NET_Q_SAM_LOGOFF q_l;
468 if ((vuser = get_valid_user_struct(vuid)) == NULL)
471 /* the DOM_ID_INFO_1 structure is a bit big. plus we might want to
472 dynamically allocate it inside net_io_q_sam_logon, at some point */
473 q_l.sam_id.ctr = &ctr;
475 /* grab the challenge... */
476 net_io_q_sam_logoff("", &q_l, data, 0);
478 /* checks and updates credentials. creates reply credentials */
479 deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
480 &(q_l.sam_id.client.cred), &srv_cred);
481 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
483 /* construct reply. always indicate success */
484 net_reply_sam_logoff(&q_l, rdata,
489 /*************************************************************************
490 net_login_interactive:
491 *************************************************************************/
492 static uint32 net_login_interactive(NET_ID_INFO_1 *id1,
493 struct sam_passwd *smb_pass,
500 unsigned char key[16];
503 memcpy(key, vuser->dc.sess_key, 8);
505 memcpy(lm_pwd, id1->lm_owf.data, 16);
506 memcpy(nt_pwd, id1->nt_owf.data, 16);
508 #ifdef DEBUG_PASSWORD
510 dump_data(100, key, 16);
512 DEBUG(100,("lm owf password:"));
513 dump_data(100, lm_pwd, 16);
515 DEBUG(100,("nt owf password:"));
516 dump_data(100, nt_pwd, 16);
519 SamOEMhash((uchar *)lm_pwd, key, False);
520 SamOEMhash((uchar *)nt_pwd, key, False);
522 #ifdef DEBUG_PASSWORD
523 DEBUG(100,("decrypt of lm owf password:"));
524 dump_data(100, lm_pwd, 16);
526 DEBUG(100,("decrypt of nt owf password:"));
527 dump_data(100, nt_pwd, 16);
530 if (memcmp(smb_pass->smb_passwd , lm_pwd, 16) != 0 &&
531 memcmp(smb_pass->smb_nt_passwd, nt_pwd, 16) != 0)
533 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
539 /*************************************************************************
541 *************************************************************************/
542 static uint32 net_login_network(NET_ID_INFO_2 *id2,
543 struct sam_passwd *smb_pass,
546 DEBUG(5,("net_login_network: lm_len: %d nt_len: %d\n",
547 id2->hdr_lm_chal_resp.str_str_len,
548 id2->hdr_nt_chal_resp.str_str_len));
550 /* JRA. Check the NT password first if it exists - this is a higher quality
551 password, if it exists and it doesn't match - fail. */
553 if (id2->hdr_nt_chal_resp.str_str_len == 24 &&
554 smb_pass->smb_nt_passwd != NULL)
556 if(smb_password_check((char *)id2->nt_chal_resp.buffer,
557 smb_pass->smb_nt_passwd,
561 return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
564 /* lkclXXXX this is not a good place to put disabling of LM hashes in.
565 if that is to be done, first move this entire function into a
566 library routine that calls the two smb_password_check() functions.
567 if disabling LM hashes (which nt can do for security reasons) then
568 an attempt should be made to disable them everywhere (which nt does
569 not do, for various security-hole reasons).
572 if (id2->hdr_lm_chal_resp.str_str_len == 24 &&
573 smb_password_check((char *)id2->lm_chal_resp.buffer,
574 smb_pass->smb_passwd,
581 /* oops! neither password check succeeded */
583 return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
586 /*************************************************************************
588 *************************************************************************/
589 static void api_net_sam_logon( uint16 vuid,
595 NET_USER_INFO_3 usr_info;
598 struct sam_passwd *sam_pass = NULL;
599 UNISTR2 *uni_samlogon_user = NULL;
600 UNISTR2 *uni_domain = NULL;
605 NTTIME kickoff_time ;
606 NTTIME pass_last_set_time ;
607 NTTIME pass_can_change_time ;
608 NTTIME pass_must_change_time;
612 fstring logon_script;
613 fstring profile_path;
620 user_struct *vuser = NULL;
622 if ((vuser = get_valid_user_struct(vuid)) == NULL)
625 q_l.sam_id.ctr = &ctr;
627 net_io_q_sam_logon("", &q_l, data, 0);
629 /* checks and updates credentials. creates reply credentials */
630 if (!deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
631 &(q_l.sam_id.client.cred), &srv_cred))
633 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
637 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
640 /* find the username */
644 switch (q_l.sam_id.logon_level)
646 case INTERACTIVE_LOGON_TYPE:
648 uni_samlogon_user = &(q_l.sam_id.ctr->auth.id1.uni_user_name);
649 uni_domain = &(q_l.sam_id.ctr->auth.id1.uni_domain_name);
651 DEBUG(3,("SAM Logon (Interactive). Domain:[%s]. ", global_sam_name));
656 uni_samlogon_user = &(q_l.sam_id.ctr->auth.id2.uni_user_name);
657 uni_domain = &(q_l.sam_id.ctr->auth.id2.uni_domain_name);
659 DEBUG(3,("SAM Logon (Network). Domain:[%s]. ", global_sam_name));
664 DEBUG(2,("SAM Logon: unsupported switch value\n"));
665 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
669 } /* end if status == 0 */
671 /* check username exists */
675 fstrcpy(nt_username, unistr2_to_str(uni_samlogon_user));
677 slprintf(nt_username, sizeof(nt_username), "%s\\%s",
678 unistr2_to_str(uni_domain),
679 unistr2_to_str(uni_samlogon_user));
681 DEBUG(3,("User:[%s]\n", nt_username));
684 sam_pass = getsam21pwntnam(nt_username);
687 if (sam_pass == NULL)
689 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
691 else if (IS_BITS_SET_ALL(sam_pass->acct_ctrl, ACB_DISABLED) &&
692 IS_BITS_CLR_ALL(sam_pass->acct_ctrl, ACB_PWNOTREQ))
694 status = 0xC0000000 | NT_STATUS_ACCOUNT_DISABLED;
700 logon_time = sam_pass->logon_time;
701 logoff_time = sam_pass->logoff_time;
702 kickoff_time = sam_pass->kickoff_time;
703 pass_last_set_time = sam_pass->pass_last_set_time;
704 pass_can_change_time = sam_pass->pass_can_change_time;
705 pass_must_change_time = sam_pass->pass_must_change_time;
707 fstrcpy(nt_name , sam_pass->nt_name);
708 fstrcpy(full_name , sam_pass->full_name);
709 fstrcpy(logon_script, sam_pass->logon_script);
710 fstrcpy(profile_path, sam_pass->profile_path);
711 fstrcpy(home_dir , sam_pass->home_dir);
712 fstrcpy(dir_drive , sam_pass->dir_drive);
714 user_rid = sam_pass->user_rid;
715 group_rid = sam_pass->group_rid;
718 /* validate password - if required */
720 if (status == 0 && !(IS_BITS_SET_ALL(sam_pass->acct_ctrl, ACB_PWNOTREQ)))
722 switch (q_l.sam_id.logon_level)
724 case INTERACTIVE_LOGON_TYPE:
726 /* interactive login. */
727 status = net_login_interactive(&q_l.sam_id.ctr->auth.id1, sam_pass, vuser);
732 /* network login. lm challenge and 24 byte responses */
733 status = net_login_network(&q_l.sam_id.ctr->auth.id2, sam_pass, vuser);
739 /* lkclXXXX this is the point at which, if the login was
740 successful, that the SAM Local Security Authority should
741 record that the user is logged in to the domain.
744 /* return the profile plus other bits :-) */
749 DOMAIN_GRP *grp_mem = NULL;
751 /* set up pointer indicating user/password failed to be found */
752 usr_info.ptr_user_info = 0;
754 if (!getusergroupsntnam(nt_username, &grp_mem, &num_gids))
756 status = 0xC0000000 | NT_STATUS_INVALID_PRIMARY_GROUP;
761 DOM_GID *gids = NULL;
762 num_gids = make_dom_gids(grp_mem, num_gids, &gids);
764 make_net_user_info3(&usr_info,
769 &pass_can_change_time,
770 &pass_must_change_time,
772 nt_name , /* user_name */
773 full_name , /* full_name */
774 logon_script , /* logon_script */
775 profile_path , /* profile_path */
776 home_dir , /* home_dir */
777 dir_drive , /* dir_drive */
780 0, /* bad_pw_count */
782 user_rid , /* RID user_id */
783 group_rid , /* RID group_id */
784 num_gids, /* uint32 num_groups */
785 gids , /* DOM_GID *gids */
786 0x20 , /* uint32 user_flgs (?) */
788 NULL, /* char sess_key[16] */
790 global_myname , /* char *logon_srv */
791 global_sam_name, /* char *logon_dom */
792 &global_sam_sid, /* DOM_SID *dom_sid */
793 NULL); /* char *other_sids */
795 /* Free any allocated groups array. */
804 net_reply_sam_logon(&q_l, rdata, &srv_cred, &usr_info, status);
808 /*************************************************************************
809 api_net_trust_dom_list:
810 *************************************************************************/
811 static void api_net_trust_dom_list( uint16 vuid,
815 NET_Q_TRUST_DOM_LIST q_t;
817 char *trusted_domain = "test_domain";
819 DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
821 /* grab the lsa trusted domain list query... */
822 net_io_q_trust_dom("", &q_t, data, 0);
824 /* construct reply. */
825 net_reply_trust_dom_list(&q_t, rdata,
828 DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
832 /*************************************************************************
833 error messages cropping up when using nltest.exe...
834 *************************************************************************/
835 #define ERROR_NO_SUCH_DOMAIN 0x54b
836 #define ERROR_NO_LOGON_SERVERS 0x51f
838 /*************************************************************************
840 *************************************************************************/
841 static void api_net_logon_ctrl2( uint16 vuid,
845 NET_Q_LOGON_CTRL2 q_l;
847 /* lkclXXXX - guess what - absolutely no idea what these are! */
849 uint32 pdc_connection_status = 0x0;
850 uint32 logon_attempts = 0x0;
851 uint32 tc_status = ERROR_NO_LOGON_SERVERS;
852 char *trusted_domain = "test_domain";
854 DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
856 /* grab the lsa netlogon ctrl2 query... */
857 net_io_q_logon_ctrl2("", &q_l, data, 0);
859 /* construct reply. */
860 net_reply_logon_ctrl2(&q_l, rdata,
861 flags, pdc_connection_status, logon_attempts,
862 tc_status, trusted_domain);
864 DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
867 /*******************************************************************
868 array of \PIPE\NETLOGON operations
869 ********************************************************************/
870 static struct api_struct api_net_cmds [] =
872 { "NET_REQCHAL" , NET_REQCHAL , api_net_req_chal },
873 { "NET_AUTH2" , NET_AUTH2 , api_net_auth_2 },
874 { "NET_SRVPWSET" , NET_SRVPWSET , api_net_srv_pwset },
875 { "NET_SAMLOGON" , NET_SAMLOGON , api_net_sam_logon },
876 { "NET_SAMLOGOFF" , NET_SAMLOGOFF , api_net_sam_logoff },
877 { "NET_LOGON_CTRL2" , NET_LOGON_CTRL2 , api_net_logon_ctrl2 },
878 { "NET_TRUST_DOM_LIST", NET_TRUST_DOM_LIST, api_net_trust_dom_list },
882 /*******************************************************************
883 receives a netlogon pipe and responds.
884 ********************************************************************/
885 BOOL api_netlog_rpc(pipes_struct *p, prs_struct *data)
887 return api_rpcTNP(p, "api_netlog_rpc", api_net_cmds, data);