2008-02-15 16:13:11 +03:00
/*
2002-08-23 02:48:54 +04:00
Unix SMB / CIFS implementation .
dump the remote SAM using rpc samsync operations
Copyright ( C ) Andrew Tridgell 2002
Copyright ( C ) Tim Potter 2001 , 2002
2005-07-07 01:02:43 +04:00
Copyright ( C ) Jim McDonough < jmcd @ us . ibm . com > 2005
2002-10-01 22:26:00 +04:00
Modified by Volker Lendecke 2002
2005-09-30 21:13:37 +04:00
Copyright ( C ) Jeremy Allison 2005.
2008-02-27 21:38:48 +03:00
Copyright ( C ) Guenther Deschner 2008.
2002-08-23 02:48:54 +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-23 02:48:54 +04:00
( at your option ) any later version .
2008-02-15 16:13:11 +03:00
2002-08-23 02:48:54 +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-15 16:13:11 +03:00
2002-08-23 02:48:54 +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-23 02:48:54 +04:00
*/
# include "includes.h"
2004-10-07 08:01:18 +04:00
# include "utils/net.h"
2010-05-05 03:39:16 +04:00
# include "../librpc/gen_ndr/ndr_netlogon.h"
# include "../librpc/gen_ndr/ndr_drsuapi.h"
2010-07-02 02:14:04 +04:00
# include "libnet/libnet_samsync.h"
# include "libnet/libnet_dssync.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2011-03-22 18:50:02 +03:00
# include "passdb/machine_sid.h"
2002-08-23 02:48:54 +04:00
2008-11-04 18:25:40 +03:00
static void parse_samsync_partial_replication_objects ( TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv ,
bool * do_single_object_replication ,
struct samsync_object * * objects ,
uint32_t * num_objects )
{
int i ;
if ( argc > 0 ) {
* do_single_object_replication = true ;
}
for ( i = 0 ; i < argc ; i + + ) {
struct samsync_object o ;
ZERO_STRUCT ( o ) ;
2011-05-13 22:23:36 +04:00
if ( ! strncasecmp_m ( argv [ i ] , " user_rid= " , strlen ( " user_rid= " ) ) ) {
2008-11-04 18:25:40 +03:00
o . object_identifier . rid = get_int_param ( argv [ i ] ) ;
o . object_type = NETR_DELTA_USER ;
o . database_id = SAM_DATABASE_DOMAIN ;
}
2011-05-13 22:23:36 +04:00
if ( ! strncasecmp_m ( argv [ i ] , " group_rid= " , strlen ( " group_rid= " ) ) ) {
2008-11-04 18:25:40 +03:00
o . object_identifier . rid = get_int_param ( argv [ i ] ) ;
o . object_type = NETR_DELTA_GROUP ;
o . database_id = SAM_DATABASE_DOMAIN ;
}
2011-05-13 22:23:36 +04:00
if ( ! strncasecmp_m ( argv [ i ] , " group_member_rid= " , strlen ( " group_member_rid= " ) ) ) {
2008-11-04 18:25:40 +03:00
o . object_identifier . rid = get_int_param ( argv [ i ] ) ;
o . object_type = NETR_DELTA_GROUP_MEMBER ;
o . database_id = SAM_DATABASE_DOMAIN ;
}
2011-05-13 22:23:36 +04:00
if ( ! strncasecmp_m ( argv [ i ] , " alias_rid= " , strlen ( " alias_rid= " ) ) ) {
2008-11-04 18:25:40 +03:00
o . object_identifier . rid = get_int_param ( argv [ i ] ) ;
o . object_type = NETR_DELTA_ALIAS ;
o . database_id = SAM_DATABASE_BUILTIN ;
}
2011-05-13 22:23:36 +04:00
if ( ! strncasecmp_m ( argv [ i ] , " alias_member_rid= " , strlen ( " alias_member_rid= " ) ) ) {
2008-11-04 18:25:40 +03:00
o . object_identifier . rid = get_int_param ( argv [ i ] ) ;
o . object_type = NETR_DELTA_ALIAS_MEMBER ;
o . database_id = SAM_DATABASE_BUILTIN ;
}
2011-05-13 22:23:36 +04:00
if ( ! strncasecmp_m ( argv [ i ] , " account_sid= " , strlen ( " account_sid= " ) ) ) {
2008-11-04 18:25:40 +03:00
const char * sid_str = get_string_param ( argv [ i ] ) ;
string_to_sid ( & o . object_identifier . sid , sid_str ) ;
o . object_type = NETR_DELTA_ACCOUNT ;
o . database_id = SAM_DATABASE_PRIVS ;
}
2011-05-13 22:23:36 +04:00
if ( ! strncasecmp_m ( argv [ i ] , " policy_sid= " , strlen ( " policy_sid= " ) ) ) {
2008-11-04 18:25:40 +03:00
const char * sid_str = get_string_param ( argv [ i ] ) ;
string_to_sid ( & o . object_identifier . sid , sid_str ) ;
o . object_type = NETR_DELTA_POLICY ;
o . database_id = SAM_DATABASE_PRIVS ;
}
2011-05-13 22:23:36 +04:00
if ( ! strncasecmp_m ( argv [ i ] , " trustdom_sid= " , strlen ( " trustdom_sid= " ) ) ) {
2008-11-04 18:25:40 +03:00
const char * sid_str = get_string_param ( argv [ i ] ) ;
string_to_sid ( & o . object_identifier . sid , sid_str ) ;
o . object_type = NETR_DELTA_TRUSTED_DOMAIN ;
o . database_id = SAM_DATABASE_PRIVS ;
}
2011-05-13 22:23:36 +04:00
if ( ! strncasecmp_m ( argv [ i ] , " secret_name= " , strlen ( " secret_name= " ) ) ) {
2008-11-04 18:25:40 +03:00
o . object_identifier . name = get_string_param ( argv [ i ] ) ;
o . object_type = NETR_DELTA_SECRET ;
o . database_id = SAM_DATABASE_PRIVS ;
}
if ( o . object_type > 0 ) {
ADD_TO_ARRAY ( mem_ctx , struct samsync_object , o ,
objects , num_objects ) ;
}
}
}
2008-02-15 16:13:11 +03:00
/**
2005-07-07 01:02:43 +04:00
* Basic usage function for ' net rpc vampire '
2008-05-10 01:22:12 +04:00
*
* @ param c A net_context structure
2005-07-07 01:02:43 +04:00
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
* */
2008-05-10 01:22:12 +04:00
int rpc_vampire_usage ( struct net_context * c , int argc , const char * * argv )
2008-02-15 16:13:11 +03:00
{
2009-08-10 21:54:27 +04:00
d_printf ( _ ( " net rpc vampire ([ldif [<ldif-filename>] | [keytab] "
" [<keytab-filename]) [options] \n "
" \t to pull accounts from a remote PDC where we are a BDC \n "
" \t \t no args puts accounts in local passdb from smb.conf \n "
" \t \t ldif - put accounts in ldif format (file defaults to "
" /tmp/tmp.ldif) \n "
" \t \t keytab - put account passwords in krb5 keytab "
" (defaults to system keytab) \n " ) ) ;
2005-07-07 01:02:43 +04:00
2008-05-10 01:22:12 +04:00
net_common_flags_usage ( c , argc , argv ) ;
2005-07-07 01:02:43 +04:00
return - 1 ;
}
2008-11-22 01:48:45 +03:00
static NTSTATUS rpc_vampire_ds_internals ( struct net_context * c ,
const struct dom_sid * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
{
NTSTATUS status ;
struct dssync_context * ctx = NULL ;
if ( ! dom_sid_equal ( domain_sid , get_global_sam_sid ( ) ) ) {
d_printf ( _ ( " Cannot import users from %s at this time, "
" as the current domain: \n \t %s: %s \n conflicts "
" with the remote domain \n \t %s: %s \n "
" Perhaps you need to set: \n \n \t security=user \n \t "
" workgroup=%s \n \n in your smb.conf? \n " ) ,
domain_name ,
get_global_sam_name ( ) ,
sid_string_dbg ( get_global_sam_sid ( ) ) ,
domain_name ,
sid_string_dbg ( domain_sid ) ,
domain_name ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
status = libnet_dssync_init_context ( mem_ctx ,
& ctx ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
ctx - > cli = pipe_hnd ;
ctx - > domain_name = domain_name ;
ctx - > ops = & libnet_dssync_passdb_ops ;
status = libnet_dssync ( mem_ctx , ctx ) ;
if ( ! NT_STATUS_IS_OK ( status ) & & ctx - > error_message ) {
d_fprintf ( stderr , " %s \n " , ctx - > error_message ) ;
goto out ;
}
if ( ctx - > result_message ) {
d_fprintf ( stdout , " %s \n " , ctx - > result_message ) ;
}
out :
TALLOC_FREE ( ctx ) ;
return status ;
}
2005-07-07 01:02:43 +04:00
2008-11-18 15:25:50 +03:00
int rpc_vampire_passdb ( struct net_context * c , int argc , const char * * argv )
{
2008-11-22 01:48:45 +03:00
int ret = 0 ;
NTSTATUS status ;
struct cli_state * cli = NULL ;
struct net_dc_info dc_info ;
2008-11-18 15:25:50 +03:00
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
2009-08-10 21:54:27 +04:00
" net rpc vampire passdb \n "
2010-01-19 13:43:54 +03:00
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Dump remote SAM database to passdb " ) ) ;
2008-11-18 15:25:50 +03:00
return 0 ;
}
2008-11-22 01:48:45 +03:00
status = net_make_ipc_connection ( c , 0 , & cli ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return - 1 ;
}
status = net_scan_dc ( c , cli , & dc_info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return - 1 ;
}
if ( ! dc_info . is_ad ) {
2017-09-20 01:03:43 +03:00
printf ( _ ( " DC is not running Active Directory, exiting \n " ) ) ;
return - 1 ;
2008-11-22 01:48:45 +03:00
}
if ( ! c - > opt_force ) {
d_printf ( " %s \n "
" net rpc vampire passdb \n "
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Should not be used against Active Directory, maybe use --force " ) ) ;
return - 1 ;
}
2012-01-10 14:53:42 +04:00
ret = run_rpc_command ( c , cli , & ndr_table_drsuapi ,
2008-11-22 01:48:45 +03:00
NET_FLAGS_SEAL | NET_FLAGS_TCP ,
rpc_vampire_ds_internals , argc , argv ) ;
return ret ;
2008-11-18 15:25:50 +03:00
}
2011-01-04 15:02:35 +03:00
static NTSTATUS rpc_vampire_keytab_internals ( struct net_context * c ,
const struct dom_sid * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2008-06-18 14:52:00 +04:00
{
NTSTATUS status ;
struct samsync_context * ctx = NULL ;
status = libnet_samsync_init_context ( mem_ctx ,
domain_sid ,
& ctx ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2008-11-10 11:51:39 +03:00
if ( argc < 1 ) {
/* the caller should ensure that a filename is provided */
return NT_STATUS_INVALID_PARAMETER ;
} else {
2008-06-18 14:52:00 +04:00
ctx - > output_filename = argv [ 0 ] ;
}
2008-11-04 18:25:40 +03:00
if ( argc > = 2 ) {
parse_samsync_partial_replication_objects ( ctx , argc - 1 , argv + 1 ,
& ctx - > single_object_replication ,
& ctx - > objects ,
& ctx - > num_objects ) ;
}
2008-06-18 14:52:00 +04:00
ctx - > mode = NET_SAMSYNC_MODE_FETCH_KEYTAB ;
ctx - > cli = pipe_hnd ;
2008-11-17 18:31:59 +03:00
ctx - > ops = & libnet_samsync_keytab_ops ;
2008-06-18 14:52:00 +04:00
ctx - > domain_name = domain_name ;
2009-07-05 11:21:07 +04:00
ctx - > username = c - > opt_user_name ;
ctx - > password = c - > opt_password ;
2008-06-18 14:52:00 +04:00
2008-11-04 18:25:40 +03:00
ctx - > force_full_replication = c - > opt_force_full_repl ? true : false ;
ctx - > clean_old_entries = c - > opt_clean_old_entries ? true : false ;
2008-06-18 14:52:00 +04:00
/* fetch domain */
status = libnet_samsync ( SAM_DATABASE_DOMAIN , ctx ) ;
if ( ! NT_STATUS_IS_OK ( status ) & & ctx - > error_message ) {
d_fprintf ( stderr , " %s \n " , ctx - > error_message ) ;
goto out ;
}
if ( ctx - > result_message ) {
d_fprintf ( stdout , " %s \n " , ctx - > result_message ) ;
}
out :
TALLOC_FREE ( ctx ) ;
return status ;
}
2008-07-17 15:06:46 +04:00
static NTSTATUS rpc_vampire_keytab_ds_internals ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-07-17 15:06:46 +04:00
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2008-06-27 17:36:19 +04:00
{
NTSTATUS status ;
struct dssync_context * ctx = NULL ;
status = libnet_dssync_init_context ( mem_ctx ,
& ctx ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2008-07-30 19:46:13 +04:00
ctx - > force_full_replication = c - > opt_force_full_repl ? true : false ;
2008-08-01 02:12:18 +04:00
ctx - > clean_old_entries = c - > opt_clean_old_entries ? true : false ;
2008-07-30 00:52:59 +04:00
2008-11-10 11:51:39 +03:00
if ( argc < 1 ) {
/* the caller should ensure that a filename is provided */
return NT_STATUS_INVALID_PARAMETER ;
} else {
2008-06-27 17:36:19 +04:00
ctx - > output_filename = argv [ 0 ] ;
}
2008-11-10 11:51:39 +03:00
2008-07-18 02:18:40 +04:00
if ( argc > = 2 ) {
2008-07-30 15:02:36 +04:00
ctx - > object_dns = & argv [ 1 ] ;
ctx - > object_count = argc - 1 ;
2008-08-01 01:05:45 +04:00
ctx - > single_object_replication = c - > opt_single_obj_repl ? true
: false ;
2008-07-18 02:18:40 +04:00
}
2008-06-27 17:36:19 +04:00
ctx - > cli = pipe_hnd ;
ctx - > domain_name = domain_name ;
2008-07-16 19:12:04 +04:00
ctx - > ops = & libnet_dssync_keytab_ops ;
2008-06-27 17:36:19 +04:00
status = libnet_dssync ( mem_ctx , ctx ) ;
if ( ! NT_STATUS_IS_OK ( status ) & & ctx - > error_message ) {
d_fprintf ( stderr , " %s \n " , ctx - > error_message ) ;
goto out ;
}
if ( ctx - > result_message ) {
d_fprintf ( stdout , " %s \n " , ctx - > result_message ) ;
}
out :
TALLOC_FREE ( ctx ) ;
return status ;
}
2008-06-18 14:52:00 +04:00
/**
* Basic function for ' net rpc vampire keytab '
*
* @ param c A net_context structure
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
* */
int rpc_vampire_keytab ( struct net_context * c , int argc , const char * * argv )
{
2008-06-27 17:36:19 +04:00
int ret = 0 ;
2008-11-11 21:00:26 +03:00
NTSTATUS status ;
struct cli_state * cli = NULL ;
struct net_dc_info dc_info ;
2008-06-27 17:36:19 +04:00
2008-11-10 11:51:39 +03:00
if ( c - > display_usage | | ( argc < 1 ) ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net rpc vampire keytab <keytabfile> \n "
2009-08-10 21:54:27 +04:00
" Dump remote SAM database to Kerberos keytab "
" file \n " ) ) ;
2008-06-18 14:52:00 +04:00
return 0 ;
}
2008-11-11 21:00:26 +03:00
status = net_make_ipc_connection ( c , 0 , & cli ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return - 1 ;
2008-06-27 17:36:19 +04:00
}
2008-11-11 21:00:26 +03:00
status = net_scan_dc ( c , cli , & dc_info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return - 1 ;
}
if ( ! dc_info . is_ad ) {
2009-08-10 21:54:27 +04:00
printf ( _ ( " DC is not running Active Directory \n " ) ) ;
2012-01-10 14:53:42 +04:00
ret = run_rpc_command ( c , cli , & ndr_table_netlogon ,
2009-11-08 21:37:26 +03:00
0 ,
rpc_vampire_keytab_internals , argc , argv ) ;
2008-11-11 21:00:26 +03:00
} else {
2012-01-10 14:53:42 +04:00
ret = run_rpc_command ( c , cli , & ndr_table_drsuapi ,
2009-09-11 00:23:21 +04:00
NET_FLAGS_SEAL | NET_FLAGS_TCP ,
2008-11-11 21:00:26 +03:00
rpc_vampire_keytab_ds_internals , argc , argv ) ;
2009-07-13 15:24:19 +04:00
if ( ret ! = 0 & & dc_info . is_mixed_mode ) {
2009-08-10 21:54:27 +04:00
printf ( _ ( " Fallback to NT4 vampire on Mixed-Mode AD "
" Domain \n " ) ) ;
2012-01-10 14:53:42 +04:00
ret = run_rpc_command ( c , cli , & ndr_table_netlogon ,
2009-07-13 15:24:19 +04:00
0 ,
2009-11-08 21:37:26 +03:00
rpc_vampire_keytab_internals , argc , argv ) ;
2012-03-02 04:29:15 +04:00
} else {
# ifndef HAVE_ADS
printf ( _ ( " Vampire requested against AD DC but ADS "
" support not built in: HAVE_ADS is not defined \n " ) ) ;
# endif
2009-07-13 15:24:19 +04:00
}
2008-11-11 21:00:26 +03:00
}
return ret ;
2008-06-18 14:52:00 +04:00
}