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, unistrn2(q_r.uni_logon_clnt.buffer,
292 q_r.uni_logon_clnt.uni_str_len));
294 fstrcpy(mach_name, mach_acct);
297 fstrcat(mach_acct, "$");
299 if (get_md4pw((char *)vuser->dc.md4pw, mach_name, mach_acct))
301 /* copy the client credentials */
302 memcpy(vuser->dc.clnt_chal.data , q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
303 memcpy(vuser->dc.clnt_cred.challenge.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
305 /* create a server challenge for the client */
306 /* Set these to random values. */
307 generate_random_buffer(vuser->dc.srv_chal.data, 8, False);
309 memcpy(vuser->dc.srv_cred.challenge.data, vuser->dc.srv_chal.data, 8);
311 bzero(vuser->dc.sess_key, sizeof(vuser->dc.sess_key));
313 /* from client / server challenges and md4 password, generate sess key */
314 cred_session_key(&(vuser->dc.clnt_chal), &(vuser->dc.srv_chal),
315 (char *)vuser->dc.md4pw, vuser->dc.sess_key);
319 /* lkclXXXX take a guess at a good error message to return :-) */
320 status = 0xC0000000 | NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
323 /* construct reply. */
324 net_reply_req_chal(&q_r, rdata,
325 &(vuser->dc.srv_chal), status);
329 /*************************************************************************
331 *************************************************************************/
332 static void api_net_auth_2( uint16 vuid,
344 if ((vuser = get_valid_user_struct(vuid)) == NULL)
349 /* grab the challenge... */
350 net_io_q_auth_2("", &q_a, data, 0);
352 /* check that the client credentials are valid */
353 if (cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key,
354 &(vuser->dc.clnt_cred.challenge), srv_time))
357 /* create server challenge for inclusion in the reply */
358 cred_create(vuser->dc.sess_key, &(vuser->dc.srv_cred.challenge), srv_time, &srv_cred);
360 /* copy the received client credentials for use next time */
361 memcpy(vuser->dc.clnt_cred.challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
362 memcpy(vuser->dc.srv_cred .challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
366 status = NT_STATUS_ACCESS_DENIED | 0xC0000000;
369 /* construct reply. */
370 net_reply_auth_2(&q_a, rdata, &srv_cred, status);
374 /*************************************************************************
376 *************************************************************************/
377 static void api_net_srv_pwset( uint16 vuid,
382 uint32 status = NT_STATUS_WRONG_PASSWORD|0xC0000000;
385 struct smb_passwd *smb_pass;
389 if ((vuser = get_valid_user_struct(vuid)) == NULL)
392 /* grab the challenge and encrypted password ... */
393 net_io_q_srv_pwset("", &q_a, data, 0);
395 /* checks and updates credentials. creates reply credentials */
396 if (deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
397 &(q_a.clnt_id.cred), &srv_cred))
399 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
401 DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
403 pstrcpy(mach_acct, unistrn2(q_a.clnt_id.login.uni_acct_name.buffer,
404 q_a.clnt_id.login.uni_acct_name.uni_str_len));
406 DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
409 smb_pass = getsmbpwnam(mach_acct);
412 if (smb_pass != NULL)
414 unsigned char pwd[16];
417 DEBUG(100,("Server password set : new given value was :\n"));
418 for(i = 0; i < 16; i++)
420 DEBUG(100,("%02X ", q_a.pwd[i]));
424 cred_hash3( pwd, q_a.pwd, vuser->dc.sess_key, 0);
426 /* lies! nt and lm passwords are _not_ the same: don't care */
427 smb_pass->smb_passwd = pwd;
428 smb_pass->smb_nt_passwd = pwd;
429 smb_pass->acct_ctrl = ACB_WSTRUST;
432 ret = mod_smbpwd_entry(smb_pass,False);
442 DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
447 /* lkclXXXX take a guess at a sensible error code to return... */
448 status = 0xC0000000 | NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
451 /* Construct reply. */
452 net_reply_srv_pwset(&q_a, rdata, &srv_cred, status);
456 /*************************************************************************
458 *************************************************************************/
459 static void api_net_sam_logoff( uint16 vuid,
463 NET_Q_SAM_LOGOFF q_l;
470 if ((vuser = get_valid_user_struct(vuid)) == NULL)
473 /* the DOM_ID_INFO_1 structure is a bit big. plus we might want to
474 dynamically allocate it inside net_io_q_sam_logon, at some point */
475 q_l.sam_id.ctr = &ctr;
477 /* grab the challenge... */
478 net_io_q_sam_logoff("", &q_l, data, 0);
480 /* checks and updates credentials. creates reply credentials */
481 deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
482 &(q_l.sam_id.client.cred), &srv_cred);
483 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
485 /* construct reply. always indicate success */
486 net_reply_sam_logoff(&q_l, rdata,
491 /*************************************************************************
492 net_login_interactive:
493 *************************************************************************/
494 static uint32 net_login_interactive(NET_ID_INFO_1 *id1,
495 struct sam_passwd *smb_pass,
502 unsigned char key[16];
505 memcpy(key, vuser->dc.sess_key, 8);
507 memcpy(lm_pwd, id1->lm_owf.data, 16);
508 memcpy(nt_pwd, id1->nt_owf.data, 16);
510 #ifdef DEBUG_PASSWORD
512 dump_data(100, key, 16);
514 DEBUG(100,("lm owf password:"));
515 dump_data(100, lm_pwd, 16);
517 DEBUG(100,("nt owf password:"));
518 dump_data(100, nt_pwd, 16);
521 SamOEMhash((uchar *)lm_pwd, key, False);
522 SamOEMhash((uchar *)nt_pwd, key, False);
524 #ifdef DEBUG_PASSWORD
525 DEBUG(100,("decrypt of lm owf password:"));
526 dump_data(100, lm_pwd, 16);
528 DEBUG(100,("decrypt of nt owf password:"));
529 dump_data(100, nt_pwd, 16);
532 if (memcmp(smb_pass->smb_passwd , lm_pwd, 16) != 0 &&
533 memcmp(smb_pass->smb_nt_passwd, nt_pwd, 16) != 0)
535 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
541 /*************************************************************************
543 *************************************************************************/
544 static uint32 net_login_network(NET_ID_INFO_2 *id2,
545 struct sam_passwd *smb_pass,
548 DEBUG(5,("net_login_network: lm_len: %d nt_len: %d\n",
549 id2->hdr_lm_chal_resp.str_str_len,
550 id2->hdr_nt_chal_resp.str_str_len));
552 /* JRA. Check the NT password first if it exists - this is a higher quality
553 password, if it exists and it doesn't match - fail. */
555 if (id2->hdr_nt_chal_resp.str_str_len == 24 &&
556 smb_pass->smb_nt_passwd != NULL)
558 if(smb_password_check((char *)id2->nt_chal_resp.buffer,
559 smb_pass->smb_nt_passwd,
563 return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
566 /* lkclXXXX this is not a good place to put disabling of LM hashes in.
567 if that is to be done, first move this entire function into a
568 library routine that calls the two smb_password_check() functions.
569 if disabling LM hashes (which nt can do for security reasons) then
570 an attempt should be made to disable them everywhere (which nt does
571 not do, for various security-hole reasons).
574 if (id2->hdr_lm_chal_resp.str_str_len == 24 &&
575 smb_password_check((char *)id2->lm_chal_resp.buffer,
576 smb_pass->smb_passwd,
583 /* oops! neither password check succeeded */
585 return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
588 /*************************************************************************
590 *************************************************************************/
591 static void api_net_sam_logon( uint16 vuid,
597 NET_USER_INFO_3 usr_info;
600 struct sam_passwd *sam_pass = NULL;
601 UNISTR2 *uni_samlogon_user = NULL;
602 UNISTR2 *uni_domain = NULL;
607 NTTIME kickoff_time ;
608 NTTIME pass_last_set_time ;
609 NTTIME pass_can_change_time ;
610 NTTIME pass_must_change_time;
614 fstring logon_script;
615 fstring profile_path;
622 user_struct *vuser = NULL;
624 if ((vuser = get_valid_user_struct(vuid)) == NULL)
627 q_l.sam_id.ctr = &ctr;
629 net_io_q_sam_logon("", &q_l, data, 0);
631 /* checks and updates credentials. creates reply credentials */
632 if (!deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
633 &(q_l.sam_id.client.cred), &srv_cred))
635 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
639 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
642 /* find the username */
646 switch (q_l.sam_id.logon_level)
648 case INTERACTIVE_LOGON_TYPE:
650 uni_samlogon_user = &(q_l.sam_id.ctr->auth.id1.uni_user_name);
651 uni_domain = &(q_l.sam_id.ctr->auth.id1.uni_domain_name);
653 DEBUG(3,("SAM Logon (Interactive). Domain:[%s]. ", global_sam_name));
658 uni_samlogon_user = &(q_l.sam_id.ctr->auth.id2.uni_user_name);
659 uni_domain = &(q_l.sam_id.ctr->auth.id2.uni_domain_name);
661 DEBUG(3,("SAM Logon (Network). Domain:[%s]. ", global_sam_name));
666 DEBUG(2,("SAM Logon: unsupported switch value\n"));
667 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
671 } /* end if status == 0 */
673 /* check username exists */
677 fstrcpy(nt_username, unistr2_to_str(uni_samlogon_user));
679 slprintf(nt_username, sizeof(nt_username), "%s\\%s",
680 unistr2_to_str(uni_domain),
681 unistr2_to_str(uni_samlogon_user));
683 DEBUG(3,("User:[%s]\n", nt_username));
686 sam_pass = getsam21pwntnam(nt_username);
689 if (sam_pass == NULL)
691 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
693 else if (IS_BITS_SET_ALL(sam_pass->acct_ctrl, ACB_DISABLED) &&
694 IS_BITS_CLR_ALL(sam_pass->acct_ctrl, ACB_PWNOTREQ))
696 status = 0xC0000000 | NT_STATUS_ACCOUNT_DISABLED;
702 logon_time = sam_pass->logon_time;
703 logoff_time = sam_pass->logoff_time;
704 kickoff_time = sam_pass->kickoff_time;
705 pass_last_set_time = sam_pass->pass_last_set_time;
706 pass_can_change_time = sam_pass->pass_can_change_time;
707 pass_must_change_time = sam_pass->pass_must_change_time;
709 fstrcpy(nt_name , sam_pass->nt_name);
710 fstrcpy(full_name , sam_pass->full_name);
711 fstrcpy(logon_script, sam_pass->logon_script);
712 fstrcpy(profile_path, sam_pass->profile_path);
713 fstrcpy(home_dir , sam_pass->home_dir);
714 fstrcpy(dir_drive , sam_pass->dir_drive);
716 user_rid = sam_pass->user_rid;
717 group_rid = sam_pass->group_rid;
720 /* validate password - if required */
722 if (status == 0 && !(IS_BITS_SET_ALL(sam_pass->acct_ctrl, ACB_PWNOTREQ)))
724 switch (q_l.sam_id.logon_level)
726 case INTERACTIVE_LOGON_TYPE:
728 /* interactive login. */
729 status = net_login_interactive(&q_l.sam_id.ctr->auth.id1, sam_pass, vuser);
734 /* network login. lm challenge and 24 byte responses */
735 status = net_login_network(&q_l.sam_id.ctr->auth.id2, sam_pass, vuser);
741 /* lkclXXXX this is the point at which, if the login was
742 successful, that the SAM Local Security Authority should
743 record that the user is logged in to the domain.
746 /* return the profile plus other bits :-) */
751 DOMAIN_GRP *grp_mem = NULL;
753 /* set up pointer indicating user/password failed to be found */
754 usr_info.ptr_user_info = 0;
756 if (!getusergroupsntnam(nt_username, &grp_mem, &num_gids))
758 status = 0xC0000000 | NT_STATUS_INVALID_PRIMARY_GROUP;
763 DOM_GID *gids = NULL;
764 num_gids = make_dom_gids(grp_mem, num_gids, &gids);
766 make_net_user_info3(&usr_info,
771 &pass_can_change_time,
772 &pass_must_change_time,
774 nt_name , /* user_name */
775 full_name , /* full_name */
776 logon_script , /* logon_script */
777 profile_path , /* profile_path */
778 home_dir , /* home_dir */
779 dir_drive , /* dir_drive */
782 0, /* bad_pw_count */
784 user_rid , /* RID user_id */
785 group_rid , /* RID group_id */
786 num_gids, /* uint32 num_groups */
787 gids , /* DOM_GID *gids */
788 0x20 , /* uint32 user_flgs (?) */
790 NULL, /* char sess_key[16] */
792 global_myname , /* char *logon_srv */
793 global_sam_name, /* char *logon_dom */
794 &global_sam_sid, /* DOM_SID *dom_sid */
795 NULL); /* char *other_sids */
797 /* Free any allocated groups array. */
806 net_reply_sam_logon(&q_l, rdata, &srv_cred, &usr_info, status);
810 /*************************************************************************
811 api_net_trust_dom_list:
812 *************************************************************************/
813 static void api_net_trust_dom_list( uint16 vuid,
817 NET_Q_TRUST_DOM_LIST q_t;
819 char *trusted_domain = "test_domain";
821 DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
823 /* grab the lsa trusted domain list query... */
824 net_io_q_trust_dom("", &q_t, data, 0);
826 /* construct reply. */
827 net_reply_trust_dom_list(&q_t, rdata,
830 DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
834 /*************************************************************************
835 error messages cropping up when using nltest.exe...
836 *************************************************************************/
837 #define ERROR_NO_SUCH_DOMAIN 0x54b
838 #define ERROR_NO_LOGON_SERVERS 0x51f
840 /*************************************************************************
842 *************************************************************************/
843 static void api_net_logon_ctrl2( uint16 vuid,
847 NET_Q_LOGON_CTRL2 q_l;
849 /* lkclXXXX - guess what - absolutely no idea what these are! */
851 uint32 pdc_connection_status = 0x0;
852 uint32 logon_attempts = 0x0;
853 uint32 tc_status = ERROR_NO_LOGON_SERVERS;
854 char *trusted_domain = "test_domain";
856 DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
858 /* grab the lsa netlogon ctrl2 query... */
859 net_io_q_logon_ctrl2("", &q_l, data, 0);
861 /* construct reply. */
862 net_reply_logon_ctrl2(&q_l, rdata,
863 flags, pdc_connection_status, logon_attempts,
864 tc_status, trusted_domain);
866 DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
869 /*******************************************************************
870 array of \PIPE\NETLOGON operations
871 ********************************************************************/
872 static struct api_struct api_net_cmds [] =
874 { "NET_REQCHAL" , NET_REQCHAL , api_net_req_chal },
875 { "NET_AUTH2" , NET_AUTH2 , api_net_auth_2 },
876 { "NET_SRVPWSET" , NET_SRVPWSET , api_net_srv_pwset },
877 { "NET_SAMLOGON" , NET_SAMLOGON , api_net_sam_logon },
878 { "NET_SAMLOGOFF" , NET_SAMLOGOFF , api_net_sam_logoff },
879 { "NET_LOGON_CTRL2" , NET_LOGON_CTRL2 , api_net_logon_ctrl2 },
880 { "NET_TRUST_DOM_LIST", NET_TRUST_DOM_LIST, api_net_trust_dom_list },
884 /*******************************************************************
885 receives a netlogon pipe and responds.
886 ********************************************************************/
887 BOOL api_netlog_rpc(pipes_struct *p, prs_struct *data)
889 return api_rpcTNP(p, "api_netlog_rpc", api_net_cmds, data);