X-Git-Url: http://git.samba.org/?p=samba.git;a=blobdiff_plain;f=source3%2Frpc_client%2Fcli_netlogon.c;h=2c3e205e2f4dbb39777acfb3487552118f6f4aca;hp=8b905e95fac12397c77bb7d06472785662c5df3a;hb=b62bba83ba8544adfc3700e927247ec942735538;hpb=d460ead4680780acb5fded5b33124711de23e536 diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index 8b905e95fac..2c3e205e2f4 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -21,310 +21,350 @@ */ #include "includes.h" +#include "system/filesys.h" +#include "libsmb/libsmb.h" +#include "rpc_client/rpc_client.h" +#include "rpc_client/cli_pipe.h" +#include "../libcli/auth/libcli_auth.h" +#include "../libcli/auth/netlogon_creds_cli.h" +#include "../librpc/gen_ndr/ndr_netlogon_c.h" +#include "../librpc/gen_ndr/schannel.h" +#include "rpc_client/cli_netlogon.h" +#include "rpc_client/init_netlogon.h" +#include "rpc_client/util_netlogon.h" +#include "../libcli/security/security.h" +#include "lib/param/param.h" +#include "libcli/smb/smbXcli_base.h" +#include "dbwrap/dbwrap.h" +#include "dbwrap/dbwrap_open.h" +#include "util_tdb.h" + + +NTSTATUS rpccli_pre_open_netlogon_creds(void) +{ + static bool already_open = false; + TALLOC_CTX *frame; + struct loadparm_context *lp_ctx; + char *fname; + struct db_context *global_db; + NTSTATUS status; + + if (already_open) { + return NT_STATUS_OK; + } -/* LSA Request Challenge. Sends our challenge to server, then gets - server response. These are used to generate the credentials. - The sent and received challenges are stored in the netlog pipe - private data. Only call this via rpccli_netlogon_setup_creds(). JRA. -*/ + frame = talloc_stackframe(); -/* instead of rpccli_net_req_chal() we use rpccli_netr_ServerReqChallenge() now - gd */ + lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers()); + if (lp_ctx == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } -#if 0 -/**************************************************************************** -LSA Authenticate 2 + fname = lpcfg_private_db_path(frame, lp_ctx, "netlogon_creds_cli"); + if (fname == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } -Send the client credential, receive back a server credential. -Ensure that the server credential returned matches the session key -encrypt of the server challenge originally received. JRA. -****************************************************************************/ + global_db = db_open(frame, fname, + 0, TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, + O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_2, + DBWRAP_FLAG_OPTIMIZE_READONLY_ACCESS); + if (global_db == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } - NTSTATUS rpccli_net_auth2(struct rpc_pipe_client *cli, - uint16 sec_chan, - uint32 *neg_flags, DOM_CHAL *srv_chal) -{ - prs_struct qbuf, rbuf; - NET_Q_AUTH_2 q; - NET_R_AUTH_2 r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - fstring machine_acct; - - if ( sec_chan == SEC_CHAN_DOMAIN ) - fstr_sprintf( machine_acct, "%s$", lp_workgroup() ); - else - fstrcpy( machine_acct, cli->mach_acct ); - - /* create and send a MSRPC command with api NET_AUTH2 */ - - DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", - cli->srv_name_slash, machine_acct, sec_chan, global_myname(), - credstr(cli->clnt_cred.challenge.data), *neg_flags)); - - /* store the parameters */ - - init_q_auth_2(&q, cli->srv_name_slash, machine_acct, - sec_chan, global_myname(), &cli->clnt_cred.challenge, - *neg_flags); - - /* turn parameters into data stream */ - - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_AUTH2, - q, r, - qbuf, rbuf, - net_io_q_auth_2, - net_io_r_auth_2, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - - if (NT_STATUS_IS_OK(result)) { - UTIME zerotime; - - /* - * Check the returned value using the initial - * server received challenge. - */ - - zerotime.time = 0; - if (cred_assert( &r.srv_chal, cli->sess_key, srv_chal, zerotime) == 0) { - - /* - * Server replied with bad credential. Fail. - */ - DEBUG(0,("cli_net_auth2: server %s replied with bad credential (bad machine \ -password ?).\n", cli->cli->desthost )); - return NT_STATUS_ACCESS_DENIED; - } - *neg_flags = r.srv_flgs.neg_flags; - } - - return result; + status = netlogon_creds_cli_set_global_db(&global_db); + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + already_open = true; + return NT_STATUS_OK; } -#endif -/**************************************************************************** - LSA Authenticate 2 +static NTSTATUS rpccli_create_netlogon_creds( + const char *server_computer, + const char *server_netbios_domain, + const char *server_dns_domain, + const char *client_account, + enum netr_SchannelType sec_chan_type, + struct messaging_context *msg_ctx, + TALLOC_CTX *mem_ctx, + struct netlogon_creds_cli_context **netlogon_creds) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct loadparm_context *lp_ctx; + NTSTATUS status; + + status = rpccli_pre_open_netlogon_creds(); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } - Send the client credential, receive back a server credential. - The caller *must* ensure that the server credential returned matches the session key - encrypt of the server challenge originally received. JRA. -****************************************************************************/ + lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers()); + if (lp_ctx == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + status = netlogon_creds_cli_context_global(lp_ctx, + msg_ctx, + client_account, + sec_chan_type, + server_computer, + server_netbios_domain, + server_dns_domain, + mem_ctx, netlogon_creds); + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + return status; + } -/* instead of rpccli_net_auth2() we use rpccli_netr_ServerAuthenticate2() now - gd */ + return NT_STATUS_OK; +} +NTSTATUS rpccli_create_netlogon_creds_ctx( + struct cli_credentials *creds, + const char *server_computer, + struct messaging_context *msg_ctx, + TALLOC_CTX *mem_ctx, + struct netlogon_creds_cli_context **netlogon_creds) +{ + enum netr_SchannelType sec_chan_type; + const char *server_netbios_domain; + const char *server_dns_domain; + const char *client_account; + + sec_chan_type = cli_credentials_get_secure_channel_type(creds); + if (sec_chan_type == SEC_CHAN_NULL) { + return NT_STATUS_INVALID_PARAMETER_MIX; + } -/**************************************************************************** - Wrapper function that uses the auth and auth2 calls to set up a NETLOGON - credentials chain. Stores the credentials in the struct dcinfo in the - netlogon pipe struct. -****************************************************************************/ + client_account = cli_credentials_get_username(creds); + server_netbios_domain = cli_credentials_get_domain(creds); + server_dns_domain = cli_credentials_get_realm(creds); + + return rpccli_create_netlogon_creds(server_computer, + server_netbios_domain, + server_dns_domain, + client_account, + sec_chan_type, + msg_ctx, mem_ctx, + netlogon_creds); +} -NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli, - const char *server_name, - const char *domain, - const char *clnt_name, - const char *machine_account, - const unsigned char machine_pwd[16], - enum netr_SchannelType sec_chan_type, - uint32_t *neg_flags_inout) +NTSTATUS rpccli_setup_netlogon_creds( + struct cli_state *cli, + enum dcerpc_transport_t transport, + struct netlogon_creds_cli_context *netlogon_creds, + bool force_reauth, + struct cli_credentials *cli_creds) { - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - struct netr_Credential clnt_chal_send; - struct netr_Credential srv_chal_recv; - struct dcinfo *dc; - bool retried = false; - - SMB_ASSERT(ndr_syntax_id_equal(&cli->abstract_syntax, - &ndr_table_netlogon.syntax_id)); - - TALLOC_FREE(cli->dc); - cli->dc = talloc_zero(cli, struct dcinfo); - if (cli->dc == NULL) { + TALLOC_CTX *frame = talloc_stackframe(); + struct rpc_pipe_client *netlogon_pipe = NULL; + struct netlogon_creds_CredentialState *creds = NULL; + uint8_t num_nt_hashes = 0; + const struct samr_Password *nt_hashes[2] = { NULL, NULL }; + uint8_t idx_nt_hashes = 0; + NTSTATUS status; + + status = netlogon_creds_cli_get(netlogon_creds, + frame, &creds); + if (NT_STATUS_IS_OK(status)) { + const char *action = "using"; + + if (force_reauth) { + action = "overwrite"; + } + + DEBUG(5,("%s: %s cached netlogon_creds cli[%s/%s] to %s\n", + __FUNCTION__, action, + creds->account_name, creds->computer_name, + smbXcli_conn_remote_name(cli->conn))); + if (!force_reauth) { + TALLOC_FREE(frame); + return NT_STATUS_OK; + } + TALLOC_FREE(creds); + } + + nt_hashes[0] = cli_credentials_get_nt_hash(cli_creds, talloc_tos()); + if (nt_hashes[0] == NULL) { + TALLOC_FREE(frame); return NT_STATUS_NO_MEMORY; } - dc = cli->dc; + num_nt_hashes = 1; + + nt_hashes[1] = cli_credentials_get_old_nt_hash(cli_creds, + talloc_tos()); + if (nt_hashes[1] != NULL) { + num_nt_hashes = 2; + } - /* Store the machine account password we're going to use. */ - memcpy(dc->mach_pw, machine_pwd, 16); + status = cli_rpc_pipe_open_noauth_transport(cli, + transport, + &ndr_table_netlogon, + &netlogon_pipe); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(5,("%s: failed to open noauth netlogon connection to %s - %s\n", + __FUNCTION__, + smbXcli_conn_remote_name(cli->conn), + nt_errstr(status))); + TALLOC_FREE(frame); + return status; + } + talloc_steal(frame, netlogon_pipe); + + status = netlogon_creds_cli_auth(netlogon_creds, + netlogon_pipe->binding_handle, + num_nt_hashes, + nt_hashes, + &idx_nt_hashes); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } - fstrcpy(dc->remote_machine, "\\\\"); - fstrcat(dc->remote_machine, server_name); + status = netlogon_creds_cli_get(netlogon_creds, + frame, &creds); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return NT_STATUS_INTERNAL_ERROR; + } - fstrcpy(dc->domain, domain); + DEBUG(5,("%s: using new netlogon_creds cli[%s/%s] to %s\n", + __FUNCTION__, + creds->account_name, creds->computer_name, + smbXcli_conn_remote_name(cli->conn))); - fstr_sprintf( dc->mach_acct, "%s$", machine_account); + TALLOC_FREE(frame); + return NT_STATUS_OK; +} - again: - /* Create the client challenge. */ - generate_random_buffer(clnt_chal_send.data, 8); +static NTSTATUS map_validation_to_info3(TALLOC_CTX *mem_ctx, + uint16_t validation_level, + union netr_Validation *validation, + struct netr_SamInfo3 **info3_p) +{ + struct netr_SamInfo3 *info3; + NTSTATUS status; - /* Get the server challenge. */ - result = rpccli_netr_ServerReqChallenge(cli, talloc_tos(), - dc->remote_machine, - clnt_name, - &clnt_chal_send, - &srv_chal_recv); - if (!NT_STATUS_IS_OK(result)) { - return result; + if (validation == NULL) { + return NT_STATUS_INVALID_PARAMETER; } - /* Calculate the session key and client credentials */ - creds_client_init(*neg_flags_inout, - dc, - &clnt_chal_send, - &srv_chal_recv, - machine_pwd, - &clnt_chal_send); - - /* - * Send client auth-2 challenge and receive server repy. - */ - - result = rpccli_netr_ServerAuthenticate2(cli, talloc_tos(), - dc->remote_machine, - dc->mach_acct, - sec_chan_type, - clnt_name, - &clnt_chal_send, /* input. */ - &srv_chal_recv, /* output. */ - neg_flags_inout); - - /* we might be talking to NT4, so let's downgrade in that case and retry - * with the returned neg_flags - gd */ - - if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) && !retried) { - retried = true; - goto again; - } + switch (validation_level) { + case 3: + if (validation->sam3 == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } - if (!NT_STATUS_IS_OK(result)) { - return result; - } + info3 = talloc_move(mem_ctx, &validation->sam3); + break; + case 6: + if (validation->sam6 == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } - /* - * Check the returned value using the initial - * server received challenge. - */ - - if (!netlogon_creds_client_check(dc, &srv_chal_recv)) { - /* - * Server replied with bad credential. Fail. - */ - DEBUG(0,("rpccli_netlogon_setup_creds: server %s " - "replied with bad credential\n", - cli->desthost )); - return NT_STATUS_ACCESS_DENIED; + info3 = talloc_zero(mem_ctx, struct netr_SamInfo3); + if (info3 == NULL) { + return NT_STATUS_NO_MEMORY; + } + status = copy_netr_SamBaseInfo(info3, &validation->sam6->base, &info3->base); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(info3); + return status; + } + + info3->sidcount = validation->sam6->sidcount; + info3->sids = talloc_move(info3, &validation->sam6->sids); + break; + default: + return NT_STATUS_BAD_VALIDATION_CLASS; } - DEBUG(5,("rpccli_netlogon_setup_creds: server %s credential " - "chain established.\n", - cli->desthost )); + *info3_p = info3; return NT_STATUS_OK; } /* Logon domain user */ -NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - uint32 logon_parameters, - const char *domain, - const char *username, - const char *password, - const char *workstation, - int logon_type) +NTSTATUS rpccli_netlogon_password_logon(struct netlogon_creds_cli_context *creds, + struct dcerpc_binding_handle *binding_handle, + TALLOC_CTX *mem_ctx, + uint32_t logon_parameters, + const char *domain, + const char *username, + const char *password, + const char *workstation, + enum netr_LogonInfoClass logon_type, + uint8_t *authoritative, + uint32_t *flags, + struct netr_SamInfo3 **info3) { - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - struct netr_Authenticator clnt_creds; - struct netr_Authenticator ret_creds; - union netr_LogonInfo *logon; - union netr_Validation validation; - uint8_t authoritative; - int validation_level = 3; - fstring clnt_name_slash; - uint8 zeros[16]; - - ZERO_STRUCT(ret_creds); - ZERO_STRUCT(zeros); - - logon = TALLOC_ZERO_P(mem_ctx, union netr_LogonInfo); - if (!logon) { + TALLOC_CTX *frame = talloc_stackframe(); + NTSTATUS status; + union netr_LogonLevel *logon; + uint16_t validation_level = 0; + union netr_Validation *validation = NULL; + char *workstation_slash = NULL; + + logon = talloc_zero(frame, union netr_LogonLevel); + if (logon == NULL) { + TALLOC_FREE(frame); return NT_STATUS_NO_MEMORY; } - if (workstation) { - fstr_sprintf( clnt_name_slash, "\\\\%s", workstation ); - } else { - fstr_sprintf( clnt_name_slash, "\\\\%s", global_myname() ); + if (workstation == NULL) { + workstation = lp_netbios_name(); } - /* Initialise input parameters */ + workstation_slash = talloc_asprintf(frame, "\\\\%s", workstation); + if (workstation_slash == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } - netlogon_creds_client_step(cli->dc, &clnt_creds); + /* Initialise input parameters */ switch (logon_type) { - case INTERACTIVE_LOGON_TYPE: { + case NetlogonInteractiveInformation: { struct netr_PasswordInfo *password_info; struct samr_Password lmpassword; struct samr_Password ntpassword; - unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16]; - - unsigned char lm_owf[16]; - unsigned char nt_owf[16]; - unsigned char key[16]; - - password_info = TALLOC_ZERO_P(mem_ctx, struct netr_PasswordInfo); - if (!password_info) { + password_info = talloc_zero(frame, struct netr_PasswordInfo); + if (password_info == NULL) { + TALLOC_FREE(frame); return NT_STATUS_NO_MEMORY; } - nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("lm cypher:")); - dump_data(100, lm_owf_user_pwd, 16); - - DEBUG(100,("nt cypher:")); - dump_data(100, nt_owf_user_pwd, 16); -#endif - memset(key, 0, 16); - memcpy(key, cli->dc->sess_key, 8); - - memcpy(lm_owf, lm_owf_user_pwd, 16); - SamOEMhash(lm_owf, key, 16); - memcpy(nt_owf, nt_owf_user_pwd, 16); - SamOEMhash(nt_owf, key, 16); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("encrypt of lm owf password:")); - dump_data(100, lm_owf, 16); - - DEBUG(100,("encrypt of nt owf password:")); - dump_data(100, nt_owf, 16); -#endif - memcpy(lmpassword.hash, lm_owf, 16); - memcpy(ntpassword.hash, nt_owf, 16); - - init_netr_PasswordInfo(password_info, - domain, - logon_parameters, - 0xdead, - 0xbeef, - username, - clnt_name_slash, - lmpassword, - ntpassword); + nt_lm_owf_gen(password, ntpassword.hash, lmpassword.hash); + + password_info->identity_info.domain_name.string = domain; + password_info->identity_info.parameter_control = logon_parameters; + password_info->identity_info.logon_id_low = 0xdead; + password_info->identity_info.logon_id_high = 0xbeef; + password_info->identity_info.account_name.string = username; + password_info->identity_info.workstation.string = workstation_slash; + + password_info->lmpassword = lmpassword; + password_info->ntpassword = ntpassword; logon->password = password_info; break; } - case NET_LOGON_TYPE: { + case NetlogonNetworkInformation: { struct netr_NetworkInfo *network_info; - uint8 chal[8]; + uint8_t chal[8]; unsigned char local_lm_response[24]; unsigned char local_nt_response[24]; struct netr_ChallengeResponse lm; @@ -333,8 +373,9 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli, ZERO_STRUCT(lm); ZERO_STRUCT(nt); - network_info = TALLOC_ZERO_P(mem_ctx, struct netr_NetworkInfo); - if (!network_info) { + network_info = talloc_zero(frame, struct netr_NetworkInfo); + if (network_info == NULL) { + TALLOC_FREE(frame); return NT_STATUS_NO_MEMORY; } @@ -349,16 +390,16 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli, nt.length = 24; nt.data = local_nt_response; - init_netr_NetworkInfo(network_info, - domain, - logon_parameters, - 0xdead, - 0xbeef, - username, - clnt_name_slash, - chal, - nt, - lm); + network_info->identity_info.domain_name.string = domain; + network_info->identity_info.parameter_control = logon_parameters; + network_info->identity_info.logon_id_low = 0xdead; + network_info->identity_info.logon_id_high = 0xbeef; + network_info->identity_info.account_name.string = username; + network_info->identity_info.workstation.string = workstation_slash; + + memcpy(network_info->challenge, chal, 8); + network_info->nt = nt; + network_info->lm = lm; logon->network = network_info; @@ -367,31 +408,35 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli, default: DEBUG(0, ("switch value %d not supported\n", logon_type)); + TALLOC_FREE(frame); return NT_STATUS_INVALID_INFO_CLASS; } - result = rpccli_netr_LogonSamLogon(cli, mem_ctx, - cli->dc->remote_machine, - global_myname(), - &clnt_creds, - &ret_creds, - logon_type, - logon, - validation_level, - &validation, - &authoritative); - - if (memcmp(zeros, &ret_creds.cred.data, sizeof(ret_creds.cred.data)) != 0) { - /* Check returned credentials if present. */ - if (!netlogon_creds_client_check(cli->dc, &ret_creds.cred)) { - DEBUG(0,("rpccli_netlogon_sam_logon: credentials chain check failed\n")); - return NT_STATUS_ACCESS_DENIED; - } + status = netlogon_creds_cli_LogonSamLogon(creds, + binding_handle, + logon_type, + logon, + frame, + &validation_level, + &validation, + authoritative, + flags); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + + status = map_validation_to_info3(mem_ctx, + validation_level, validation, + info3); + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + return status; } - return result; -} + return NT_STATUS_OK; +} /** * Logon domain user with an 'network' SAM logon @@ -399,188 +444,52 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli, * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller. **/ -NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - uint32 logon_parameters, - const char *server, - const char *username, - const char *domain, - const char *workstation, - const uint8 chal[8], - DATA_BLOB lm_response, - DATA_BLOB nt_response, - struct netr_SamInfo3 **info3) -{ - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - int validation_level = 3; - const char *workstation_name_slash; - const char *server_name_slash; - uint8 zeros[16]; - struct netr_Authenticator clnt_creds; - struct netr_Authenticator ret_creds; - union netr_LogonInfo *logon = NULL; - struct netr_NetworkInfo *network_info; - uint8_t authoritative; - union netr_Validation validation; - struct netr_ChallengeResponse lm; - struct netr_ChallengeResponse nt; - struct netr_UserSessionKey user_session_key; - struct netr_LMSessionKey lmsesskey; - - *info3 = NULL; - - ZERO_STRUCT(zeros); - ZERO_STRUCT(ret_creds); - - ZERO_STRUCT(lm); - ZERO_STRUCT(nt); - - logon = TALLOC_ZERO_P(mem_ctx, union netr_LogonInfo); - if (!logon) { - return NT_STATUS_NO_MEMORY; - } - - network_info = TALLOC_ZERO_P(mem_ctx, struct netr_NetworkInfo); - if (!network_info) { - return NT_STATUS_NO_MEMORY; - } - - netlogon_creds_client_step(cli->dc, &clnt_creds); - - if (server[0] != '\\' && server[1] != '\\') { - server_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", server); - } else { - server_name_slash = server; - } - - if (workstation[0] != '\\' && workstation[1] != '\\') { - workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation); - } else { - workstation_name_slash = workstation; - } - - if (!workstation_name_slash || !server_name_slash) { - DEBUG(0, ("talloc_asprintf failed!\n")); - return NT_STATUS_NO_MEMORY; - } - - /* Initialise input parameters */ - - lm.data = lm_response.data; - lm.length = lm_response.length; - nt.data = nt_response.data; - nt.length = nt_response.length; - - init_netr_NetworkInfo(network_info, - domain, - logon_parameters, - 0xdead, - 0xbeef, - username, - workstation_name_slash, - (uint8_t *) chal, - nt, - lm); - - logon->network = network_info; - - /* Marshall data and send request */ - - result = rpccli_netr_LogonSamLogon(cli, mem_ctx, - server_name_slash, - global_myname(), - &clnt_creds, - &ret_creds, - NET_LOGON_TYPE, - logon, - validation_level, - &validation, - &authoritative); - if (!NT_STATUS_IS_OK(result)) { - return result; - } - - user_session_key = validation.sam3->base.key; - lmsesskey = validation.sam3->base.LMSessKey; - - if (memcmp(zeros, user_session_key.key, 16) != 0) { - SamOEMhash(user_session_key.key, cli->dc->sess_key, 16); - } - - if (memcmp(zeros, lmsesskey.key, 8) != 0) { - SamOEMhash(lmsesskey.key, cli->dc->sess_key, 8); - } - if (memcmp(zeros, ret_creds.cred.data, sizeof(ret_creds.cred.data)) != 0) { - /* Check returned credentials if present. */ - if (!netlogon_creds_client_check(cli->dc, &ret_creds.cred)) { - DEBUG(0,("rpccli_netlogon_sam_network_logon: credentials chain check failed\n")); - return NT_STATUS_ACCESS_DENIED; - } - } - - *info3 = validation.sam3; - - return result; -} - -NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - uint32 logon_parameters, - const char *server, - const char *username, - const char *domain, - const char *workstation, - const uint8 chal[8], - DATA_BLOB lm_response, - DATA_BLOB nt_response, - struct netr_SamInfo3 **info3) +NTSTATUS rpccli_netlogon_network_logon(struct netlogon_creds_cli_context *creds, + struct dcerpc_binding_handle *binding_handle, + TALLOC_CTX *mem_ctx, + uint32_t logon_parameters, + const char *username, + const char *domain, + const char *workstation, + const uint8_t chal[8], + DATA_BLOB lm_response, + DATA_BLOB nt_response, + uint8_t *authoritative, + uint32_t *flags, + struct netr_SamInfo3 **info3) { - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - int validation_level = 3; + NTSTATUS status; const char *workstation_name_slash; - const char *server_name_slash; - uint8 zeros[16]; - union netr_LogonInfo *logon = NULL; + union netr_LogonLevel *logon = NULL; struct netr_NetworkInfo *network_info; - uint8_t authoritative; - union netr_Validation validation; + uint16_t validation_level = 0; + union netr_Validation *validation = NULL; struct netr_ChallengeResponse lm; struct netr_ChallengeResponse nt; - struct netr_UserSessionKey user_session_key; - struct netr_LMSessionKey lmsesskey; - uint32_t flags = 0; *info3 = NULL; - ZERO_STRUCT(zeros); - ZERO_STRUCT(lm); ZERO_STRUCT(nt); - logon = TALLOC_ZERO_P(mem_ctx, union netr_LogonInfo); + logon = talloc_zero(mem_ctx, union netr_LogonLevel); if (!logon) { return NT_STATUS_NO_MEMORY; } - network_info = TALLOC_ZERO_P(mem_ctx, struct netr_NetworkInfo); + network_info = talloc_zero(mem_ctx, struct netr_NetworkInfo); if (!network_info) { return NT_STATUS_NO_MEMORY; } - if (server[0] != '\\' && server[1] != '\\') { - server_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", server); - } else { - server_name_slash = server; - } - if (workstation[0] != '\\' && workstation[1] != '\\') { workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation); } else { workstation_name_slash = workstation; } - if (!workstation_name_slash || !server_name_slash) { + if (!workstation_name_slash) { DEBUG(0, ("talloc_asprintf failed!\n")); return NT_STATUS_NO_MEMORY; } @@ -592,46 +501,40 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli, nt.data = nt_response.data; nt.length = nt_response.length; - init_netr_NetworkInfo(network_info, - domain, - logon_parameters, - 0xdead, - 0xbeef, - username, - workstation_name_slash, - (uint8_t *) chal, - nt, - lm); + network_info->identity_info.domain_name.string = domain; + network_info->identity_info.parameter_control = logon_parameters; + network_info->identity_info.logon_id_low = 0xdead; + network_info->identity_info.logon_id_high = 0xbeef; + network_info->identity_info.account_name.string = username; + network_info->identity_info.workstation.string = workstation_name_slash; - logon->network = network_info; + memcpy(network_info->challenge, chal, 8); + network_info->nt = nt; + network_info->lm = lm; - /* Marshall data and send request */ - - result = rpccli_netr_LogonSamLogonEx(cli, mem_ctx, - server_name_slash, - global_myname(), - NET_LOGON_TYPE, - logon, - validation_level, - &validation, - &authoritative, - &flags); - if (!NT_STATUS_IS_OK(result)) { - return result; - } + logon->network = network_info; - user_session_key = validation.sam3->base.key; - lmsesskey = validation.sam3->base.LMSessKey; + /* Marshall data and send request */ - if (memcmp(zeros, user_session_key.key, 16) != 0) { - SamOEMhash(user_session_key.key, cli->dc->sess_key, 16); + status = netlogon_creds_cli_LogonSamLogon(creds, + binding_handle, + NetlogonNetworkInformation, + logon, + mem_ctx, + &validation_level, + &validation, + authoritative, + flags); + if (!NT_STATUS_IS_OK(status)) { + return status; } - if (memcmp(zeros, lmsesskey.key, 8) != 0) { - SamOEMhash(lmsesskey.key, cli->dc->sess_key, 8); + status = map_validation_to_info3(mem_ctx, + validation_level, validation, + info3); + if (!NT_STATUS_IS_OK(status)) { + return status; } - *info3 = validation.sam3; - - return result; + return NT_STATUS_OK; }