2008-02-17 04:10:43 +03:00
/*
2002-08-17 20:05:44 +04:00
Unix SMB / CIFS implementation .
NT Domain Authentication SMB / MSRPC client
Copyright ( C ) Andrew Tridgell 1992 - 2000
Copyright ( C ) Jeremy Allison 1998.
2005-09-30 21:13:37 +04:00
Largely re - written by Jeremy Allison ( C ) 2005.
2008-02-27 21:38:48 +03:00
Copyright ( C ) Guenther Deschner 2008.
2005-09-30 21:13:37 +04:00
2002-08-17 20:05:44 +04:00
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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2002-08-17 20:05:44 +04:00
( at your option ) any later version .
2008-02-17 04:10:43 +03:00
2002-08-17 20:05:44 +04:00
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 .
2008-02-17 04:10:43 +03:00
2002-08-17 20:05:44 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2002-08-17 20:05:44 +04:00
*/
1998-03-12 00:11:04 +03:00
# include "includes.h"
2014-01-17 17:07:37 +04:00
# include "system/filesys.h"
2013-08-07 13:27:25 +04:00
# include "libsmb/libsmb.h"
2011-04-13 16:32:16 +04:00
# include "rpc_client/rpc_client.h"
2013-08-07 13:27:25 +04:00
# include "rpc_client/cli_pipe.h"
2009-03-16 13:27:58 +03:00
# include "../libcli/auth/libcli_auth.h"
2013-07-27 13:30:13 +04:00
# include "../libcli/auth/netlogon_creds_cli.h"
2011-01-12 13:36:06 +03:00
# include "../librpc/gen_ndr/ndr_netlogon_c.h"
2013-08-07 13:27:25 +04:00
# include "../librpc/gen_ndr/schannel.h"
2010-05-18 20:26:03 +04:00
# include "rpc_client/cli_netlogon.h"
2010-05-28 03:19:25 +04:00
# include "rpc_client/init_netlogon.h"
2011-01-07 19:28:29 +03:00
# include "rpc_client/util_netlogon.h"
# include "../libcli/security/security.h"
2013-07-27 13:30:13 +04:00
# include "lib/param/param.h"
2013-08-07 13:27:25 +04:00
# include "libcli/smb/smbXcli_base.h"
2014-01-17 17:07:37 +04:00
# include "dbwrap/dbwrap.h"
# include "dbwrap/dbwrap_open.h"
# include "util_tdb.h"
1998-03-12 00:11:04 +03:00
2002-08-17 20:05:44 +04:00
2013-12-17 23:05:56 +04:00
NTSTATUS rpccli_pre_open_netlogon_creds ( void )
{
2014-01-17 17:07:37 +04:00
static bool already_open = false ;
TALLOC_CTX * frame ;
2013-12-17 23:05:56 +04:00
struct loadparm_context * lp_ctx ;
2014-01-17 17:07:37 +04:00
char * fname ;
struct db_context * global_db ;
2013-12-17 23:05:56 +04:00
NTSTATUS status ;
2014-01-17 17:07:37 +04:00
if ( already_open ) {
return NT_STATUS_OK ;
}
frame = talloc_stackframe ( ) ;
2013-12-17 23:05:56 +04:00
lp_ctx = loadparm_init_s3 ( frame , loadparm_s3_helpers ( ) ) ;
if ( lp_ctx = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
2014-01-17 17:07:37 +04:00
fname = lpcfg_private_db_path ( frame , lp_ctx , " netlogon_creds_cli " ) ;
if ( fname = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
2017-07-24 22:58:29 +03:00
global_db = db_open ( frame , fname ,
2014-01-17 17:07:37 +04:00
0 , TDB_CLEAR_IF_FIRST | TDB_INCOMPATIBLE_HASH ,
2014-01-27 17:49:12 +04:00
O_RDWR | O_CREAT , 0600 , DBWRAP_LOCK_ORDER_2 ,
2014-01-27 19:21:14 +04:00
DBWRAP_FLAG_OPTIMIZE_READONLY_ACCESS ) ;
2014-01-17 17:07:37 +04:00
if ( global_db = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
status = netlogon_creds_cli_set_global_db ( & global_db ) ;
2013-12-17 23:05:56 +04:00
TALLOC_FREE ( frame ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2014-01-17 17:07:37 +04:00
already_open = true ;
2013-12-17 23:05:56 +04:00
return NT_STATUS_OK ;
}
2017-09-06 15:14:28 +03:00
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 )
2013-08-07 13:27:25 +04:00
{
TALLOC_CTX * frame = talloc_stackframe ( ) ;
struct loadparm_context * lp_ctx ;
NTSTATUS status ;
2014-01-17 17:07:37 +04:00
status = rpccli_pre_open_netlogon_creds ( ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
TALLOC_FREE ( frame ) ;
return status ;
}
2013-08-07 13:27:25 +04:00
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 ,
2017-09-06 14:48:18 +03:00
server_dns_domain ,
2013-08-07 13:27:25 +04:00
mem_ctx , netlogon_creds ) ;
TALLOC_FREE ( frame ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
return NT_STATUS_OK ;
}
2017-09-06 18:23:47 +03:00
NTSTATUS rpccli_create_netlogon_creds_ctx (
struct cli_credentials * creds ,
const char * server_computer ,
struct messaging_context * msg_ctx ,
TALLOC_CTX * mem_ctx ,
2017-09-05 17:17:58 +03:00
struct netlogon_creds_cli_context * * creds_ctx )
2014-12-17 11:40:49 +03:00
{
enum netr_SchannelType sec_chan_type ;
const char * server_netbios_domain ;
2017-09-06 14:48:18 +03:00
const char * server_dns_domain ;
2014-12-17 11:40:49 +03:00
const char * client_account ;
sec_chan_type = cli_credentials_get_secure_channel_type ( creds ) ;
client_account = cli_credentials_get_username ( creds ) ;
server_netbios_domain = cli_credentials_get_domain ( creds ) ;
2017-09-06 14:48:18 +03:00
server_dns_domain = cli_credentials_get_realm ( creds ) ;
2014-12-17 11:40:49 +03:00
return rpccli_create_netlogon_creds ( server_computer ,
server_netbios_domain ,
2017-09-06 14:48:18 +03:00
server_dns_domain ,
2014-12-17 11:40:49 +03:00
client_account ,
sec_chan_type ,
msg_ctx , mem_ctx ,
2017-09-05 17:17:58 +03:00
creds_ctx ) ;
2014-12-17 11:40:49 +03:00
}
2017-09-17 17:31:28 +03:00
NTSTATUS rpccli_setup_netlogon_creds_locked (
2017-09-06 15:21:36 +03:00
struct cli_state * cli ,
enum dcerpc_transport_t transport ,
2017-09-05 17:17:58 +03:00
struct netlogon_creds_cli_context * creds_ctx ,
2017-09-06 15:21:36 +03:00
bool force_reauth ,
2017-09-18 23:17:01 +03:00
struct cli_credentials * cli_creds ,
uint32_t * negotiate_flags )
2013-08-07 13:27:25 +04:00
{
TALLOC_CTX * frame = talloc_stackframe ( ) ;
struct rpc_pipe_client * netlogon_pipe = NULL ;
struct netlogon_creds_CredentialState * creds = NULL ;
2017-05-22 21:44:40 +03:00
uint8_t num_nt_hashes = 0 ;
const struct samr_Password * nt_hashes [ 2 ] = { NULL , NULL } ;
uint8_t idx_nt_hashes = 0 ;
2013-08-07 13:27:25 +04:00
NTSTATUS status ;
2017-09-05 17:17:58 +03:00
status = netlogon_creds_cli_get ( creds_ctx , frame , & creds ) ;
2013-08-07 13:27:25 +04:00
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 ) {
2017-09-18 23:17:01 +03:00
goto done ;
2013-08-07 13:27:25 +04:00
}
TALLOC_FREE ( creds ) ;
}
2017-09-06 18:31:38 +03:00
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 ;
}
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 ;
}
2014-09-05 08:59:00 +04:00
status = cli_rpc_pipe_open_noauth_transport ( cli ,
transport ,
& ndr_table_netlogon ,
& netlogon_pipe ) ;
2013-08-07 13:27:25 +04:00
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 ) ;
2017-09-05 17:17:58 +03:00
status = netlogon_creds_cli_auth ( creds_ctx ,
2013-08-07 13:27:25 +04:00
netlogon_pipe - > binding_handle ,
2017-05-22 21:44:40 +03:00
num_nt_hashes ,
nt_hashes ,
& idx_nt_hashes ) ;
2013-08-07 13:27:25 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
TALLOC_FREE ( frame ) ;
return status ;
}
2017-09-05 17:17:58 +03:00
status = netlogon_creds_cli_get ( creds_ctx , frame , & creds ) ;
2013-08-07 13:27:25 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_INTERNAL_ERROR ;
}
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 ) ) ) ;
2017-09-18 23:17:01 +03:00
done :
if ( negotiate_flags ! = NULL ) {
* negotiate_flags = creds - > negotiate_flags ;
}
2013-08-07 13:27:25 +04:00
TALLOC_FREE ( frame ) ;
return NT_STATUS_OK ;
}
2017-09-17 17:31:28 +03:00
NTSTATUS rpccli_setup_netlogon_creds (
struct cli_state * cli ,
enum dcerpc_transport_t transport ,
struct netlogon_creds_cli_context * creds_ctx ,
bool force_reauth ,
struct cli_credentials * cli_creds )
{
TALLOC_CTX * frame = talloc_stackframe ( ) ;
struct netlogon_creds_cli_lck * lck ;
NTSTATUS status ;
status = netlogon_creds_cli_lck (
creds_ctx , NETLOGON_CREDS_CLI_LCK_EXCLUSIVE ,
frame , & lck ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DBG_WARNING ( " netlogon_creds_cli_lck failed: %s \n " ,
nt_errstr ( status ) ) ;
TALLOC_FREE ( frame ) ;
return status ;
}
status = rpccli_setup_netlogon_creds_locked (
2017-09-18 23:17:01 +03:00
cli , transport , creds_ctx , force_reauth , cli_creds , NULL ) ;
2017-09-17 17:31:28 +03:00
TALLOC_FREE ( frame ) ;
return status ;
}
2017-09-18 23:26:03 +03:00
NTSTATUS rpccli_connect_netlogon (
struct cli_state * cli ,
enum dcerpc_transport_t transport ,
struct netlogon_creds_cli_context * creds_ctx ,
bool force_reauth ,
struct cli_credentials * trust_creds ,
struct rpc_pipe_client * * _rpccli )
{
TALLOC_CTX * frame = talloc_stackframe ( ) ;
struct netlogon_creds_CredentialState * creds = NULL ;
enum netlogon_creds_cli_lck_type lck_type ;
enum netr_SchannelType sec_chan_type ;
2017-11-26 21:04:19 +03:00
struct netlogon_creds_cli_lck * lck = NULL ;
2017-09-18 23:26:03 +03:00
uint32_t negotiate_flags ;
uint8_t found_session_key [ 16 ] = { 0 } ;
bool found_existing_creds = false ;
bool do_serverauth ;
struct rpc_pipe_client * rpccli ;
NTSTATUS status ;
2017-10-18 14:36:59 +03:00
bool retry = false ;
2017-09-18 23:26:03 +03:00
2017-11-26 21:04:19 +03:00
sec_chan_type = cli_credentials_get_secure_channel_type ( trust_creds ) ;
if ( sec_chan_type = = SEC_CHAN_NULL ) {
DBG_ERR ( " secure_channel_type gave SEC_CHAN_NULL \n " ) ;
status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO ;
goto fail ;
}
2017-09-18 23:26:03 +03:00
again :
/*
* See whether we can use existing netlogon_creds or
* whether we have to serverauthenticate .
*/
status = netlogon_creds_cli_get ( creds_ctx , frame , & creds ) ;
if ( NT_STATUS_IS_OK ( status ) ) {
int cmp = memcmp ( found_session_key ,
creds - > session_key ,
sizeof ( found_session_key ) ) ;
found_existing_creds = ( cmp ! = 0 ) ;
memcpy ( found_session_key ,
creds - > session_key ,
sizeof ( found_session_key ) ) ;
TALLOC_FREE ( creds ) ;
}
lck_type = ( force_reauth | | ! found_existing_creds ) ?
NETLOGON_CREDS_CLI_LCK_EXCLUSIVE :
NETLOGON_CREDS_CLI_LCK_SHARED ;
status = netlogon_creds_cli_lck ( creds_ctx , lck_type , frame , & lck ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DBG_DEBUG ( " netlogon_creds_cli_lck failed: %s \n " ,
nt_errstr ( status ) ) ;
goto fail ;
}
if ( ! found_existing_creds ) {
/*
* Try to find creds under the lock again . Someone
* else might have done it for us .
*/
status = netlogon_creds_cli_get ( creds_ctx , frame , & creds ) ;
if ( NT_STATUS_IS_OK ( status ) ) {
int cmp = memcmp ( found_session_key ,
creds - > session_key ,
sizeof ( found_session_key ) ) ;
found_existing_creds = ( cmp ! = 0 ) ;
memcpy ( found_session_key , creds - > session_key ,
sizeof ( found_session_key ) ) ;
TALLOC_FREE ( creds ) ;
}
}
do_serverauth = force_reauth | | ! found_existing_creds ;
if ( ! do_serverauth ) {
/*
* Do the quick schannel bind without a reauth
*/
status = cli_rpc_pipe_open_bind_schannel (
cli , & ndr_table_netlogon , transport , creds_ctx ,
& rpccli ) ;
2017-10-18 14:36:59 +03:00
if ( ! retry & & NT_STATUS_EQUAL ( status , NT_STATUS_NETWORK_ACCESS_DENIED ) ) {
2017-09-18 23:26:03 +03:00
DBG_DEBUG ( " Retrying with serverauthenticate \n " ) ;
TALLOC_FREE ( lck ) ;
2017-10-18 14:36:59 +03:00
retry = true ;
2017-09-18 23:26:03 +03:00
goto again ;
}
2017-10-18 14:36:59 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DBG_DEBUG ( " cli_rpc_pipe_open_bind_schannel "
" failed: %s \n " , nt_errstr ( status ) ) ;
goto fail ;
}
2017-09-18 23:26:03 +03:00
goto done ;
}
if ( cli_credentials_is_anonymous ( trust_creds ) ) {
DBG_WARNING ( " get_trust_credential for %s only gave anonymous, "
2017-10-18 14:26:07 +03:00
" unable to negotiate NETLOGON credentials \n " ,
2017-09-18 23:26:03 +03:00
netlogon_creds_cli_debug_string (
creds_ctx , frame ) ) ;
status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO ;
goto fail ;
}
status = rpccli_setup_netlogon_creds_locked (
cli , transport , creds_ctx , true , trust_creds ,
& negotiate_flags ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DBG_DEBUG ( " rpccli_setup_netlogon_creds failed for %s, "
" unable to setup NETLOGON credentials: %s \n " ,
netlogon_creds_cli_debug_string (
creds_ctx , frame ) ,
nt_errstr ( status ) ) ;
goto fail ;
}
if ( ! ( negotiate_flags & NETLOGON_NEG_AUTHENTICATED_RPC ) ) {
if ( lp_winbind_sealed_pipes ( ) | | lp_require_strong_key ( ) ) {
status = NT_STATUS_DOWNGRADE_DETECTED ;
DBG_WARNING ( " Unwilling to make connection to %s "
" without connection level security, "
" must set 'winbind sealed pipes = false' "
" and 'require strong key = false' "
" to proceed: %s \n " ,
netlogon_creds_cli_debug_string (
creds_ctx , frame ) ,
nt_errstr ( status ) ) ;
goto fail ;
}
status = cli_rpc_pipe_open_noauth_transport (
cli , transport , & ndr_table_netlogon , & rpccli ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DBG_DEBUG ( " cli_rpc_pipe_open_noauth_transport "
" failed: %s \n " , nt_errstr ( status ) ) ;
2017-10-18 14:36:59 +03:00
goto fail ;
2017-09-18 23:26:03 +03:00
}
goto done ;
}
status = cli_rpc_pipe_open_bind_schannel (
cli , & ndr_table_netlogon , transport , creds_ctx , & rpccli ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DBG_DEBUG ( " cli_rpc_pipe_open_bind_schannel "
" failed: %s \n " , nt_errstr ( status ) ) ;
goto fail ;
}
2017-09-20 02:45:27 +03:00
status = netlogon_creds_cli_check ( creds_ctx , rpccli - > binding_handle ,
NULL ) ;
2017-09-18 23:26:03 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DBG_WARNING ( " netlogon_creds_cli_check failed: %s \n " ,
nt_errstr ( status ) ) ;
goto fail ;
}
done :
* _rpccli = rpccli ;
status = NT_STATUS_OK ;
fail :
ZERO_STRUCT ( found_session_key ) ;
TALLOC_FREE ( lck ) ;
TALLOC_FREE ( frame ) ;
return status ;
}
2002-08-17 20:05:44 +04:00
/* Logon domain user */
2017-09-05 17:17:58 +03:00
NTSTATUS rpccli_netlogon_password_logon (
struct netlogon_creds_cli_context * creds_ctx ,
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 ,
2017-12-01 01:35:40 +03:00
uint16_t * _validation_level ,
union netr_Validation * * _validation )
2013-08-27 16:56:06 +04:00
{
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 = = NULL ) {
workstation = lp_netbios_name ( ) ;
}
workstation_slash = talloc_asprintf ( frame , " \\ \\ %s " , workstation ) ;
if ( workstation_slash = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
/* Initialise input parameters */
switch ( logon_type ) {
2018-01-15 13:58:31 +03:00
case NetlogonInteractiveInformation :
case NetlogonInteractiveTransitiveInformation : {
2013-08-27 16:56:06 +04:00
struct netr_PasswordInfo * password_info ;
struct samr_Password lmpassword ;
struct samr_Password ntpassword ;
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 , 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 ;
}
2018-01-15 13:58:31 +03:00
case NetlogonNetworkInformation :
case NetlogonNetworkTransitiveInformation : {
2013-08-27 16:56:06 +04:00
struct netr_NetworkInfo * network_info ;
2015-05-09 19:49:04 +03:00
uint8_t chal [ 8 ] ;
2013-08-27 16:56:06 +04:00
unsigned char local_lm_response [ 24 ] ;
unsigned char local_nt_response [ 24 ] ;
struct netr_ChallengeResponse lm ;
struct netr_ChallengeResponse nt ;
ZERO_STRUCT ( lm ) ;
ZERO_STRUCT ( nt ) ;
network_info = talloc_zero ( frame , struct netr_NetworkInfo ) ;
if ( network_info = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
generate_random_buffer ( chal , 8 ) ;
SMBencrypt ( password , chal , local_lm_response ) ;
SMBNTencrypt ( password , chal , local_nt_response ) ;
lm . length = 24 ;
lm . data = local_lm_response ;
nt . length = 24 ;
nt . data = local_nt_response ;
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 ;
break ;
}
default :
DEBUG ( 0 , ( " switch value %d not supported \n " ,
logon_type ) ) ;
TALLOC_FREE ( frame ) ;
return NT_STATUS_INVALID_INFO_CLASS ;
}
2017-09-05 17:17:58 +03:00
status = netlogon_creds_cli_LogonSamLogon ( creds_ctx ,
2013-08-27 16:56:06 +04:00
binding_handle ,
logon_type ,
logon ,
2017-12-01 01:35:40 +03:00
mem_ctx ,
2013-08-27 16:56:06 +04:00
& validation_level ,
& validation ,
2017-01-28 14:36:11 +03:00
authoritative ,
flags ) ;
2013-08-27 16:56:06 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2014-07-15 10:28:42 +04:00
TALLOC_FREE ( frame ) ;
2013-08-27 16:56:06 +04:00
return status ;
}
2014-07-15 10:28:42 +04:00
TALLOC_FREE ( frame ) ;
2017-12-01 01:35:40 +03:00
* _validation_level = validation_level ;
* _validation = validation ;
2011-01-07 19:28:29 +03:00
return NT_STATUS_OK ;
}
2001-02-24 03:42:41 +03:00
2008-02-17 04:10:43 +03:00
/**
* Logon domain user with an ' network ' SAM logon
2002-08-17 20:05:44 +04:00
*
* @ param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller .
* */
2017-09-05 17:17:58 +03:00
NTSTATUS rpccli_netlogon_network_logon (
struct netlogon_creds_cli_context * creds_ctx ,
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 ,
2018-01-15 14:00:19 +03:00
enum netr_LogonInfoClass logon_type ,
2017-09-05 17:17:58 +03:00
uint8_t * authoritative ,
uint32_t * flags ,
2017-12-01 01:35:40 +03:00
uint16_t * _validation_level ,
union netr_Validation * * _validation )
2013-08-27 16:36:24 +04:00
{
NTSTATUS status ;
const char * workstation_name_slash ;
union netr_LogonLevel * logon = NULL ;
struct netr_NetworkInfo * network_info ;
uint16_t validation_level = 0 ;
union netr_Validation * validation = NULL ;
struct netr_ChallengeResponse lm ;
struct netr_ChallengeResponse nt ;
2017-12-01 01:35:40 +03:00
* _validation = NULL ;
2013-08-27 16:36:24 +04:00
ZERO_STRUCT ( lm ) ;
ZERO_STRUCT ( nt ) ;
2018-01-15 14:00:19 +03:00
switch ( logon_type ) {
case NetlogonNetworkInformation :
case NetlogonNetworkTransitiveInformation :
break ;
default :
DEBUG ( 0 , ( " switch value %d not supported \n " ,
logon_type ) ) ;
return NT_STATUS_INVALID_INFO_CLASS ;
}
2013-08-27 16:36:24 +04:00
logon = talloc_zero ( mem_ctx , union netr_LogonLevel ) ;
if ( ! logon ) {
return NT_STATUS_NO_MEMORY ;
}
network_info = talloc_zero ( mem_ctx , struct netr_NetworkInfo ) ;
if ( ! network_info ) {
return NT_STATUS_NO_MEMORY ;
}
if ( workstation [ 0 ] ! = ' \\ ' & & workstation [ 1 ] ! = ' \\ ' ) {
workstation_name_slash = talloc_asprintf ( mem_ctx , " \\ \\ %s " , workstation ) ;
} else {
workstation_name_slash = workstation ;
}
if ( ! workstation_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 ;
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 ;
memcpy ( network_info - > challenge , chal , 8 ) ;
network_info - > nt = nt ;
network_info - > lm = lm ;
logon - > network = network_info ;
/* Marshall data and send request */
2017-09-05 17:17:58 +03:00
status = netlogon_creds_cli_LogonSamLogon ( creds_ctx ,
2013-08-27 16:36:24 +04:00
binding_handle ,
2018-01-15 14:00:19 +03:00
logon_type ,
2013-08-27 16:36:24 +04:00
logon ,
mem_ctx ,
& validation_level ,
& validation ,
authoritative ,
flags ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2017-12-01 01:35:40 +03:00
* _validation_level = validation_level ;
* _validation = validation ;
2013-08-27 16:36:24 +04:00
return NT_STATUS_OK ;
}
2018-02-09 18:15:18 +03:00
NTSTATUS rpccli_netlogon_interactive_logon (
struct netlogon_creds_cli_context * creds_ctx ,
struct dcerpc_binding_handle * binding_handle ,
TALLOC_CTX * mem_ctx ,
uint32_t logon_parameters ,
const char * username ,
const char * domain ,
const char * workstation ,
DATA_BLOB lm_hash ,
DATA_BLOB nt_hash ,
enum netr_LogonInfoClass logon_type ,
uint8_t * authoritative ,
uint32_t * flags ,
uint16_t * _validation_level ,
union netr_Validation * * _validation )
{
TALLOC_CTX * frame = talloc_stackframe ( ) ;
NTSTATUS status ;
const char * workstation_name_slash ;
union netr_LogonLevel * logon = NULL ;
struct netr_PasswordInfo * password_info = NULL ;
uint16_t validation_level = 0 ;
union netr_Validation * validation = NULL ;
struct netr_ChallengeResponse lm ;
struct netr_ChallengeResponse nt ;
* _validation = NULL ;
ZERO_STRUCT ( lm ) ;
ZERO_STRUCT ( nt ) ;
switch ( logon_type ) {
case NetlogonInteractiveInformation :
case NetlogonInteractiveTransitiveInformation :
break ;
default :
DEBUG ( 0 , ( " switch value %d not supported \n " ,
logon_type ) ) ;
TALLOC_FREE ( frame ) ;
return NT_STATUS_INVALID_INFO_CLASS ;
}
logon = talloc_zero ( mem_ctx , union netr_LogonLevel ) ;
if ( logon = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
password_info = talloc_zero ( logon , struct netr_PasswordInfo ) ;
if ( password_info = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
if ( workstation [ 0 ] ! = ' \\ ' & & workstation [ 1 ] ! = ' \\ ' ) {
workstation_name_slash = talloc_asprintf ( frame , " \\ \\ %s " , workstation ) ;
} else {
workstation_name_slash = workstation ;
}
if ( workstation_name_slash = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
/* Initialise input parameters */
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_name_slash ;
if ( nt_hash . length ! = sizeof ( password_info - > ntpassword . hash ) ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
memcpy ( password_info - > ntpassword . hash , nt_hash . data , nt_hash . length ) ;
if ( lm_hash . length ! = 0 ) {
if ( lm_hash . length ! = sizeof ( password_info - > lmpassword . hash ) ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
memcpy ( password_info - > lmpassword . hash , lm_hash . data , lm_hash . length ) ;
}
logon - > password = password_info ;
/* Marshall data and send request */
status = netlogon_creds_cli_LogonSamLogon ( creds_ctx ,
binding_handle ,
logon_type ,
logon ,
mem_ctx ,
& validation_level ,
& validation ,
authoritative ,
flags ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
TALLOC_FREE ( frame ) ;
return status ;
}
* _validation_level = validation_level ;
* _validation = validation ;
TALLOC_FREE ( frame ) ;
return NT_STATUS_OK ;
}