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
2002-10-01 22:26:00 +04:00
Modified by Volker Lendecke 2002
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
the Free Software Foundation ; either version 2 of the License , or
( 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
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
# include "../utils/net.h"
2002-09-24 10:50:11 +04:00
extern DOM_SID global_sid_Builtin ;
2002-08-23 02:48:54 +04:00
static void display_group_mem_info ( uint32 rid , SAM_GROUP_MEM_INFO * g )
{
int i ;
d_printf ( " Group mem %u: " , rid ) ;
for ( i = 0 ; i < g - > num_members ; i + + ) {
d_printf ( " %u " , g - > rids [ i ] ) ;
}
d_printf ( " \n " ) ;
}
static void display_alias_info ( uint32 rid , SAM_ALIAS_INFO * a )
{
d_printf ( " Alias '%s' " , unistr2_static ( & a - > uni_als_name ) ) ;
d_printf ( " desc='%s' rid=%u \n " , unistr2_static ( & a - > uni_als_desc ) , a - > als_rid ) ;
}
static void display_alias_mem ( uint32 rid , SAM_ALIAS_MEM_INFO * a )
{
int i ;
d_printf ( " Alias rid %u: " , rid ) ;
2002-08-29 12:00:15 +04:00
for ( i = 0 ; i < a - > num_members ; i + + ) {
2002-08-23 02:48:54 +04:00
d_printf ( " %s " , sid_string_static ( & a - > sids [ i ] . sid ) ) ;
}
d_printf ( " \n " ) ;
}
static void display_account_info ( uint32 rid , SAM_ACCOUNT_INFO * a )
{
fstring hex_nt_passwd , hex_lm_passwd ;
uchar lm_passwd [ 16 ] , nt_passwd [ 16 ] ;
/* Decode hashes from password hash */
sam_pwd_hash ( a - > user_rid , a - > pass . buf_lm_pwd , lm_passwd , 0 ) ;
sam_pwd_hash ( a - > user_rid , a - > pass . buf_nt_pwd , nt_passwd , 0 ) ;
/* Encode as strings */
smbpasswd_sethexpwd ( hex_lm_passwd , lm_passwd , a - > acb_info ) ;
smbpasswd_sethexpwd ( hex_nt_passwd , nt_passwd , a - > acb_info ) ;
printf ( " %s:%d:%s:%s:%s:LCT-0 \n " , unistr2_static ( & a - > uni_acct_name ) ,
a - > user_rid , hex_lm_passwd , hex_nt_passwd ,
smbpasswd_encode_acb_info ( a - > acb_info ) ) ;
}
2002-08-29 14:36:05 +04:00
static void display_domain_info ( SAM_DOMAIN_INFO * a )
{
d_printf ( " Domain name: %s \n " , unistr2_static ( & a - > uni_dom_name ) ) ;
}
static void display_group_info ( uint32 rid , SAM_GROUP_INFO * a )
{
d_printf ( " Group '%s' " , unistr2_static ( & a - > uni_grp_name ) ) ;
d_printf ( " desc='%s', rid=%u \n " , unistr2_static ( & a - > uni_grp_desc ) , rid ) ;
}
2002-08-23 02:48:54 +04:00
static void display_sam_entry ( SAM_DELTA_HDR * hdr_delta , SAM_DELTA_CTR * delta )
{
switch ( hdr_delta - > type ) {
case SAM_DELTA_ACCOUNT_INFO :
display_account_info ( hdr_delta - > target_rid , & delta - > account_info ) ;
break ;
case SAM_DELTA_GROUP_MEM :
display_group_mem_info ( hdr_delta - > target_rid , & delta - > grp_mem_info ) ;
break ;
case SAM_DELTA_ALIAS_INFO :
display_alias_info ( hdr_delta - > target_rid , & delta - > alias_info ) ;
break ;
case SAM_DELTA_ALIAS_MEM :
display_alias_mem ( hdr_delta - > target_rid , & delta - > als_mem_info ) ;
break ;
2002-08-29 14:36:05 +04:00
case SAM_DELTA_DOMAIN_INFO :
display_domain_info ( & delta - > domain_info ) ;
break ;
case SAM_DELTA_GROUP_INFO :
display_group_info ( hdr_delta - > target_rid , & delta - > group_info ) ;
break ;
2002-08-23 02:48:54 +04:00
default :
d_printf ( " Unknown delta record type %d \n " , hdr_delta - > type ) ;
break ;
}
}
2002-08-29 12:00:15 +04:00
static void dump_database ( struct cli_state * cli , unsigned db_type , DOM_CRED * ret_creds )
2002-08-23 02:48:54 +04:00
{
2002-11-02 06:47:48 +03:00
unsigned sync_context = 0 ;
2002-08-29 12:00:15 +04:00
NTSTATUS result ;
int i ;
TALLOC_CTX * mem_ctx ;
2002-08-23 02:48:54 +04:00
SAM_DELTA_HDR * hdr_deltas ;
SAM_DELTA_CTR * deltas ;
uint32 num_deltas ;
2002-08-29 12:00:15 +04:00
if ( ! ( mem_ctx = talloc_init ( ) ) ) {
return ;
}
d_printf ( " Dumping database %u \n " , db_type ) ;
do {
2002-11-02 06:47:48 +03:00
result = cli_netlogon_sam_sync ( cli , mem_ctx , ret_creds , db_type ,
sync_context ,
2002-08-29 12:00:15 +04:00
& num_deltas , & hdr_deltas , & deltas ) ;
clnt_deal_with_creds ( cli - > sess_key , & ( cli - > clnt_cred ) , ret_creds ) ;
for ( i = 0 ; i < num_deltas ; i + + ) {
display_sam_entry ( & hdr_deltas [ i ] , & deltas [ i ] ) ;
}
2002-11-02 06:47:48 +03:00
sync_context + = 1 ;
} while ( NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) ) ;
2002-08-29 12:00:15 +04:00
talloc_destroy ( mem_ctx ) ;
}
/* dump sam database via samsync rpc calls */
int rpc_samdump ( int argc , const char * * argv )
{
2002-08-23 02:48:54 +04:00
NTSTATUS result ;
struct cli_state * cli = NULL ;
uchar trust_password [ 16 ] ;
2002-08-29 12:00:15 +04:00
DOM_CRED ret_creds ;
2002-08-30 14:46:59 +04:00
uint32 neg_flags = 0x000001ff ;
2002-08-29 12:00:15 +04:00
ZERO_STRUCT ( ret_creds ) ;
2002-08-23 02:48:54 +04:00
/* Connect to remote machine */
if ( ! ( cli = net_make_ipc_connection ( NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC ) ) ) {
return 1 ;
}
2002-10-04 08:10:23 +04:00
if ( ! cli_nt_session_open ( cli , PI_NETLOGON ) ) {
2002-08-23 02:48:54 +04:00
DEBUG ( 0 , ( " Error connecting to NETLOGON pipe \n " ) ) ;
goto fail ;
}
if ( ! secrets_fetch_trust_account_password ( lp_workgroup ( ) , trust_password , NULL ) ) {
d_printf ( " Could not retrieve domain trust secret " ) ;
goto fail ;
}
2002-08-30 14:46:59 +04:00
result = cli_nt_setup_creds ( cli , SEC_CHAN_BDC , trust_password , & neg_flags , 2 ) ;
2002-08-23 02:48:54 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Failed to setup BDC creds \n " ) ;
goto fail ;
}
2002-08-29 12:00:15 +04:00
dump_database ( cli , SAM_DATABASE_DOMAIN , & ret_creds ) ;
dump_database ( cli , SAM_DATABASE_BUILTIN , & ret_creds ) ;
2002-09-22 14:30:00 +04:00
dump_database ( cli , SAM_DATABASE_PRIVS , & ret_creds ) ;
2002-08-23 02:48:54 +04:00
cli_nt_session_close ( cli ) ;
return 0 ;
fail :
if ( cli ) {
cli_nt_session_close ( cli ) ;
}
return - 1 ;
}
2002-09-18 10:34:10 +04:00
/* Convert a SAM_ACCOUNT_DELTA to a SAM_ACCOUNT. */
static NTSTATUS
sam_account_from_delta ( SAM_ACCOUNT * account , SAM_ACCOUNT_INFO * delta )
{
fstring s ;
2002-09-24 10:50:11 +04:00
uchar lm_passwd [ 16 ] , nt_passwd [ 16 ] ;
2002-09-18 10:34:10 +04:00
/* Username, fullname, home dir, dir drive, logon script, acct
desc , workstations , profile . */
unistr2_to_ascii ( s , & delta - > uni_acct_name , sizeof ( s ) - 1 ) ;
2002-11-02 06:47:48 +03:00
pdb_set_nt_username ( account , s , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
/* Unix username is the same - for sainity */
2002-11-02 06:47:48 +03:00
pdb_set_username ( account , s , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
unistr2_to_ascii ( s , & delta - > uni_full_name , sizeof ( s ) - 1 ) ;
2002-11-02 06:47:48 +03:00
pdb_set_fullname ( account , s , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
unistr2_to_ascii ( s , & delta - > uni_home_dir , sizeof ( s ) - 1 ) ;
2002-11-02 06:47:48 +03:00
pdb_set_homedir ( account , s , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
unistr2_to_ascii ( s , & delta - > uni_dir_drive , sizeof ( s ) - 1 ) ;
2002-11-02 06:47:48 +03:00
pdb_set_dir_drive ( account , s , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
unistr2_to_ascii ( s , & delta - > uni_logon_script , sizeof ( s ) - 1 ) ;
2002-11-02 06:47:48 +03:00
pdb_set_logon_script ( account , s , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
unistr2_to_ascii ( s , & delta - > uni_acct_desc , sizeof ( s ) - 1 ) ;
2002-11-02 06:47:48 +03:00
pdb_set_acct_desc ( account , s , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
unistr2_to_ascii ( s , & delta - > uni_workstations , sizeof ( s ) - 1 ) ;
2002-11-02 06:47:48 +03:00
pdb_set_workstations ( account , s , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
unistr2_to_ascii ( s , & delta - > uni_profile , sizeof ( s ) - 1 ) ;
2002-11-02 06:47:48 +03:00
pdb_set_profile_path ( account , s , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
/* User and group sid */
2002-11-02 06:47:48 +03:00
pdb_set_user_sid_from_rid ( account , delta - > user_rid , PDB_CHANGED ) ;
pdb_set_group_sid_from_rid ( account , delta - > group_rid , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
/* Logon and password information */
2002-11-02 06:47:48 +03:00
pdb_set_logon_time ( account , nt_time_to_unix ( & delta - > logon_time ) , PDB_CHANGED ) ;
2002-09-24 10:50:11 +04:00
pdb_set_logoff_time ( account , nt_time_to_unix ( & delta - > logoff_time ) ,
2002-11-02 06:47:48 +03:00
PDB_CHANGED ) ;
pdb_set_logon_divs ( account , delta - > logon_divs , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
/* TODO: logon hours */
/* TODO: bad password count */
/* TODO: logon count */
pdb_set_pass_last_set_time (
2002-11-02 06:47:48 +03:00
account , nt_time_to_unix ( & delta - > pwd_last_set_time ) , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
2002-11-02 06:47:48 +03:00
pdb_set_kickoff_time ( account , get_time_t_max ( ) , PDB_CHANGED ) ;
2002-09-24 10:50:11 +04:00
/* Decode hashes from password hash */
sam_pwd_hash ( delta - > user_rid , delta - > pass . buf_lm_pwd , lm_passwd , 0 ) ;
sam_pwd_hash ( delta - > user_rid , delta - > pass . buf_nt_pwd , nt_passwd , 0 ) ;
2002-11-02 06:47:48 +03:00
pdb_set_nt_passwd ( account , nt_passwd , PDB_CHANGED ) ;
pdb_set_lanman_passwd ( account , lm_passwd , PDB_CHANGED ) ;
2002-09-24 10:50:11 +04:00
2002-09-18 10:34:10 +04:00
/* TODO: account expiry time */
2002-11-02 06:47:48 +03:00
pdb_set_acct_ctrl ( account , delta - > acb_info , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
return NT_STATUS_OK ;
}
static NTSTATUS
fetch_account_info ( uint32 rid , SAM_ACCOUNT_INFO * delta )
{
NTSTATUS nt_ret ;
fstring account ;
pstring add_script ;
SAM_ACCOUNT * sam_account = NULL ;
2002-09-24 10:50:11 +04:00
GROUP_MAP map ;
struct group * grp ;
2002-09-18 10:34:10 +04:00
fstrcpy ( account , unistr2_static ( & delta - > uni_acct_name ) ) ;
d_printf ( " Creating account: %s \n " , account ) ;
if ( ! NT_STATUS_IS_OK ( nt_ret = pdb_init_sam ( & sam_account ) ) )
return nt_ret ;
if ( ! pdb_getsampwnam ( sam_account , account ) ) {
struct passwd * pw ;
2002-09-24 10:50:11 +04:00
pdb_free_sam ( & sam_account ) ;
2002-09-18 10:34:10 +04:00
/* Create appropriate user */
if ( delta - > acb_info & ACB_NORMAL ) {
pstrcpy ( add_script , lp_adduser_script ( ) ) ;
} else if ( ( delta - > acb_info & ACB_WSTRUST ) | |
( delta - > acb_info & ACB_SVRTRUST ) ) {
pstrcpy ( add_script , lp_addmachine_script ( ) ) ;
} else {
DEBUG ( 1 , ( " Unknown user type: %s \n " ,
smbpasswd_encode_acb_info ( delta - > acb_info ) ) ) ;
pdb_free_sam ( & sam_account ) ;
return NT_STATUS_NO_SUCH_USER ;
}
if ( * add_script ) {
int add_ret ;
all_string_sub ( add_script , " %u " , account ,
sizeof ( account ) ) ;
add_ret = smbrun ( add_script , NULL ) ;
DEBUG ( 1 , ( " fetch_account: Running the command `%s' "
" gave %d \n " , add_script , add_ret ) ) ;
}
pw = getpwnam_alloc ( account ) ;
if ( pw ) {
nt_ret = pdb_init_sam_pw ( & sam_account , pw ) ;
if ( ! NT_STATUS_IS_OK ( nt_ret ) ) {
passwd_free ( & pw ) ;
pdb_free_sam ( & sam_account ) ;
return nt_ret ;
}
passwd_free ( & pw ) ;
} else {
DEBUG ( 3 , ( " Could not create account %s \n " , account ) ) ;
pdb_free_sam ( & sam_account ) ;
return NT_STATUS_NO_SUCH_USER ;
}
}
sam_account_from_delta ( sam_account , delta ) ;
2002-09-24 10:50:11 +04:00
if ( ! pdb_add_sam_account ( sam_account ) ) {
DEBUG ( 1 , ( " SAM Account for %s already existed, updating \n " ,
account ) ) ;
pdb_update_sam_account ( sam_account ) ;
}
2002-11-02 06:47:48 +03:00
if ( ! pdb_getgrsid ( & map , * pdb_get_group_sid ( sam_account ) , False ) ) {
2002-09-24 10:50:11 +04:00
DEBUG ( 0 , ( " Primary group of %s has no mapping! \n " ,
pdb_get_username ( sam_account ) ) ) ;
pdb_free_sam ( & sam_account ) ;
return NT_STATUS_NO_SUCH_GROUP ;
}
if ( ! ( grp = getgrgid ( map . gid ) ) ) {
DEBUG ( 0 , ( " Could not find unix group %d \n " , map . gid ) ) ;
pdb_free_sam ( & sam_account ) ;
return NT_STATUS_NO_SUCH_GROUP ;
}
smb_set_primary_group ( grp - > gr_name , pdb_get_username ( sam_account ) ) ;
2002-09-18 10:34:10 +04:00
pdb_free_sam ( & sam_account ) ;
return NT_STATUS_OK ;
}
static NTSTATUS
fetch_group_info ( uint32 rid , SAM_GROUP_INFO * delta )
{
fstring name ;
fstring comment ;
2002-09-24 10:50:11 +04:00
struct group * grp = NULL ;
2002-09-18 10:34:10 +04:00
DOM_SID group_sid ;
fstring sid_string ;
GROUP_MAP map ;
2002-11-02 06:47:48 +03:00
BOOL insert = True ;
2002-09-18 10:34:10 +04:00
unistr2_to_ascii ( name , & delta - > uni_grp_name , sizeof ( name ) - 1 ) ;
unistr2_to_ascii ( comment , & delta - > uni_grp_desc , sizeof ( comment ) - 1 ) ;
/* add the group to the mapping table */
sid_copy ( & group_sid , get_global_sam_sid ( ) ) ;
sid_append_rid ( & group_sid , rid ) ;
sid_to_string ( sid_string , & group_sid ) ;
2002-11-02 06:47:48 +03:00
if ( pdb_getgrsid ( & map , group_sid , False ) ) {
2002-09-24 10:50:11 +04:00
grp = getgrgid ( map . gid ) ;
2002-11-02 06:47:48 +03:00
insert = False ;
2002-09-24 10:50:11 +04:00
}
if ( grp = = NULL )
{
2002-10-01 22:26:00 +04:00
gid_t gid ;
2002-09-24 10:50:11 +04:00
/* No group found from mapping, find it from its name. */
if ( ( grp = getgrnam ( name ) ) = = NULL ) {
/* No appropriate group found, create one */
d_printf ( " Creating unix group: '%s' \n " , name ) ;
2002-10-01 22:26:00 +04:00
if ( smb_create_group ( name , & gid ) ! = 0 )
return NT_STATUS_ACCESS_DENIED ;
if ( ( grp = getgrgid ( gid ) ) = = NULL )
2002-09-24 10:50:11 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
2002-09-18 10:34:10 +04:00
}
map . gid = grp - > gr_gid ;
map . sid = group_sid ;
map . sid_name_use = SID_NAME_DOM_GRP ;
fstrcpy ( map . nt_name , name ) ;
fstrcpy ( map . comment , comment ) ;
map . priv_set . count = 0 ;
map . priv_set . set = NULL ;
2002-11-02 06:47:48 +03:00
if ( insert )
pdb_add_group_mapping_entry ( & map ) ;
else
pdb_update_group_mapping_entry ( & map ) ;
2002-09-18 10:34:10 +04:00
return NT_STATUS_OK ;
}
2002-09-24 10:50:11 +04:00
static NTSTATUS
fetch_group_mem_info ( uint32 rid , SAM_GROUP_MEM_INFO * delta )
{
int i ;
TALLOC_CTX * t = NULL ;
char * * nt_members = NULL ;
char * * unix_members ;
DOM_SID group_sid ;
GROUP_MAP map ;
struct group * grp ;
if ( delta - > num_members = = 0 ) {
return NT_STATUS_OK ;
}
sid_copy ( & group_sid , get_global_sam_sid ( ) ) ;
sid_append_rid ( & group_sid , rid ) ;
if ( ! get_domain_group_from_sid ( group_sid , & map , False ) ) {
DEBUG ( 0 , ( " Could not find global group %d \n " , rid ) ) ;
return NT_STATUS_NO_SUCH_GROUP ;
}
if ( ! ( grp = getgrgid ( map . gid ) ) ) {
DEBUG ( 0 , ( " Could not find unix group %d \n " , map . gid ) ) ;
return NT_STATUS_NO_SUCH_GROUP ;
}
d_printf ( " Group members of %s: " , grp - > gr_name ) ;
if ( ! ( t = talloc_init ( ) ) ) {
DEBUG ( 0 , ( " could not talloc_init \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
nt_members = talloc_zero ( t , sizeof ( char * ) * delta - > num_members ) ;
for ( i = 0 ; i < delta - > num_members ; i + + ) {
NTSTATUS nt_status ;
SAM_ACCOUNT * member = NULL ;
DOM_SID member_sid ;
if ( ! NT_STATUS_IS_OK ( nt_status = pdb_init_sam_talloc ( t , & member ) ) ) {
talloc_destroy ( t ) ;
return nt_status ;
}
sid_copy ( & member_sid , get_global_sam_sid ( ) ) ;
sid_append_rid ( & member_sid , delta - > rids [ i ] ) ;
if ( ! pdb_getsampwsid ( member , & member_sid ) ) {
DEBUG ( 1 , ( " Found bogus group member: %d \n " ,
delta - > rids [ i ] ) ) ;
pdb_free_sam ( & member ) ;
continue ;
}
if ( pdb_get_group_rid ( member ) = = rid ) {
d_printf ( " %s(primary), " , pdb_get_username ( member ) ) ;
pdb_free_sam ( & member ) ;
continue ;
}
d_printf ( " %s, " , pdb_get_username ( member ) ) ;
nt_members [ i ] = talloc_strdup ( t , pdb_get_username ( member ) ) ;
pdb_free_sam ( & member ) ;
}
d_printf ( " \n " ) ;
unix_members = grp - > gr_mem ;
while ( * unix_members ) {
BOOL is_nt_member = False ;
for ( i = 0 ; i < delta - > num_members ; i + + ) {
if ( nt_members [ i ] = = NULL ) {
/* This was a primary group */
continue ;
}
if ( strcmp ( * unix_members , nt_members [ i ] ) = = 0 ) {
is_nt_member = True ;
break ;
}
}
if ( ! is_nt_member ) {
/* We look at a unix group member that is not
an nt group member . So , remove it . NT is
boss here . */
smb_delete_user_group ( grp - > gr_name , * unix_members ) ;
}
unix_members + = 1 ;
}
for ( i = 0 ; i < delta - > num_members ; i + + ) {
BOOL is_unix_member = False ;
if ( nt_members [ i ] = = NULL ) {
/* This was the primary group */
continue ;
}
unix_members = grp - > gr_mem ;
while ( * unix_members ) {
if ( strcmp ( * unix_members , nt_members [ i ] ) = = 0 ) {
is_unix_member = True ;
break ;
}
unix_members + = 1 ;
}
if ( ! is_unix_member ) {
/* We look at a nt group member that is not a
unix group member currently . So , add the nt
group member . */
smb_add_user_group ( grp - > gr_name , nt_members [ i ] ) ;
}
}
talloc_destroy ( t ) ;
return NT_STATUS_OK ;
}
static NTSTATUS fetch_alias_info ( uint32 rid , SAM_ALIAS_INFO * delta ,
DOM_SID dom_sid )
{
fstring name ;
fstring comment ;
struct group * grp = NULL ;
DOM_SID alias_sid ;
fstring sid_string ;
GROUP_MAP map ;
2002-11-02 06:47:48 +03:00
BOOL insert = True ;
2002-09-24 10:50:11 +04:00
unistr2_to_ascii ( name , & delta - > uni_als_name , sizeof ( name ) - 1 ) ;
unistr2_to_ascii ( comment , & delta - > uni_als_desc , sizeof ( comment ) - 1 ) ;
/* Find out whether the group is already mapped */
sid_copy ( & alias_sid , & dom_sid ) ;
sid_append_rid ( & alias_sid , rid ) ;
sid_to_string ( sid_string , & alias_sid ) ;
2002-11-02 06:47:48 +03:00
if ( pdb_getgrsid ( & map , alias_sid , False ) ) {
2002-09-24 10:50:11 +04:00
grp = getgrgid ( map . gid ) ;
2002-11-02 06:47:48 +03:00
insert = False ;
2002-09-24 10:50:11 +04:00
}
if ( grp = = NULL ) {
2002-10-01 22:26:00 +04:00
gid_t gid ;
2002-09-24 10:50:11 +04:00
/* No group found from mapping, find it from its name. */
if ( ( grp = getgrnam ( name ) ) = = NULL ) {
/* No appropriate group found, create one */
d_printf ( " Creating unix group: '%s' \n " , name ) ;
2002-10-01 22:26:00 +04:00
if ( smb_create_group ( name , & gid ) ! = 0 )
return NT_STATUS_ACCESS_DENIED ;
if ( ( grp = getgrgid ( gid ) ) = = NULL )
2002-09-24 10:50:11 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
}
map . gid = grp - > gr_gid ;
map . sid = alias_sid ;
2002-10-01 22:26:00 +04:00
if ( sid_equal ( & dom_sid , & global_sid_Builtin ) )
map . sid_name_use = SID_NAME_WKN_GRP ;
else
map . sid_name_use = SID_NAME_ALIAS ;
2002-09-24 10:50:11 +04:00
fstrcpy ( map . nt_name , name ) ;
fstrcpy ( map . comment , comment ) ;
map . priv_set . count = 0 ;
map . priv_set . set = NULL ;
2002-11-02 06:47:48 +03:00
if ( insert )
pdb_add_group_mapping_entry ( & map ) ;
else
pdb_update_group_mapping_entry ( & map ) ;
2002-09-24 10:50:11 +04:00
return NT_STATUS_OK ;
}
static NTSTATUS
fetch_alias_mem ( uint32 rid , SAM_ALIAS_MEM_INFO * delta , DOM_SID dom_sid )
{
return NT_STATUS_OK ;
}
2002-09-18 10:34:10 +04:00
static void
2002-09-24 10:50:11 +04:00
fetch_sam_entry ( SAM_DELTA_HDR * hdr_delta , SAM_DELTA_CTR * delta ,
DOM_SID dom_sid )
2002-09-18 10:34:10 +04:00
{
switch ( hdr_delta - > type ) {
case SAM_DELTA_ACCOUNT_INFO :
fetch_account_info ( hdr_delta - > target_rid ,
& delta - > account_info ) ;
break ;
case SAM_DELTA_GROUP_INFO :
fetch_group_info ( hdr_delta - > target_rid ,
& delta - > group_info ) ;
break ;
2002-09-24 10:50:11 +04:00
case SAM_DELTA_GROUP_MEM :
fetch_group_mem_info ( hdr_delta - > target_rid ,
& delta - > grp_mem_info ) ;
break ;
case SAM_DELTA_ALIAS_INFO :
fetch_alias_info ( hdr_delta - > target_rid ,
& delta - > alias_info , dom_sid ) ;
break ;
case SAM_DELTA_ALIAS_MEM :
fetch_alias_mem ( hdr_delta - > target_rid ,
& delta - > als_mem_info , dom_sid ) ;
break ;
2002-09-18 10:34:10 +04:00
default :
d_printf ( " Unknown delta record type %d \n " , hdr_delta - > type ) ;
break ;
}
}
static void
2002-09-24 10:50:11 +04:00
fetch_database ( struct cli_state * cli , unsigned db_type , DOM_CRED * ret_creds ,
DOM_SID dom_sid )
2002-09-18 10:34:10 +04:00
{
2002-11-02 06:47:48 +03:00
unsigned sync_context = 0 ;
2002-09-18 10:34:10 +04:00
NTSTATUS result ;
int i ;
TALLOC_CTX * mem_ctx ;
SAM_DELTA_HDR * hdr_deltas ;
SAM_DELTA_CTR * deltas ;
uint32 num_deltas ;
if ( ! ( mem_ctx = talloc_init ( ) ) ) {
return ;
}
d_printf ( " Fetching database %u \n " , db_type ) ;
do {
result = cli_netlogon_sam_sync ( cli , mem_ctx , ret_creds ,
2002-11-02 06:47:48 +03:00
db_type , sync_context ,
2002-09-18 10:34:10 +04:00
& num_deltas ,
& hdr_deltas , & deltas ) ;
clnt_deal_with_creds ( cli - > sess_key , & ( cli - > clnt_cred ) ,
ret_creds ) ;
for ( i = 0 ; i < num_deltas ; i + + ) {
2002-09-24 10:50:11 +04:00
fetch_sam_entry ( & hdr_deltas [ i ] , & deltas [ i ] , dom_sid ) ;
2002-09-18 10:34:10 +04:00
}
2002-11-02 06:47:48 +03:00
sync_context + = 1 ;
} while ( NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) ) ;
2002-09-18 10:34:10 +04:00
talloc_destroy ( mem_ctx ) ;
}
/* dump sam database via samsync rpc calls */
int rpc_vampire ( int argc , const char * * argv )
{
NTSTATUS result ;
struct cli_state * cli = NULL ;
uchar trust_password [ 16 ] ;
DOM_CRED ret_creds ;
uint32 neg_flags = 0x000001ff ;
2002-09-24 10:50:11 +04:00
DOM_SID dom_sid ;
2002-09-18 10:34:10 +04:00
ZERO_STRUCT ( ret_creds ) ;
/* Connect to remote machine */
if ( ! ( cli = net_make_ipc_connection ( NET_FLAGS_ANONYMOUS |
NET_FLAGS_PDC ) ) ) {
return 1 ;
}
2002-10-04 08:10:23 +04:00
if ( ! cli_nt_session_open ( cli , PI_NETLOGON ) ) {
2002-09-18 10:34:10 +04:00
DEBUG ( 0 , ( " Error connecting to NETLOGON pipe \n " ) ) ;
goto fail ;
}
if ( ! secrets_fetch_trust_account_password ( lp_workgroup ( ) ,
trust_password , NULL ) ) {
d_printf ( " Could not retrieve domain trust secret " ) ;
goto fail ;
}
result = cli_nt_setup_creds ( cli , SEC_CHAN_BDC , trust_password ,
& neg_flags , 2 ) ;
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Failed to setup BDC creds \n " ) ;
goto fail ;
}
2002-09-24 10:50:11 +04:00
dom_sid = * get_global_sam_sid ( ) ;
fetch_database ( cli , SAM_DATABASE_DOMAIN , & ret_creds , dom_sid ) ;
sid_copy ( & dom_sid , & global_sid_Builtin ) ;
fetch_database ( cli , SAM_DATABASE_BUILTIN , & ret_creds , dom_sid ) ;
2002-09-18 10:34:10 +04:00
/* Currently we crash on PRIVS somewhere in unmarshalling */
/* Dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); */
cli_nt_session_close ( cli ) ;
return 0 ;
fail :
if ( cli ) {
cli_nt_session_close ( cli ) ;
}
return - 1 ;
}