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_machine_sid;
37 /*************************************************************************
39 *************************************************************************/
40 static void make_net_r_req_chal(NET_R_REQ_CHAL *r_c,
41 DOM_CHAL *srv_chal, int status)
43 DEBUG(6,("make_net_r_req_chal: %d\n", __LINE__));
44 memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data));
48 /*************************************************************************
50 *************************************************************************/
51 static void net_reply_req_chal(NET_Q_REQ_CHAL *q_c, prs_struct *rdata,
52 DOM_CHAL *srv_chal, uint32 srv_time)
56 DEBUG(6,("net_reply_req_chal: %d\n", __LINE__));
58 /* set up the LSA REQUEST CHALLENGE response */
59 make_net_r_req_chal(&r_c, srv_chal, srv_time);
61 /* store the response in the SMB stream */
62 net_io_r_req_chal("", &r_c, rdata, 0);
64 DEBUG(6,("net_reply_req_chal: %d\n", __LINE__));
68 /*************************************************************************
69 net_reply_logon_ctrl2:
70 *************************************************************************/
71 static void net_reply_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, prs_struct *rdata,
72 uint32 flags, uint32 pdc_status, uint32 logon_attempts,
73 uint32 tc_status, char *trust_domain_name)
75 NET_R_LOGON_CTRL2 r_l;
77 DEBUG(6,("net_reply_logon_ctrl2: %d\n", __LINE__));
79 /* set up the Logon Control2 response */
80 make_r_logon_ctrl2(&r_l, q_l->query_level,
81 flags, pdc_status, logon_attempts,
82 tc_status, trust_domain_name);
84 /* store the response in the SMB stream */
85 net_io_r_logon_ctrl2("", &r_l, rdata, 0);
87 DEBUG(6,("net_reply_logon_ctrl2: %d\n", __LINE__));
91 /*************************************************************************
92 net_reply_trust_dom_list:
93 *************************************************************************/
94 static void net_reply_trust_dom_list(NET_Q_TRUST_DOM_LIST *q_t, prs_struct *rdata,
95 uint32 num_trust_domains, char *trust_domain_name)
97 NET_R_TRUST_DOM_LIST r_t;
99 DEBUG(6,("net_reply_trust_dom_list: %d\n", __LINE__));
101 /* set up the Trusted Domain List response */
102 make_r_trust_dom(&r_t, num_trust_domains, trust_domain_name);
104 /* store the response in the SMB stream */
105 net_io_r_trust_dom("", &r_t, rdata, 0);
107 DEBUG(6,("net_reply_trust_dom_listlogon_ctrl2: %d\n", __LINE__));
111 /*************************************************************************
113 *************************************************************************/
114 static void make_net_r_auth_2(NET_R_AUTH_2 *r_a,
115 DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status)
117 memcpy( r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
118 memcpy(&(r_a->srv_flgs) , flgs , sizeof(r_a->srv_flgs));
119 r_a->status = status;
122 /*************************************************************************
124 *************************************************************************/
125 static void net_reply_auth_2(NET_Q_AUTH_2 *q_a, prs_struct *rdata,
126 DOM_CHAL *resp_cred, int status)
130 /* set up the LSA AUTH 2 response */
132 make_net_r_auth_2(&r_a, resp_cred, &(q_a->clnt_flgs), status);
134 /* store the response in the SMB stream */
135 net_io_r_auth_2("", &r_a, rdata, 0);
139 /***********************************************************************************
140 make_net_r_srv_pwset:
141 ***********************************************************************************/
142 static void make_net_r_srv_pwset(NET_R_SRV_PWSET *r_s,
143 DOM_CRED *srv_cred, int status)
145 DEBUG(5,("make_net_r_srv_pwset: %d\n", __LINE__));
147 memcpy(&(r_s->srv_cred), srv_cred, sizeof(r_s->srv_cred));
148 r_s->status = status;
150 DEBUG(5,("make_net_r_srv_pwset: %d\n", __LINE__));
153 /*************************************************************************
155 *************************************************************************/
156 static void net_reply_srv_pwset(NET_Q_SRV_PWSET *q_s, prs_struct *rdata,
157 DOM_CRED *srv_cred, int status)
161 DEBUG(5,("net_srv_pwset: %d\n", __LINE__));
163 /* set up the LSA Server Password Set response */
164 make_net_r_srv_pwset(&r_s, srv_cred, status);
166 /* store the response in the SMB stream */
167 net_io_r_srv_pwset("", &r_s, rdata, 0);
169 DEBUG(5,("net_srv_pwset: %d\n", __LINE__));
173 /*************************************************************************
175 *************************************************************************/
176 static void net_reply_sam_logon(NET_Q_SAM_LOGON *q_s, prs_struct *rdata,
177 DOM_CRED *srv_cred, NET_USER_INFO_3 *user_info,
182 /* XXXX maybe we want to say 'no', reject the client's credentials */
183 r_s.buffer_creds = 1; /* yes, we have valid server credentials */
184 memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
186 /* store the user information, if there is any. */
187 r_s.user = user_info;
188 if (status == 0x0 && user_info != NULL && user_info->ptr_user_info != 0)
190 r_s.switch_value = 3; /* indicates type of validation user info */
194 r_s.switch_value = 0; /* indicates no info */
198 r_s.auth_resp = 1; /* authoritative response */
200 /* store the response in the SMB stream */
201 net_io_r_sam_logon("", &r_s, rdata, 0);
206 /*************************************************************************
207 net_reply_sam_logoff:
208 *************************************************************************/
209 static void net_reply_sam_logoff(NET_Q_SAM_LOGOFF *q_s, prs_struct *rdata,
213 NET_R_SAM_LOGOFF r_s;
215 /* XXXX maybe we want to say 'no', reject the client's credentials */
216 r_s.buffer_creds = 1; /* yes, we have valid server credentials */
217 memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
221 /* store the response in the SMB stream */
222 net_io_r_sam_logoff("", &r_s, rdata, 0);
226 /******************************************************************
227 gets a machine password entry. checks access rights of the host.
228 ******************************************************************/
229 static BOOL get_md4pw(char *md4pw, char *mach_name, char *mach_acct)
231 struct smb_passwd *smb_pass;
235 * Currently this code is redundent as we already have a filter
236 * by hostname list. What this code really needs to do is to
237 * get a hosts allowed/hosts denied list from the SAM database
238 * on a per user basis, and make the access decision there.
239 * I will leave this code here for now as a reminder to implement
240 * this at a later date. JRA.
243 if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
244 client_name(Client), client_addr(Client)))
246 DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct));
252 smb_pass = getsmbpwnam(mach_acct);
255 if ((smb_pass) != NULL && !(smb_pass->acct_ctrl & ACB_DISABLED) &&
256 (smb_pass->smb_nt_passwd != NULL))
258 memcpy(md4pw, smb_pass->smb_nt_passwd, 16);
259 dump_data(5, md4pw, 16);
263 DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
267 /*************************************************************************
269 *************************************************************************/
270 static void api_net_req_chal( uint16 vuid,
282 DEBUG(5,("api_net_req_chal(%d): vuid %d\n", __LINE__, (int)vuid));
284 if ((vuser = get_valid_user_struct(vuid)) == NULL)
287 /* grab the challenge... */
288 net_io_q_req_chal("", &q_r, data, 0);
290 fstrcpy(mach_acct, unistrn2(q_r.uni_logon_clnt.buffer,
291 q_r.uni_logon_clnt.uni_str_len));
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 pstrcpy(mach_acct, unistrn2(q_a.clnt_id.login.uni_acct_name.buffer,
403 q_a.clnt_id.login.uni_acct_name.uni_str_len));
405 DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
408 smb_pass = getsmbpwnam(mach_acct);
411 if (smb_pass != NULL)
413 unsigned char pwd[16];
416 DEBUG(100,("Server password set : new given value was :\n"));
417 for(i = 0; i < 16; i++)
419 DEBUG(100,("%02X ", q_a.pwd[i]));
423 cred_hash3( pwd, q_a.pwd, vuser->dc.sess_key, 0);
425 /* lies! nt and lm passwords are _not_ the same: don't care */
426 smb_pass->smb_passwd = pwd;
427 smb_pass->smb_nt_passwd = pwd;
428 smb_pass->acct_ctrl = ACB_WSTRUST;
431 ret = mod_smbpwd_entry(smb_pass,False);
441 DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
446 /* lkclXXXX take a guess at a sensible error code to return... */
447 status = 0xC0000000 | NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
450 /* Construct reply. */
451 net_reply_srv_pwset(&q_a, rdata, &srv_cred, status);
455 /*************************************************************************
457 *************************************************************************/
458 static void api_net_sam_logoff( uint16 vuid,
462 NET_Q_SAM_LOGOFF q_l;
469 if ((vuser = get_valid_user_struct(vuid)) == NULL)
472 /* the DOM_ID_INFO_1 structure is a bit big. plus we might want to
473 dynamically allocate it inside net_io_q_sam_logon, at some point */
474 q_l.sam_id.ctr = &ctr;
476 /* grab the challenge... */
477 net_io_q_sam_logoff("", &q_l, data, 0);
479 /* checks and updates credentials. creates reply credentials */
480 deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
481 &(q_l.sam_id.client.cred), &srv_cred);
482 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
484 /* construct reply. always indicate success */
485 net_reply_sam_logoff(&q_l, rdata,
490 /*************************************************************************
491 net_login_interactive:
492 *************************************************************************/
493 static uint32 net_login_interactive(NET_ID_INFO_1 *id1,
494 struct smb_passwd *smb_pass,
501 unsigned char key[16];
504 memcpy(key, vuser->dc.sess_key, 8);
506 memcpy(lm_pwd, id1->lm_owf.data, 16);
507 memcpy(nt_pwd, id1->nt_owf.data, 16);
509 SamOEMhash((uchar *)lm_pwd, key, False);
510 SamOEMhash((uchar *)nt_pwd, key, False);
512 #ifdef DEBUG_PASSWORD
513 DEBUG(100,("decrypt of lm owf password:"));
514 dump_data(100, lm_pwd, 16);
516 DEBUG(100,("decrypt of nt owf password:"));
517 dump_data(100, nt_pwd, 16);
520 if (memcmp(smb_pass->smb_passwd , lm_pwd, 16) != 0 &&
521 memcmp(smb_pass->smb_nt_passwd, nt_pwd, 16) != 0)
523 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
529 /*************************************************************************
531 *************************************************************************/
532 static uint32 net_login_network(NET_ID_INFO_2 *id2,
533 struct smb_passwd *smb_pass,
536 DEBUG(5,("net_login_network: lm_len: %d nt_len: %d\n",
537 id2->hdr_lm_chal_resp.str_str_len,
538 id2->hdr_nt_chal_resp.str_str_len));
540 /* JRA. Check the NT password first if it exists - this is a higher quality
541 password, if it exists and it doesn't match - fail. */
543 if (id2->hdr_nt_chal_resp.str_str_len == 24 &&
544 smb_pass->smb_nt_passwd != NULL)
546 if(smb_password_check((char *)id2->nt_chal_resp.buffer,
547 smb_pass->smb_nt_passwd,
551 return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
554 /* lkclXXXX this is not a good place to put disabling of LM hashes in.
555 if that is to be done, first move this entire function into a
556 library routine that calls the two smb_password_check() functions.
557 if disabling LM hashes (which nt can do for security reasons) then
558 an attempt should be made to disable them everywhere (which nt does
559 not do, for various security-hole reasons).
562 if (id2->hdr_lm_chal_resp.str_str_len == 24 &&
563 smb_password_check((char *)id2->lm_chal_resp.buffer,
564 smb_pass->smb_passwd,
571 /* oops! neither password check succeeded */
573 return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
576 /*************************************************************************
578 *************************************************************************/
579 static void api_net_sam_logon( uint16 vuid,
585 NET_USER_INFO_3 usr_info;
588 struct smb_passwd *smb_pass = NULL;
589 UNISTR2 *uni_samlogon_user = NULL;
591 user_struct *vuser = NULL;
593 if ((vuser = get_valid_user_struct(vuid)) == NULL)
596 q_l.sam_id.ctr = &ctr;
598 net_io_q_sam_logon("", &q_l, data, 0);
600 /* checks and updates credentials. creates reply credentials */
601 if (!deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
602 &(q_l.sam_id.client.cred), &srv_cred))
604 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
608 memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
611 /* find the username */
615 switch (q_l.sam_id.logon_level)
617 case INTERACTIVE_LOGON_TYPE:
619 uni_samlogon_user = &(q_l.sam_id.ctr->auth.id1.uni_user_name);
621 DEBUG(3,("SAM Logon (Interactive). Domain:[%s]. ", lp_workgroup()));
626 uni_samlogon_user = &(q_l.sam_id.ctr->auth.id2.uni_user_name);
628 DEBUG(3,("SAM Logon (Network). Domain:[%s]. ", lp_workgroup()));
633 DEBUG(2,("SAM Logon: unsupported switch value\n"));
634 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
638 } /* end if status == 0 */
640 /* check username exists */
644 pstrcpy(samlogon_user, unistrn2(uni_samlogon_user->buffer,
645 uni_samlogon_user->uni_str_len));
647 DEBUG(3,("User:[%s]\n", samlogon_user));
650 * Convert to a UNIX username.
652 map_username(samlogon_user);
655 * Do any case conversions.
657 (void)Get_Pwnam(samlogon_user, True);
660 smb_pass = getsmbpwnam(samlogon_user);
663 if (smb_pass == NULL)
664 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
665 else if (smb_pass->acct_ctrl & ACB_DISABLED)
666 status = 0xC0000000 | NT_STATUS_ACCOUNT_DISABLED;
669 /* validate password. */
673 switch (q_l.sam_id.logon_level)
675 case INTERACTIVE_LOGON_TYPE:
677 /* interactive login. */
678 status = net_login_interactive(&q_l.sam_id.ctr->auth.id1, smb_pass, vuser);
683 /* network login. lm challenge and 24 byte responses */
684 status = net_login_network(&q_l.sam_id.ctr->auth.id2, smb_pass, vuser);
690 /* lkclXXXX this is the point at which, if the login was
691 successful, that the SAM Local Security Authority should
692 record that the user is logged in to the domain.
695 /* return the profile plus other bits :-) */
699 DOM_GID *gids = NULL;
702 pstring logon_script;
703 pstring profile_path;
707 pstring my_workgroup;
708 pstring domain_groups;
712 /* set up pointer indicating user/password failed to be found */
713 usr_info.ptr_user_info = 0;
715 dummy_time.low = 0xffffffff;
716 dummy_time.high = 0x7fffffff;
718 /* XXXX hack to get standard_sub_basic() to use sam logon username */
719 /* possibly a better way would be to do a become_user() call */
720 sam_logon_in_ssb = True;
722 pstrcpy(logon_script, lp_logon_script());
723 pstrcpy(profile_path, lp_logon_path());
725 pstrcpy(my_workgroup, lp_workgroup());
727 pstrcpy(home_drive, lp_logon_drive());
728 pstrcpy(home_dir, lp_logon_home());
730 pstrcpy(my_name, global_myname);
734 * This is the point at which we get the group
735 * database - we should be getting the gid_t list
736 * from /etc/group and then turning the uids into
737 * rids and then into machine sids for this user.
741 get_domain_user_groups(domain_groups, samlogon_user);
744 * make_dom_gids allocates the gids array. JRA.
747 num_gids = make_dom_gids(domain_groups, &gids);
749 sam_logon_in_ssb = False;
751 if (pdb_name_to_rid(samlogon_user, &r_uid, &r_gid))
753 make_net_user_info3(&usr_info,
754 &dummy_time, /* logon_time */
755 &dummy_time, /* logoff_time */
756 &dummy_time, /* kickoff_time */
757 &dummy_time, /* pass_last_set_time */
758 &dummy_time, /* pass_can_change_time */
759 &dummy_time, /* pass_must_change_time */
761 samlogon_user , /* user_name */
762 vuser->real_name, /* full_name */
763 logon_script , /* logon_script */
764 profile_path , /* profile_path */
765 home_dir , /* home_dir */
766 home_drive , /* dir_drive */
769 0, /* bad_pw_count */
771 r_uid , /* RID user_id */
772 r_gid , /* RID group_id */
773 num_gids, /* uint32 num_groups */
774 gids , /* DOM_GID *gids */
775 0x20 , /* uint32 user_flgs (?) */
777 NULL, /* char sess_key[16] */
779 my_name , /* char *logon_srv */
780 my_workgroup, /* char *logon_dom */
782 &global_machine_sid, /* DOM_SID *dom_sid */
783 NULL); /* char *other_sids */
787 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
790 /* Free any allocated groups array. */
795 net_reply_sam_logon(&q_l, rdata, &srv_cred, &usr_info, status);
799 /*************************************************************************
800 api_net_trust_dom_list:
801 *************************************************************************/
802 static void api_net_trust_dom_list( uint16 vuid,
806 NET_Q_TRUST_DOM_LIST q_t;
808 char *trusted_domain = "test_domain";
810 DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
812 /* grab the lsa trusted domain list query... */
813 net_io_q_trust_dom("", &q_t, data, 0);
815 /* construct reply. */
816 net_reply_trust_dom_list(&q_t, rdata,
819 DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
823 /*************************************************************************
824 error messages cropping up when using nltest.exe...
825 *************************************************************************/
826 #define ERROR_NO_SUCH_DOMAIN 0x54b
827 #define ERROR_NO_LOGON_SERVERS 0x51f
829 /*************************************************************************
831 *************************************************************************/
832 static void api_net_logon_ctrl2( uint16 vuid,
836 NET_Q_LOGON_CTRL2 q_l;
838 /* lkclXXXX - guess what - absolutely no idea what these are! */
840 uint32 pdc_connection_status = 0x0;
841 uint32 logon_attempts = 0x0;
842 uint32 tc_status = ERROR_NO_LOGON_SERVERS;
843 char *trusted_domain = "test_domain";
845 DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
847 /* grab the lsa netlogon ctrl2 query... */
848 net_io_q_logon_ctrl2("", &q_l, data, 0);
850 /* construct reply. */
851 net_reply_logon_ctrl2(&q_l, rdata,
852 flags, pdc_connection_status, logon_attempts,
853 tc_status, trusted_domain);
855 DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
858 /*******************************************************************
859 array of \PIPE\NETLOGON operations
860 ********************************************************************/
861 static struct api_struct api_net_cmds [] =
863 { "NET_REQCHAL" , NET_REQCHAL , api_net_req_chal },
864 { "NET_AUTH2" , NET_AUTH2 , api_net_auth_2 },
865 { "NET_SRVPWSET" , NET_SRVPWSET , api_net_srv_pwset },
866 { "NET_SAMLOGON" , NET_SAMLOGON , api_net_sam_logon },
867 { "NET_SAMLOGOFF" , NET_SAMLOGOFF , api_net_sam_logoff },
868 { "NET_LOGON_CTRL2" , NET_LOGON_CTRL2 , api_net_logon_ctrl2 },
869 { "NET_TRUST_DOM_LIST", NET_TRUST_DOM_LIST, api_net_trust_dom_list },
873 /*******************************************************************
874 receives a netlogon pipe and responds.
875 ********************************************************************/
876 BOOL api_netlog_rpc(pipes_struct *p, prs_struct *data)
878 return api_rpcTNP(p, "api_netlog_rpc", api_net_cmds, data);