2006-12-13 02:23:50 +03:00
/*
Unix SMB / CIFS implementation .
libnet_BecomeDC ( ) tests
2007-03-14 22:10:21 +03:00
Copyright ( C ) Stefan Metzmacher < metze @ samba . org > 2006
2006-12-13 02:23:50 +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-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2006-12-13 02:23:50 +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 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2006-12-13 02:23:50 +03:00
*/
# include "includes.h"
# include "lib/cmdline/popt_common.h"
2010-04-14 00:06:51 +04:00
# include "torture/rpc/torture_rpc.h"
2006-12-13 02:23:50 +03:00
# include "libnet/libnet.h"
2006-12-23 00:31:57 +03:00
# include "dsdb/samdb/samdb.h"
2008-10-11 23:31:42 +04:00
# include "../lib/util/dlinklist.h"
2007-01-05 00:09:29 +03:00
# include "librpc/gen_ndr/ndr_drsuapi.h"
# include "librpc/gen_ndr/ndr_drsblobs.h"
# include "system/time.h"
2010-06-16 15:43:38 +04:00
# include "ldb_wrap.h"
2008-02-15 02:23:56 +03:00
# include "auth/auth.h"
2008-02-15 01:28:31 +03:00
# include "param/param.h"
2008-04-09 05:23:13 +04:00
# include "param/provision.h"
2009-11-10 14:49:48 +03:00
# include "libcli/resolve/resolve.h"
2014-02-27 12:08:17 +04:00
# include "torture/libnet/proto.h"
2007-12-26 01:36:58 +03:00
2007-10-07 02:28:14 +04:00
bool torture_net_become_dc ( struct torture_context * torture )
2006-12-13 02:23:50 +03:00
{
2007-10-07 02:28:14 +04:00
bool ret = true ;
2006-12-13 02:23:50 +03:00
NTSTATUS status ;
struct libnet_BecomeDC b ;
struct libnet_UnbecomeDC u ;
2010-06-12 11:24:26 +04:00
struct libnet_vampire_cb_state * s ;
2007-01-18 03:26:07 +03:00
struct ldb_message * msg ;
int ldb_ret ;
uint32_t i ;
2011-06-02 09:43:40 +04:00
char * private_dir ;
2009-11-10 14:49:48 +03:00
const char * address ;
struct nbt_name name ;
2010-06-12 11:24:26 +04:00
const char * netbios_name ;
struct cli_credentials * machine_account ;
struct test_join * tj ;
struct loadparm_context * lp_ctx ;
struct ldb_context * ldb ;
struct libnet_context * ctx ;
struct dsdb_schema * schema ;
Make Samba4 pass the NET-API-BECOMEDC test against Win2k3 (again).
To make Samba4, using the python provision system, pass this test
required some major rework. Untested code is broken code, and some of
the refactoring for a seperate provision test (which also now passes)
broke things.
Similarly, the iconv work has compiled, but these codepaths have never
been run (NULL pointer de-reference).
In working to use a local, rather than global, loadparm context, and
to support using a target directory, a few things needed to be
reworked, particularly around path handling.
Andrew Bartlett
(This used to be commit 1169e8d7bee20477b0efbfea3534ac63c83fb3d6)
2008-03-06 13:55:26 +03:00
char * location = NULL ;
torture_assert_ntstatus_ok ( torture , torture_temp_dir ( torture , " libnet_BecomeDC " , & location ) ,
" torture_temp_dir should return NT_STATUS_OK " ) ;
2006-12-23 00:31:57 +03:00
2010-07-16 08:32:42 +04:00
netbios_name = lpcfg_parm_string ( torture - > lp_ctx , NULL , " become dc " , " smbtorture dc " ) ;
2010-06-12 11:24:26 +04:00
if ( ! netbios_name | | ! netbios_name [ 0 ] ) {
netbios_name = " smbtorturedc " ;
}
2007-12-07 03:16:50 +03:00
2009-11-10 14:49:48 +03:00
make_nbt_name_server ( & name , torture_setting_string ( torture , " host " , NULL ) ) ;
/* do an initial name resolution to find its IP */
2011-05-02 10:36:48 +04:00
status = resolve_name_ex ( lpcfg_resolve_context ( torture - > lp_ctx ) ,
0 , 0 ,
& name , torture , & address , torture - > ev ) ;
2010-03-11 15:30:19 +03:00
torture_assert_ntstatus_ok ( torture , status , talloc_asprintf ( torture ,
" Failed to resolve %s - %s \n " ,
name . name , nt_errstr ( status ) ) ) ;
2009-11-10 14:49:48 +03:00
2007-02-23 13:25:28 +03:00
2006-12-13 02:23:50 +03:00
/* Join domain as a member server. */
2010-06-12 11:24:26 +04:00
tj = torture_join_domain ( torture , netbios_name ,
2006-12-13 02:23:50 +03:00
ACB_WSTRUST ,
2010-06-12 11:24:26 +04:00
& machine_account ) ;
torture_assert ( torture , tj , talloc_asprintf ( torture ,
" %s failed to join domain as workstation \n " ,
netbios_name ) ) ;
2006-12-13 02:23:50 +03:00
2010-06-12 11:24:26 +04:00
s = libnet_vampire_cb_state_init ( torture , torture - > lp_ctx , torture - > ev ,
netbios_name ,
torture_join_dom_netbios_name ( tj ) ,
torture_join_dom_dns_name ( tj ) ,
location ) ;
torture_assert ( torture , s , " libnet_vampire_cb_state_init " ) ;
2006-12-13 02:23:50 +03:00
2010-06-12 11:24:26 +04:00
ctx = libnet_context_init ( torture - > ev , torture - > lp_ctx ) ;
ctx - > cred = cmdline_credentials ;
2006-12-31 15:32:15 +03:00
2006-12-20 18:34:32 +03:00
ZERO_STRUCT ( b ) ;
2010-06-12 11:24:26 +04:00
b . in . domain_dns_name = torture_join_dom_dns_name ( tj ) ;
b . in . domain_netbios_name = torture_join_dom_netbios_name ( tj ) ;
b . in . domain_sid = torture_join_sid ( tj ) ;
2009-11-10 14:49:48 +03:00
b . in . source_dsa_address = address ;
2010-06-12 11:24:26 +04:00
b . in . dest_dsa_netbios_name = netbios_name ;
2006-12-13 02:23:50 +03:00
2006-12-23 00:31:57 +03:00
b . in . callbacks . private_data = s ;
2010-06-12 11:24:26 +04:00
b . in . callbacks . check_options = libnet_vampire_cb_check_options ;
b . in . callbacks . prepare_db = libnet_vampire_cb_prepare_db ;
b . in . callbacks . schema_chunk = libnet_vampire_cb_schema_chunk ;
b . in . callbacks . config_chunk = libnet_vampire_cb_store_chunk ;
b . in . callbacks . domain_chunk = libnet_vampire_cb_store_chunk ;
2006-12-20 18:34:32 +03:00
2010-06-12 11:24:26 +04:00
status = libnet_BecomeDC ( ctx , s , & b ) ;
2010-03-11 15:30:19 +03:00
torture_assert_ntstatus_ok_goto ( torture , status , ret , cleanup , talloc_asprintf ( torture ,
" libnet_BecomeDC() failed - %s %s \n " ,
nt_errstr ( status ) , b . out . error_string ) ) ;
2010-06-12 11:24:26 +04:00
ldb = libnet_vampire_cb_ldb ( s ) ;
2007-01-18 03:26:07 +03:00
msg = ldb_msg_new ( s ) ;
2010-03-11 15:30:19 +03:00
torture_assert_int_equal_goto ( torture , ( msg ? 1 : 0 ) , 1 , ret , cleanup ,
" ldb_msg_new() failed \n " ) ;
2010-06-12 11:24:26 +04:00
msg - > dn = ldb_dn_new ( msg , ldb , " @ROOTDSE " ) ;
2010-03-11 15:30:19 +03:00
torture_assert_int_equal_goto ( torture , ( msg - > dn ? 1 : 0 ) , 1 , ret , cleanup ,
" ldb_msg_new(@ROOTDSE) failed \n " ) ;
2007-01-18 03:26:07 +03:00
ldb_ret = ldb_msg_add_string ( msg , " isSynchronized " , " TRUE " ) ;
2010-03-11 15:30:19 +03:00
torture_assert_int_equal_goto ( torture , ldb_ret , LDB_SUCCESS , ret , cleanup ,
" ldb_msg_add_string(msg, isSynchronized, TRUE) failed \n " ) ;
2007-01-18 03:26:07 +03:00
for ( i = 0 ; i < msg - > num_elements ; i + + ) {
msg - > elements [ i ] . flags = LDB_FLAG_MOD_REPLACE ;
}
2010-03-11 15:30:19 +03:00
torture_comment ( torture , " mark ROOTDSE with isSynchronized=TRUE \n " ) ;
2010-06-12 11:24:26 +04:00
ldb_ret = ldb_modify ( libnet_vampire_cb_ldb ( s ) , msg ) ;
2010-03-11 15:30:19 +03:00
torture_assert_int_equal_goto ( torture , ldb_ret , LDB_SUCCESS , ret , cleanup ,
" ldb_modify() failed \n " ) ;
2007-01-18 03:26:07 +03:00
2010-06-12 11:24:26 +04:00
/* commit the transaction now we know the secrets were written
* out properly
*/
ldb_ret = ldb_transaction_commit ( ldb ) ;
torture_assert_int_equal_goto ( torture , ldb_ret , LDB_SUCCESS , ret , cleanup ,
" ldb_transaction_commit() failed \n " ) ;
2007-01-18 03:26:07 +03:00
/* reopen the ldb */
2010-06-12 11:24:26 +04:00
talloc_unlink ( s , ldb ) ;
2007-01-18 03:26:07 +03:00
2010-06-12 11:24:26 +04:00
lp_ctx = libnet_vampire_cb_lp_ctx ( s ) ;
2011-06-02 09:43:40 +04:00
private_dir = talloc_asprintf ( s , " %s/%s " , location , " private " ) ;
lpcfg_set_cmdline ( lp_ctx , " private dir " , private_dir ) ;
torture_comment ( torture , " Reopen the SAM LDB with system credentials and all replicated data: %s \n " , private_dir ) ;
2010-10-12 21:53:47 +04:00
ldb = samdb_connect ( s , torture - > ev , lp_ctx , system_session ( lp_ctx ) , 0 ) ;
torture_assert_goto ( torture , ldb ! = NULL , ret , cleanup ,
2010-03-11 15:30:19 +03:00
talloc_asprintf ( torture ,
2011-06-02 09:43:40 +04:00
" Failed to open '%s/sam.ldb' \n " , private_dir ) ) ;
2007-01-18 03:26:07 +03:00
2010-10-12 21:53:47 +04:00
torture_assert_goto ( torture , dsdb_uses_global_schema ( ldb ) , ret , cleanup ,
" Uses global schema " ) ;
2010-06-12 11:24:26 +04:00
schema = dsdb_get_schema ( ldb , s ) ;
2010-10-12 21:53:47 +04:00
torture_assert_goto ( torture , schema ! = NULL , ret , cleanup ,
2010-03-11 15:30:19 +03:00
" Failed to get loaded dsdb_schema \n " ) ;
2006-12-13 02:23:50 +03:00
2008-03-06 14:03:10 +03:00
/* Make sure we get this from the command line */
2010-07-16 08:32:42 +04:00
if ( lpcfg_parm_bool ( torture - > lp_ctx , NULL , " become dc " , " do not unjoin " , false ) ) {
2007-02-22 18:25:55 +03:00
talloc_free ( s ) ;
return ret ;
}
2007-01-18 03:26:07 +03:00
cleanup :
2006-12-20 18:34:32 +03:00
ZERO_STRUCT ( u ) ;
2010-06-12 11:24:26 +04:00
u . in . domain_dns_name = torture_join_dom_dns_name ( tj ) ;
u . in . domain_netbios_name = torture_join_dom_netbios_name ( tj ) ;
2009-11-10 14:49:48 +03:00
u . in . source_dsa_address = address ;
2010-06-12 11:24:26 +04:00
u . in . dest_dsa_netbios_name = netbios_name ;
2006-12-13 02:23:50 +03:00
2010-06-12 11:24:26 +04:00
status = libnet_UnbecomeDC ( ctx , s , & u ) ;
2010-03-11 15:30:19 +03:00
torture_assert_ntstatus_ok ( torture , status , talloc_asprintf ( torture ,
" libnet_UnbecomeDC() failed - %s %s \n " ,
nt_errstr ( status ) , u . out . error_string ) ) ;
2006-12-13 02:23:50 +03:00
2010-10-12 21:53:47 +04:00
/* Leave domain. */
2010-06-12 11:24:26 +04:00
torture_leave_domain ( torture , tj ) ;
2006-12-23 00:31:57 +03:00
talloc_free ( s ) ;
2006-12-13 02:23:50 +03:00
return ret ;
}