2006-02-04 01:19:41 +03:00
/*
* Unix SMB / CIFS implementation .
* Helper routines for net
* Copyright ( C ) Volker Lendecke 2006
2008-09-25 01:23:01 +04:00
* Copyright ( C ) Kai Blin 2008
2006-02-04 01:19:41 +03: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
2006-02-04 01:19:41 +03:00
* ( 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
2007-07-10 09:23:25 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2006-02-04 01:19:41 +03:00
*/
# include "includes.h"
# include "utils/net.h"
2018-03-10 17:31:11 +03:00
# include "libsmb/namequery.h"
2011-02-28 12:19:44 +03:00
# include "rpc_client/cli_pipe.h"
2011-01-18 18:35:14 +03:00
# include "../librpc/gen_ndr/ndr_lsa_c.h"
2010-05-18 20:26:16 +04:00
# include "rpc_client/cli_lsarpc.h"
2011-01-11 15:35:08 +03:00
# include "../librpc/gen_ndr/ndr_dssetup_c.h"
2010-08-05 04:25:37 +04:00
# include "secrets.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2011-05-06 13:47:43 +04:00
# include "libsmb/libsmb.h"
2019-11-11 15:57:55 +03:00
# include "lib/param/param.h"
# include "auth/gensec/gensec.h"
2022-11-30 18:16:05 +03:00
# include "libcli/auth/netlogon_creds_cli.h"
2021-01-19 09:49:26 +03:00
# include "lib/cmdline/cmdline.h"
2006-02-04 01:19:41 +03:00
2008-05-10 01:22:12 +04:00
NTSTATUS net_rpc_lookup_name ( struct net_context * c ,
TALLOC_CTX * mem_ctx , struct cli_state * cli ,
2006-02-04 01:19:41 +03:00
const char * name , const char * * ret_domain ,
2010-05-21 05:25:01 +04:00
const char * * ret_name , struct dom_sid * ret_sid ,
2006-09-08 18:28:06 +04:00
enum lsa_SidType * ret_type )
2006-02-04 01:19:41 +03:00
{
2009-11-13 00:56:33 +03:00
struct rpc_pipe_client * lsa_pipe = NULL ;
2009-03-19 00:49:41 +03:00
struct policy_handle pol ;
2011-01-18 18:35:14 +03:00
NTSTATUS status , result ;
2006-02-04 01:19:41 +03:00
const char * * dom_names ;
2010-05-21 05:25:01 +04:00
struct dom_sid * sids ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType * types ;
2011-01-18 18:35:14 +03:00
struct dcerpc_binding_handle * b ;
2006-02-04 01:19:41 +03:00
ZERO_STRUCT ( pol ) ;
2013-05-24 15:29:28 +04:00
status = cli_rpc_pipe_open_noauth ( cli , & ndr_table_lsarpc ,
2008-07-20 13:04:31 +04:00
& lsa_pipe ) ;
2011-01-18 18:35:14 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-11 11:01:10 +04:00
d_fprintf ( stderr , _ ( " Could not initialise lsa pipe \n " ) ) ;
2011-01-18 18:35:14 +03:00
return status ;
2006-02-04 01:19:41 +03:00
}
2011-01-18 18:35:14 +03:00
b = lsa_pipe - > binding_handle ;
status = rpccli_lsa_open_policy ( lsa_pipe , mem_ctx , false ,
2009-04-15 03:12:13 +04:00
SEC_FLAG_MAXIMUM_ALLOWED ,
2006-02-04 01:19:41 +03:00
& pol ) ;
2011-01-18 18:35:14 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-01-19 13:43:54 +03:00
d_fprintf ( stderr , " open_policy %s: %s \n " , _ ( " failed " ) ,
2011-01-18 18:35:14 +03:00
nt_errstr ( status ) ) ;
return status ;
2006-02-04 01:19:41 +03:00
}
2011-01-18 18:35:14 +03:00
status = rpccli_lsa_lookup_names ( lsa_pipe , mem_ctx , & pol , 1 ,
2007-06-27 15:42:17 +04:00
& name , & dom_names , 1 , & sids , & types ) ;
2006-02-04 01:19:41 +03:00
2011-01-18 18:35:14 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2006-02-04 01:19:41 +03:00
/* This can happen easily, don't log an error */
goto done ;
}
if ( ret_domain ! = NULL ) {
* ret_domain = dom_names [ 0 ] ;
}
if ( ret_name ! = NULL ) {
* ret_name = talloc_strdup ( mem_ctx , name ) ;
}
if ( ret_sid ! = NULL ) {
sid_copy ( ret_sid , & sids [ 0 ] ) ;
}
if ( ret_type ! = NULL ) {
* ret_type = types [ 0 ] ;
}
done :
if ( is_valid_policy_hnd ( & pol ) ) {
2011-01-18 18:35:14 +03:00
dcerpc_lsa_Close ( b , mem_ctx , & pol , & result ) ;
2006-02-04 01:19:41 +03:00
}
2008-04-20 15:51:46 +04:00
TALLOC_FREE ( lsa_pipe ) ;
2006-02-04 01:19:41 +03:00
2011-01-18 18:35:14 +03:00
return status ;
2006-02-04 01:19:41 +03:00
}
2008-05-13 23:18:09 +04:00
/****************************************************************************
Connect to \ \ server \ service .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS connect_to_service ( struct net_context * c ,
2011-07-22 15:05:43 +04:00
struct cli_state * * cli_ctx ,
const struct sockaddr_storage * server_ss ,
const char * server_name ,
const char * service_name ,
const char * service_type )
2008-05-13 23:18:09 +04:00
{
NTSTATUS nt_status ;
2020-05-28 18:22:12 +03:00
int flags = 0 ;
2008-05-13 23:18:09 +04:00
2016-11-18 20:17:52 +03:00
if ( strequal ( service_type , " IPC " ) ) {
2020-05-28 18:22:12 +03:00
flags | = CLI_FULL_CONNECTION_IPC ;
2016-11-18 20:17:52 +03:00
}
2023-11-23 17:07:53 +03:00
nt_status = cli_full_connection_creds ( c ,
cli_ctx ,
NULL ,
server_name ,
server_ss ,
c - > opt_port ,
service_name ,
service_type ,
c - > creds ,
flags ) ;
2008-05-13 23:18:09 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2009-08-11 11:01:10 +04:00
d_fprintf ( stderr , _ ( " Could not connect to server %s \n " ) ,
server_name ) ;
2008-05-13 23:18:09 +04:00
/* Display a nicer message depending on the result */
if ( NT_STATUS_V ( nt_status ) = =
NT_STATUS_V ( NT_STATUS_LOGON_FAILURE ) )
2009-08-11 11:01:10 +04:00
d_fprintf ( stderr ,
_ ( " The username or password was not "
" correct. \n " ) ) ;
2008-05-13 23:18:09 +04:00
if ( NT_STATUS_V ( nt_status ) = =
NT_STATUS_V ( NT_STATUS_ACCOUNT_LOCKED_OUT ) )
2009-08-11 11:01:10 +04:00
d_fprintf ( stderr , _ ( " The account was locked out. \n " ) ) ;
2008-05-13 23:18:09 +04:00
if ( NT_STATUS_V ( nt_status ) = =
NT_STATUS_V ( NT_STATUS_ACCOUNT_DISABLED ) )
2009-08-11 11:01:10 +04:00
d_fprintf ( stderr , _ ( " The account was disabled. \n " ) ) ;
2008-05-13 23:18:09 +04:00
return nt_status ;
}
return nt_status ;
}
/****************************************************************************
Connect to \ \ server \ ipc $ .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS connect_to_ipc ( struct net_context * c ,
struct cli_state * * cli_ctx ,
2011-07-22 15:05:43 +04:00
const struct sockaddr_storage * server_ss ,
2008-05-13 23:18:09 +04:00
const char * server_name )
{
return connect_to_service ( c , cli_ctx , server_ss , server_name , " IPC$ " ,
" IPC " ) ;
}
/****************************************************************************
Connect to \ \ server \ ipc $ anonymously .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS connect_to_ipc_anonymous ( struct net_context * c ,
struct cli_state * * cli_ctx ,
2011-07-22 15:05:43 +04:00
const struct sockaddr_storage * server_ss ,
2008-05-13 23:18:09 +04:00
const char * server_name )
{
NTSTATUS nt_status ;
2019-11-11 17:14:18 +03:00
struct cli_credentials * anon_creds = NULL ;
2008-05-13 23:18:09 +04:00
2019-11-11 17:14:18 +03:00
anon_creds = cli_credentials_init_anon ( c ) ;
if ( anon_creds = = NULL ) {
DBG_ERR ( " cli_credentials_init_anon() failed \n " ) ;
return NT_STATUS_NO_MEMORY ;
}
2023-11-23 17:07:53 +03:00
nt_status = cli_full_connection_creds ( c ,
cli_ctx ,
c - > opt_requester_name ,
server_name ,
server_ss ,
c - > opt_port ,
" IPC$ " ,
" IPC " ,
anon_creds ,
CLI_FULL_CONNECTION_IPC ) ;
2008-05-13 23:18:09 +04:00
if ( NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
} else {
DEBUG ( 1 , ( " Cannot connect to server (anonymously). Error was %s \n " , nt_errstr ( nt_status ) ) ) ;
return nt_status ;
}
}
/**
* Connect a server and open a given pipe
*
* @ param cli_dst A cli_state
* @ param pipe The pipe to open
* @ param got_pipe boolean that stores if we got a pipe
*
* @ return Normal NTSTATUS return .
* */
NTSTATUS connect_dst_pipe ( struct net_context * c , struct cli_state * * cli_dst ,
2008-07-20 20:44:32 +04:00
struct rpc_pipe_client * * pp_pipe_hnd ,
2013-05-17 18:02:59 +04:00
const struct ndr_interface_table * table )
2008-05-13 23:18:09 +04:00
{
NTSTATUS nt_status ;
char * server_name = SMB_STRDUP ( " 127.0.0.1 " ) ;
struct cli_state * cli_tmp = NULL ;
struct rpc_pipe_client * pipe_hnd = NULL ;
if ( server_name = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
if ( c - > opt_destination ) {
SAFE_FREE ( server_name ) ;
if ( ( server_name = SMB_STRDUP ( c - > opt_destination ) ) = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
}
/* make a connection to a named pipe */
nt_status = connect_to_ipc ( c , & cli_tmp , NULL , server_name ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
SAFE_FREE ( server_name ) ;
return nt_status ;
}
2013-05-24 15:29:28 +04:00
nt_status = cli_rpc_pipe_open_noauth ( cli_tmp , table ,
2008-07-20 13:04:31 +04:00
& pipe_hnd ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2008-05-13 23:18:09 +04:00
DEBUG ( 0 , ( " couldn't not initialize pipe \n " ) ) ;
cli_shutdown ( cli_tmp ) ;
SAFE_FREE ( server_name ) ;
return nt_status ;
}
* cli_dst = cli_tmp ;
* pp_pipe_hnd = pipe_hnd ;
SAFE_FREE ( server_name ) ;
return nt_status ;
}
2009-07-05 11:21:07 +04:00
/****************************************************************************
Use the local machine account ( krb ) and password for this session .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int net_use_krb_machine_account ( struct net_context * c )
{
2024-09-11 19:21:58 +03:00
struct db_context * db_ctx = NULL ;
2009-07-05 11:21:07 +04:00
if ( ! secrets_init ( ) ) {
2009-08-11 11:01:10 +04:00
d_fprintf ( stderr , _ ( " ERROR: Unable to open secrets database \n " ) ) ;
2009-07-05 11:21:07 +04:00
exit ( 1 ) ;
}
2024-09-11 19:21:58 +03:00
db_ctx = secrets_db_ctx ( ) ;
cli_credentials_set_machine_account_db_ctx ( c - > creds , c - > lp_ctx , db_ctx ) ;
2024-03-07 16:40:10 +03:00
c - > explicit_credentials = true ;
2009-07-05 11:21:07 +04:00
return 0 ;
}
2008-05-13 23:18:09 +04:00
bool net_find_server ( struct net_context * c ,
const char * domain ,
unsigned flags ,
struct sockaddr_storage * server_ss ,
char * * server_name )
{
const char * d = domain ? domain : c - > opt_target_workgroup ;
if ( c - > opt_host ) {
* server_name = SMB_STRDUP ( c - > opt_host ) ;
}
if ( c - > opt_have_ip ) {
* server_ss = c - > opt_dest_ip ;
if ( ! * server_name ) {
char addr [ INET6_ADDRSTRLEN ] ;
print_sockaddr ( addr , sizeof ( addr ) , & c - > opt_dest_ip ) ;
* server_name = SMB_STRDUP ( addr ) ;
}
} else if ( * server_name ) {
/* resolve the IP address */
2009-07-28 22:51:58 +04:00
if ( ! resolve_name ( * server_name , server_ss , 0x20 , false ) ) {
2008-05-13 23:18:09 +04:00
DEBUG ( 1 , ( " Unable to resolve server name \n " ) ) ;
return false ;
}
} else if ( flags & NET_FLAGS_PDC ) {
fstring dc_name ;
struct sockaddr_storage pdc_ss ;
if ( ! get_pdc_ip ( d , & pdc_ss ) ) {
DEBUG ( 1 , ( " Unable to resolve PDC server address \n " ) ) ;
return false ;
}
2011-02-27 11:57:18 +03:00
if ( is_zero_addr ( & pdc_ss ) ) {
2008-05-13 23:18:09 +04:00
return false ;
}
if ( ! name_status_find ( d , 0x1b , 0x20 , & pdc_ss , dc_name ) ) {
return false ;
}
* server_name = SMB_STRDUP ( dc_name ) ;
* server_ss = pdc_ss ;
} else if ( flags & NET_FLAGS_DMB ) {
struct sockaddr_storage msbrow_ss ;
char addr [ INET6_ADDRSTRLEN ] ;
2009-07-28 22:51:58 +04:00
/* if (!resolve_name(MSBROWSE, &msbrow_ip, 1, false)) */
if ( ! resolve_name ( d , & msbrow_ss , 0x1B , false ) ) {
2008-05-13 23:18:09 +04:00
DEBUG ( 1 , ( " Unable to resolve domain browser via name lookup \n " ) ) ;
return false ;
}
* server_ss = msbrow_ss ;
print_sockaddr ( addr , sizeof ( addr ) , server_ss ) ;
* server_name = SMB_STRDUP ( addr ) ;
} else if ( flags & NET_FLAGS_MASTER ) {
struct sockaddr_storage brow_ss ;
char addr [ INET6_ADDRSTRLEN ] ;
2009-07-28 22:51:58 +04:00
if ( ! resolve_name ( d , & brow_ss , 0x1D , false ) ) {
2008-05-13 23:18:09 +04:00
/* go looking for workgroups */
DEBUG ( 1 , ( " Unable to resolve master browser via name lookup \n " ) ) ;
return false ;
}
* server_ss = brow_ss ;
print_sockaddr ( addr , sizeof ( addr ) , server_ss ) ;
* server_name = SMB_STRDUP ( addr ) ;
} else if ( ! ( flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE ) ) {
if ( ! interpret_string_addr ( server_ss ,
" 127.0.0.1 " , AI_NUMERICHOST ) ) {
DEBUG ( 1 , ( " Unable to resolve 127.0.0.1 \n " ) ) ;
return false ;
}
* server_name = SMB_STRDUP ( " 127.0.0.1 " ) ;
}
if ( ! * server_name ) {
DEBUG ( 1 , ( " no server to connect to \n " ) ) ;
return false ;
}
return true ;
}
bool net_find_pdc ( struct sockaddr_storage * server_ss ,
fstring server_name ,
const char * domain_name )
{
if ( ! get_pdc_ip ( domain_name , server_ss ) ) {
return false ;
}
2011-02-27 11:57:18 +03:00
if ( is_zero_addr ( server_ss ) ) {
2008-05-13 23:18:09 +04:00
return false ;
}
if ( ! name_status_find ( domain_name , 0x1b , 0x20 , server_ss , server_name ) ) {
return false ;
}
return true ;
}
NTSTATUS net_make_ipc_connection ( struct net_context * c , unsigned flags ,
struct cli_state * * pcli )
{
2008-08-22 02:27:22 +04:00
return net_make_ipc_connection_ex ( c , c - > opt_workgroup , NULL , NULL , flags , pcli ) ;
2008-05-13 23:18:09 +04:00
}
NTSTATUS net_make_ipc_connection_ex ( struct net_context * c , const char * domain ,
const char * server ,
2011-07-22 15:40:19 +04:00
const struct sockaddr_storage * pss ,
2008-05-13 23:18:09 +04:00
unsigned flags , struct cli_state * * pcli )
{
char * server_name = NULL ;
struct sockaddr_storage server_ss ;
struct cli_state * cli = NULL ;
NTSTATUS nt_status ;
if ( ! server | | ! pss ) {
if ( ! net_find_server ( c , domain , flags , & server_ss ,
& server_name ) ) {
2009-08-11 11:01:10 +04:00
d_fprintf ( stderr , _ ( " Unable to find a suitable server "
" for domain %s \n " ) , domain ) ;
2008-05-13 23:18:09 +04:00
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
} else {
server_name = SMB_STRDUP ( server ) ;
server_ss = * pss ;
}
if ( flags & NET_FLAGS_ANONYMOUS ) {
nt_status = connect_to_ipc_anonymous ( c , & cli , & server_ss ,
server_name ) ;
} else {
nt_status = connect_to_ipc ( c , & cli , & server_ss ,
server_name ) ;
}
/* store the server in the affinity cache if it was a PDC */
if ( ( flags & NET_FLAGS_PDC ) & & NT_STATUS_IS_OK ( nt_status ) )
2011-07-22 18:52:11 +04:00
saf_store ( cli - > server_domain , server_name ) ;
2008-05-13 23:18:09 +04:00
SAFE_FREE ( server_name ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2009-08-11 11:01:10 +04:00
d_fprintf ( stderr , _ ( " Connection failed: %s \n " ) ,
2008-05-13 23:18:09 +04:00
nt_errstr ( nt_status ) ) ;
cli = NULL ;
2009-03-26 22:32:55 +03:00
} else if ( c - > opt_request_timeout ) {
cli_set_timeout ( cli , c - > opt_request_timeout * 1000 ) ;
2008-05-13 23:18:09 +04:00
}
done :
if ( pcli ! = NULL ) {
* pcli = cli ;
}
return nt_status ;
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-18 12:56:32 +04:00
int net_run_function ( struct net_context * c , int argc , const char * * argv ,
2008-06-07 04:25:08 +04:00
const char * whoami , struct functable * table )
2008-05-22 11:41:21 +04:00
{
int i ;
2008-06-19 21:14:32 +04:00
2008-05-22 11:41:21 +04:00
if ( argc ! = 0 ) {
for ( i = 0 ; table [ i ] . funcname ! = NULL ; i + + ) {
2011-05-13 22:21:30 +04:00
if ( strcasecmp_m ( argv [ 0 ] , table [ i ] . funcname ) = = 0 )
2008-05-22 11:41:21 +04:00
return table [ i ] . fn ( c , argc - 1 , argv + 1 ) ;
}
}
if ( c - > display_usage = = false ) {
2009-08-11 11:01:10 +04:00
d_fprintf ( stderr , _ ( " Invalid command: %s %s \n " ) , whoami ,
2008-05-22 11:41:21 +04:00
( argc > 0 ) ? argv [ 0 ] : " " ) ;
}
2010-01-05 11:43:34 +03:00
d_printf ( _ ( " Usage: \n " ) ) ;
2008-05-22 11:41:21 +04:00
for ( i = 0 ; table [ i ] . funcname ! = NULL ; i + + ) {
if ( c - > display_usage = = false )
d_printf ( " %s %-15s %s \n " , whoami , table [ i ] . funcname ,
2010-01-05 11:43:34 +03:00
_ ( table [ i ] . description ) ) ;
2008-05-22 11:41:21 +04:00
else
2010-01-05 11:43:34 +03:00
d_printf ( " %s \n " , _ ( table [ i ] . usage ) ) ;
2008-05-22 11:41:21 +04:00
}
return c - > display_usage ? 0 : - 1 ;
}
2008-06-07 04:25:08 +04:00
void net_display_usage_from_functable ( struct functable * table )
2008-06-06 01:22:19 +04:00
{
int i ;
for ( i = 0 ; table [ i ] . funcname ! = NULL ; i + + ) {
2010-01-05 11:43:34 +03:00
d_printf ( " %s \n " , _ ( table [ i ] . usage ) ) ;
2008-06-06 01:22:19 +04:00
}
}
2008-09-25 01:23:01 +04:00
2022-11-30 18:16:05 +03:00
void net_warn_member_options ( void )
{
TALLOC_CTX * frame = talloc_stackframe ( ) ;
struct loadparm_context * lp_ctx = NULL ;
lp_ctx = loadparm_init_s3 ( frame , loadparm_s3_helpers ( ) ) ;
if ( lp_ctx ! = NULL ) {
netlogon_creds_cli_warn_options ( lp_ctx ) ;
}
TALLOC_FREE ( frame ) ;
}
2008-09-25 01:23:01 +04:00
const char * net_share_type_str ( int num_type )
{
switch ( num_type ) {
2009-08-11 11:01:10 +04:00
case 0 : return _ ( " Disk " ) ;
case 1 : return _ ( " Print " ) ;
case 2 : return _ ( " Dev " ) ;
case 3 : return _ ( " IPC " ) ;
default : return _ ( " Unknown " ) ;
2008-09-25 01:23:01 +04:00
}
}
2008-11-11 20:59:57 +03:00
2011-02-01 18:44:06 +03:00
static NTSTATUS net_scan_dc_noad ( struct net_context * c ,
struct cli_state * cli ,
struct net_dc_info * dc_info )
{
TALLOC_CTX * mem_ctx = talloc_tos ( ) ;
struct rpc_pipe_client * pipe_hnd = NULL ;
struct dcerpc_binding_handle * b ;
NTSTATUS status , result ;
struct policy_handle pol ;
union lsa_PolicyInformation * info ;
ZERO_STRUCTP ( dc_info ) ;
ZERO_STRUCT ( pol ) ;
2013-05-24 15:29:28 +04:00
status = cli_rpc_pipe_open_noauth ( cli , & ndr_table_lsarpc ,
2011-02-01 18:44:06 +03:00
& pipe_hnd ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
b = pipe_hnd - > binding_handle ;
status = dcerpc_lsa_open_policy ( b , mem_ctx ,
false ,
SEC_FLAG_MAXIMUM_ALLOWED ,
& pol ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
if ( ! NT_STATUS_IS_OK ( result ) ) {
status = result ;
goto done ;
}
status = dcerpc_lsa_QueryInfoPolicy ( b , mem_ctx ,
& pol ,
LSA_POLICY_INFO_ACCOUNT_DOMAIN ,
& info ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
if ( ! NT_STATUS_IS_OK ( result ) ) {
status = result ;
goto done ;
}
dc_info - > netbios_domain_name = talloc_strdup ( mem_ctx , info - > account_domain . name . string ) ;
if ( dc_info - > netbios_domain_name = = NULL ) {
status = NT_STATUS_NO_MEMORY ;
goto done ;
}
done :
if ( is_valid_policy_hnd ( & pol ) ) {
dcerpc_lsa_Close ( b , mem_ctx , & pol , & result ) ;
}
TALLOC_FREE ( pipe_hnd ) ;
return status ;
}
2008-11-11 20:59:57 +03:00
NTSTATUS net_scan_dc ( struct net_context * c ,
struct cli_state * cli ,
struct net_dc_info * dc_info )
{
TALLOC_CTX * mem_ctx = talloc_tos ( ) ;
struct rpc_pipe_client * dssetup_pipe = NULL ;
2011-01-04 19:18:22 +03:00
struct dcerpc_binding_handle * dssetup_handle = NULL ;
2008-11-11 20:59:57 +03:00
union dssetup_DsRoleInfo info ;
NTSTATUS status ;
2011-01-04 19:18:22 +03:00
WERROR werr ;
2008-11-11 20:59:57 +03:00
ZERO_STRUCTP ( dc_info ) ;
2013-05-24 15:29:28 +04:00
status = cli_rpc_pipe_open_noauth ( cli , & ndr_table_dssetup ,
2008-11-11 20:59:57 +03:00
& dssetup_pipe ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-02-01 18:44:06 +03:00
DEBUG ( 10 , ( " net_scan_dc: failed to open dssetup pipe with %s, "
" retrying with lsa pipe \n " , nt_errstr ( status ) ) ) ;
return net_scan_dc_noad ( c , cli , dc_info ) ;
2008-11-11 20:59:57 +03:00
}
2011-01-04 19:18:22 +03:00
dssetup_handle = dssetup_pipe - > binding_handle ;
2008-11-11 20:59:57 +03:00
2011-01-04 19:18:22 +03:00
status = dcerpc_dssetup_DsRoleGetPrimaryDomainInformation ( dssetup_handle , mem_ctx ,
2008-11-11 20:59:57 +03:00
DS_ROLE_BASIC_INFORMATION ,
& info ,
2011-01-04 19:18:22 +03:00
& werr ) ;
2008-11-11 20:59:57 +03:00
TALLOC_FREE ( dssetup_pipe ) ;
2011-01-04 19:18:22 +03:00
if ( NT_STATUS_IS_OK ( status ) ) {
status = werror_to_ntstatus ( werr ) ;
}
2008-11-11 20:59:57 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
dc_info - > is_dc = ( info . basic . role & ( DS_ROLE_PRIMARY_DC | DS_ROLE_BACKUP_DC ) ) ;
dc_info - > is_pdc = ( info . basic . role & DS_ROLE_PRIMARY_DC ) ;
dc_info - > is_ad = ( info . basic . flags & DS_ROLE_PRIMARY_DS_RUNNING ) ;
dc_info - > is_mixed_mode = ( info . basic . flags & DS_ROLE_PRIMARY_DS_MIXED_MODE ) ;
dc_info - > netbios_domain_name = talloc_strdup ( mem_ctx , info . basic . domain ) ;
dc_info - > dns_domain_name = talloc_strdup ( mem_ctx , info . basic . dns_domain ) ;
dc_info - > forest_name = talloc_strdup ( mem_ctx , info . basic . forest ) ;
return NT_STATUS_OK ;
}