📄 srv_netlog_nt.c
字号:
/* * Unix SMB/CIFS implementation. * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-1997, * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Paul Ashton 1997. * Copyright (C) Jeremy Allison 1998-2001. * Copyright (C) Andrew Bartlett 2001. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* This is the implementation of the netlogon pipe. */#include "includes.h"extern userdom_struct current_user_info;#undef DBGC_CLASS#define DBGC_CLASS DBGC_RPC_SRV/************************************************************************* init_net_r_req_chal: *************************************************************************/static void init_net_r_req_chal(NET_R_REQ_CHAL *r_c, DOM_CHAL *srv_chal, NTSTATUS status){ DEBUG(6,("init_net_r_req_chal: %d\n", __LINE__)); memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data)); r_c->status = status;}/************************************************************************* error messages cropping up when using nltest.exe... *************************************************************************/#define ERROR_NO_SUCH_DOMAIN 0x54b#define ERROR_NO_LOGON_SERVERS 0x51f#define NO_ERROR 0x0/************************************************************************* net_reply_logon_ctrl: *************************************************************************/NTSTATUS _net_logon_ctrl(pipes_struct *p, NET_Q_LOGON_CTRL *q_u, NET_R_LOGON_CTRL *r_u){ uint32 flags = 0x0; uint32 pdc_connection_status = 0x00; /* Maybe a win32 error code? */ /* Setup the Logon Control response */ init_net_r_logon_ctrl(r_u, q_u->query_level, flags, pdc_connection_status); return r_u->status;}/****************************************************************************Send a message to smbd to do a sam synchronisation**************************************************************************/static void send_sync_message(void){ TDB_CONTEXT *tdb; tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0); if (!tdb) { DEBUG(3, ("send_sync_message(): failed to open connections " "database\n")); return; } DEBUG(3, ("sending sam synchronisation message\n")); message_send_all(tdb, MSG_SMB_SAM_SYNC, NULL, 0, False, NULL); tdb_close(tdb);}/************************************************************************* net_reply_logon_ctrl2: *************************************************************************/NTSTATUS _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_CTRL2 *r_u){ uint32 flags = 0x0; uint32 pdc_connection_status = 0x0; uint32 logon_attempts = 0x0; uint32 tc_status; fstring servername, domain, dc_name, dc_name2; struct in_addr dc_ip; /* this should be \\global_myname() */ unistr2_to_ascii(servername, &q_u->uni_server_name, sizeof(servername)); r_u->status = NT_STATUS_OK; tc_status = ERROR_NO_SUCH_DOMAIN; fstrcpy( dc_name, "" ); switch ( q_u->function_code ) { case NETLOGON_CONTROL_TC_QUERY: unistr2_to_ascii(domain, &q_u->info.info6.domain, sizeof(domain)); if ( !is_trusted_domain( domain ) ) break; if ( !get_dc_name( domain, NULL, dc_name2, &dc_ip ) ) { tc_status = ERROR_NO_LOGON_SERVERS; break; } fstr_sprintf( dc_name, "\\\\%s", dc_name2 ); tc_status = NO_ERROR; break; case NETLOGON_CONTROL_REDISCOVER: unistr2_to_ascii(domain, &q_u->info.info6.domain, sizeof(domain)); if ( !is_trusted_domain( domain ) ) break; if ( !get_dc_name( domain, NULL, dc_name2, &dc_ip ) ) { tc_status = ERROR_NO_LOGON_SERVERS; break; } fstr_sprintf( dc_name, "\\\\%s", dc_name2 ); tc_status = NO_ERROR; break; default: /* no idea what this should be */ DEBUG(0,("_net_logon_ctrl2: unimplemented function level [%d]\n", q_u->function_code)); } /* prepare the response */ init_net_r_logon_ctrl2( r_u, q_u->query_level, flags, pdc_connection_status, logon_attempts, tc_status, dc_name ); if (lp_server_role() == ROLE_DOMAIN_BDC) send_sync_message(); return r_u->status;}/************************************************************************* net_reply_trust_dom_list: *************************************************************************/NTSTATUS _net_trust_dom_list(pipes_struct *p, NET_Q_TRUST_DOM_LIST *q_u, NET_R_TRUST_DOM_LIST *r_u){ const char *trusted_domain = "test_domain"; uint32 num_trust_domains = 1; DEBUG(6,("_net_trust_dom_list: %d\n", __LINE__)); /* set up the Trusted Domain List response */ init_r_trust_dom(r_u, num_trust_domains, trusted_domain); DEBUG(6,("_net_trust_dom_list: %d\n", __LINE__)); return r_u->status;}/*********************************************************************************** init_net_r_srv_pwset: ***********************************************************************************/static void init_net_r_srv_pwset(NET_R_SRV_PWSET *r_s, DOM_CRED *srv_cred, NTSTATUS status) { DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__)); memcpy(&r_s->srv_cred, srv_cred, sizeof(r_s->srv_cred)); r_s->status = status; DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__));}/****************************************************************** gets a machine password entry. checks access rights of the host. ******************************************************************/static BOOL get_md4pw(char *md4pw, char *mach_acct){ SAM_ACCOUNT *sampass = NULL; const uint8 *pass; BOOL ret; uint32 acct_ctrl;#if 0 /* * Currently this code is redundent as we already have a filter * by hostname list. What this code really needs to do is to * get a hosts allowed/hosts denied list from the SAM database * on a per user basis, and make the access decision there. * I will leave this code here for now as a reminder to implement * this at a later date. JRA. */ if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(), client_name(), client_addr())) { DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct)); return False; }#endif /* 0 */ if(!NT_STATUS_IS_OK(pdb_init_sam(&sampass))) return False; /* JRA. This is ok as it is only used for generating the challenge. */ become_root(); ret=pdb_getsampwnam(sampass, mach_acct); unbecome_root(); if (ret==False) { DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct)); pdb_free_sam(&sampass); return False; } acct_ctrl = pdb_get_acct_ctrl(sampass); if (!(acct_ctrl & ACB_DISABLED) && ((acct_ctrl & ACB_DOMTRUST) || (acct_ctrl & ACB_WSTRUST) || (acct_ctrl & ACB_SVRTRUST)) && ((pass=pdb_get_nt_passwd(sampass)) != NULL)) { memcpy(md4pw, pass, 16); dump_data(5, md4pw, 16); pdb_free_sam(&sampass); return True; } DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct)); pdb_free_sam(&sampass); return False;}/************************************************************************* _net_req_chal *************************************************************************/NTSTATUS _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u){ if (!p->dc) { p->dc = TALLOC_ZERO_P(p->pipe_state_mem_ctx, struct dcinfo); if (!p->dc) { return NT_STATUS_NO_MEMORY; } } else { DEBUG(10,("_net_req_chal: new challenge requested. Clearing old state.\n")); ZERO_STRUCTP(p->dc); } rpcstr_pull(p->dc->remote_machine, q_u->uni_logon_clnt.buffer, sizeof(fstring),q_u->uni_logon_clnt.uni_str_len*2,0); /* Save the client challenge to the server. */ memcpy(p->dc->clnt_chal.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data)); /* Create a server challenge for the client */ /* Set this to a random value. */ generate_random_buffer(p->dc->srv_chal.data, 8); /* set up the LSA REQUEST CHALLENGE response */ init_net_r_req_chal(r_u, &p->dc->srv_chal, NT_STATUS_OK); p->dc->challenge_sent = True; return NT_STATUS_OK;}/************************************************************************* init_net_r_auth: *************************************************************************/static void init_net_r_auth(NET_R_AUTH *r_a, DOM_CHAL *resp_cred, NTSTATUS status){ memcpy(r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data)); r_a->status = status;}/************************************************************************* _net_auth. Create the initial credentials. *************************************************************************/NTSTATUS _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u){ fstring mach_acct; fstring remote_machine; DOM_CHAL srv_chal_out; if (!p->dc || !p->dc->challenge_sent) { return NT_STATUS_ACCESS_DENIED; } rpcstr_pull(mach_acct, q_u->clnt_id.uni_acct_name.buffer,sizeof(fstring), q_u->clnt_id.uni_acct_name.uni_str_len*2,0); rpcstr_pull(remote_machine, q_u->clnt_id.uni_comp_name.buffer,sizeof(fstring), q_u->clnt_id.uni_comp_name.uni_str_len*2,0); if (!get_md4pw((char *)p->dc->mach_pw, mach_acct)) { DEBUG(0,("_net_auth: creds_server_check failed. Failed to " "get pasword for machine account %s " "from client %s\n", mach_acct, remote_machine )); return NT_STATUS_ACCESS_DENIED; } /* From the client / server challenges and md4 password, generate sess key */ creds_server_init(p->dc, &p->dc->clnt_chal, /* Stored client chal. */ &p->dc->srv_chal, /* Stored server chal. */ (const char *)p->dc->mach_pw, &srv_chal_out); /* Check client credentials are valid. */ if (!creds_server_check(p->dc, &q_u->clnt_chal)) { DEBUG(0,("_net_auth: creds_server_check failed. Rejecting auth " "request from client %s machine account %s\n", remote_machine, mach_acct )); return NT_STATUS_ACCESS_DENIED; } fstrcpy(p->dc->mach_acct, mach_acct); fstrcpy(p->dc->remote_machine, remote_machine); p->dc->authenticated = True; /* set up the LSA AUTH response */ /* Return the server credentials. */ init_net_r_auth(r_u, &srv_chal_out, NT_STATUS_OK); return r_u->status;}/************************************************************************* init_net_r_auth_2: *************************************************************************/static void init_net_r_auth_2(NET_R_AUTH_2 *r_a, DOM_CHAL *resp_cred, NEG_FLAGS *flgs, NTSTATUS status){ memcpy(r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data)); memcpy(&r_a->srv_flgs, flgs, sizeof(r_a->srv_flgs)); r_a->status = status;}/************************************************************************* _net_auth_2 *************************************************************************/NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u){ NEG_FLAGS srv_flgs; fstring mach_acct; fstring remote_machine; DOM_CHAL srv_chal_out; rpcstr_pull(mach_acct, q_u->clnt_id.uni_acct_name.buffer,sizeof(fstring), q_u->clnt_id.uni_acct_name.uni_str_len*2,0); rpcstr_pull(remote_machine, q_u->clnt_id.uni_comp_name.buffer,sizeof(fstring), q_u->clnt_id.uni_comp_name.uni_str_len*2,0); if (!p->dc || !p->dc->challenge_sent) { DEBUG(0,("_net_auth2: no challenge sent to client %s\n", remote_machine )); return NT_STATUS_ACCESS_DENIED; } if ( (lp_server_schannel() == True) && ((q_u->clnt_flgs.neg_flags & NETLOGON_NEG_SCHANNEL) == 0) ) { /* schannel must be used, but client did not offer it. */ DEBUG(0,("_net_auth2: schannel required but client failed " "to offer it. Client was %s\n", mach_acct )); return NT_STATUS_ACCESS_DENIED; } if (!get_md4pw((char *)p->dc->mach_pw, mach_acct)) { DEBUG(0,("_net_auth2: failed to get machine password for " "account %s\n", mach_acct )); return NT_STATUS_ACCESS_DENIED; } /* From the client / server challenges and md4 password, generate sess key */ creds_server_init(p->dc, &p->dc->clnt_chal, /* Stored client chal. */ &p->dc->srv_chal, /* Stored server chal. */ (const char *)p->dc->mach_pw, &srv_chal_out); /* Check client credentials are valid. */ if (!creds_server_check(p->dc, &q_u->clnt_chal)) { DEBUG(0,("_net_auth2: creds_server_check failed. Rejecting auth " "request from client %s machine account %s\n", remote_machine, mach_acct )); return NT_STATUS_ACCESS_DENIED; } srv_flgs.neg_flags = 0x000001ff; if (lp_server_schannel() != False) { srv_flgs.neg_flags |= NETLOGON_NEG_SCHANNEL; } /* set up the LSA AUTH 2 response */ init_net_r_auth_2(r_u, &srv_chal_out, &srv_flgs, NT_STATUS_OK); fstrcpy(p->dc->mach_acct, mach_acct); fstrcpy(p->dc->remote_machine, remote_machine); fstrcpy(p->dc->domain, lp_workgroup() ); p->dc->authenticated = True; /* Store off the state so we can continue after client disconnect. */ become_root(); secrets_store_schannel_session_info(p->mem_ctx, p->dc); unbecome_root(); return r_u->status;}/************************************************************************* _net_srv_pwset *************************************************************************/NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_u){ NTSTATUS status = NT_STATUS_ACCESS_DENIED; fstring workstation; SAM_ACCOUNT *sampass=NULL; BOOL ret = False; unsigned char pwd[16]; int i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -