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
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"
2004-10-07 08:01:18 +04:00
# include "utils/net.h"
2002-08-23 02:48:54 +04:00
2005-07-07 01:02:43 +04:00
/* uid's and gid's for writing deltas to ldif */
static uint32 ldif_gid = 999 ;
static uint32 ldif_uid = 999 ;
/* Kkeep track of ldap initialization */
static int init_ldap = 1 ;
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 " ) ;
}
2004-12-20 15:52:33 +03:00
static const char * display_time ( NTTIME * nttime )
{
static fstring string ;
float high ;
float low ;
int sec ;
int days , hours , mins , secs ;
int offset = 1 ;
if ( nttime - > high = = 0 & & nttime - > low = = 0 )
return " Now " ;
if ( nttime - > high = = 0x80000000 & & nttime - > low = = 0 )
return " Never " ;
high = 65536 ;
high = high / 10000 ;
high = high * 65536 ;
high = high / 1000 ;
high = high * ( ~ nttime - > high ) ;
low = ~ nttime - > low ;
low = low / ( 1000 * 1000 * 10 ) ;
sec = high + low ;
sec + = offset ;
days = sec / ( 60 * 60 * 24 ) ;
hours = ( sec - ( days * 60 * 60 * 24 ) ) / ( 60 * 60 ) ;
mins = ( sec - ( days * 60 * 60 * 24 ) - ( hours * 60 * 60 ) ) / 60 ;
secs = sec - ( days * 60 * 60 * 24 ) - ( hours * 60 * 60 ) - ( mins * 60 ) ;
fstr_sprintf ( string , " %u days, %u hours, %u minutes, %u seconds " , days , hours , mins , secs ) ;
return ( string ) ;
}
2002-08-23 02:48:54 +04:00
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 ] ;
2002-11-10 06:07:19 +03:00
static uchar zero_buf [ 16 ] ;
2002-08-23 02:48:54 +04:00
2002-11-10 06:07:19 +03:00
/* Decode hashes from password hash (if they are not NULL) */
2002-08-23 02:48:54 +04:00
2002-11-10 06:07:19 +03:00
if ( memcmp ( a - > pass . buf_lm_pwd , zero_buf , 16 ) ! = 0 ) {
sam_pwd_hash ( a - > user_rid , a - > pass . buf_lm_pwd , lm_passwd , 0 ) ;
2004-02-08 11:38:42 +03:00
pdb_sethexpwd ( hex_lm_passwd , lm_passwd , a - > acb_info ) ;
2002-11-10 06:07:19 +03:00
} else {
2004-02-08 11:38:42 +03:00
pdb_sethexpwd ( hex_lm_passwd , NULL , 0 ) ;
2002-11-10 06:07:19 +03:00
}
if ( memcmp ( a - > pass . buf_nt_pwd , zero_buf , 16 ) ! = 0 ) {
sam_pwd_hash ( a - > user_rid , a - > pass . buf_nt_pwd , nt_passwd , 0 ) ;
2004-02-08 11:38:42 +03:00
pdb_sethexpwd ( hex_nt_passwd , nt_passwd , a - > acb_info ) ;
2002-11-10 06:07:19 +03:00
} else {
2004-02-08 11:38:42 +03:00
pdb_sethexpwd ( hex_nt_passwd , NULL , 0 ) ;
2002-11-10 06:07:19 +03:00
}
2002-08-23 02:48:54 +04:00
printf ( " %s:%d:%s:%s:%s:LCT-0 \n " , unistr2_static ( & a - > uni_acct_name ) ,
a - > user_rid , hex_lm_passwd , hex_nt_passwd ,
2004-02-08 11:38:42 +03:00
pdb_encode_acct_ctrl ( a - > acb_info , NEW_PW_FORMAT_SPACE_PADDED_LEN ) ) ;
2002-08-23 02:48:54 +04:00
}
2002-08-29 14:36:05 +04:00
static void display_domain_info ( SAM_DOMAIN_INFO * a )
{
2004-12-20 15:52:33 +03:00
time_t u_logout ;
u_logout = nt_time_to_unix_abs ( ( NTTIME * ) & a - > force_logoff ) ;
2002-08-29 14:36:05 +04:00
d_printf ( " Domain name: %s \n " , unistr2_static ( & a - > uni_dom_name ) ) ;
2004-12-20 15:52:33 +03:00
d_printf ( " Minimal Password Length: %d \n " , a - > min_pwd_len ) ;
d_printf ( " Password History Length: %d \n " , a - > pwd_history_len ) ;
d_printf ( " Force Logoff: %d \n " , ( int ) u_logout ) ;
d_printf ( " Max Password Age: %s \n " , display_time ( ( NTTIME * ) & a - > max_pwd_age ) ) ;
d_printf ( " Min Password Age: %s \n " , display_time ( ( NTTIME * ) & a - > min_pwd_age ) ) ;
d_printf ( " Lockout Time: %s \n " , display_time ( ( NTTIME * ) & a - > account_lockout . lockout_duration ) ) ;
d_printf ( " Lockout Reset Time: %s \n " , display_time ( ( NTTIME * ) & a - > account_lockout . reset_count ) ) ;
d_printf ( " Bad Attempt Lockout: %d \n " , a - > account_lockout . bad_attempt_lockout ) ;
d_printf ( " User must logon to change password: %d \n " , a - > logon_chgpass ) ;
2002-08-29 14:36:05 +04:00
}
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 ;
2003-03-23 05:22:41 +03:00
/* The following types are recognised but not handled */
case SAM_DELTA_RENAME_GROUP :
d_printf ( " SAM_DELTA_RENAME_GROUP not handled \n " ) ;
break ;
case SAM_DELTA_RENAME_USER :
d_printf ( " SAM_DELTA_RENAME_USER not handled \n " ) ;
break ;
case SAM_DELTA_RENAME_ALIAS :
d_printf ( " SAM_DELTA_RENAME_ALIAS not handled \n " ) ;
break ;
case SAM_DELTA_POLICY_INFO :
d_printf ( " SAM_DELTA_POLICY_INFO not handled \n " ) ;
break ;
case SAM_DELTA_TRUST_DOMS :
d_printf ( " SAM_DELTA_TRUST_DOMS not handled \n " ) ;
break ;
case SAM_DELTA_PRIVS_INFO :
d_printf ( " SAM_DELTA_PRIVS_INFO not handled \n " ) ;
break ;
case SAM_DELTA_SECRET_INFO :
d_printf ( " SAM_DELTA_SECRET_INFO not handled \n " ) ;
break ;
case SAM_DELTA_DELETE_GROUP :
d_printf ( " SAM_DELTA_DELETE_GROUP not handled \n " ) ;
break ;
case SAM_DELTA_DELETE_USER :
d_printf ( " SAM_DELTA_DELETE_USER not handled \n " ) ;
break ;
case SAM_DELTA_MODIFIED_COUNT :
d_printf ( " SAM_DELTA_MODIFIED_COUNT not handled \n " ) ;
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
2002-12-20 23:21:31 +03:00
if ( ! ( mem_ctx = talloc_init ( " dump_database " ) ) ) {
2002-08-29 12:00:15 +04:00
return ;
}
2003-03-23 05:22:41 +03:00
switch ( db_type ) {
case SAM_DATABASE_DOMAIN :
d_printf ( " Dumping DOMAIN database \n " ) ;
break ;
case SAM_DATABASE_BUILTIN :
d_printf ( " Dumping BUILTIN database \n " ) ;
break ;
case SAM_DATABASE_PRIVS :
d_printf ( " Dumping PRIVS databases \n " ) ;
break ;
default :
d_printf ( " Dumping unknown database type %u \n " , db_type ) ;
break ;
}
2002-08-29 12:00:15 +04:00
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 ) ;
2003-10-14 07:50:27 +04:00
if ( NT_STATUS_IS_ERR ( result ) )
break ;
2002-08-29 12:00:15 +04:00
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 */
2004-02-08 13:59:09 +03:00
NTSTATUS rpc_samdump_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli , TALLOC_CTX * mem_ctx ,
int argc , const char * * argv )
2002-08-29 12:00:15 +04:00
{
2004-02-08 13:59:09 +03:00
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
2002-08-23 02:48:54 +04:00
uchar trust_password [ 16 ] ;
2002-08-29 12:00:15 +04:00
DOM_CRED ret_creds ;
2003-04-21 18:09:03 +04:00
uint32 sec_channel ;
2002-08-29 12:00:15 +04:00
ZERO_STRUCT ( ret_creds ) ;
2002-08-23 02:48:54 +04:00
2004-02-08 13:59:09 +03:00
fstrcpy ( cli - > domain , domain_name ) ;
2003-05-08 12:02:52 +04:00
2004-02-08 13:59:09 +03:00
if ( ! secrets_fetch_trust_account_password ( domain_name ,
2003-04-09 19:54:17 +04:00
trust_password ,
2003-04-21 18:09:03 +04:00
NULL , & sec_channel ) ) {
2003-04-09 19:54:17 +04:00
DEBUG ( 0 , ( " Could not fetch trust account password \n " ) ) ;
2002-08-23 02:48:54 +04:00
goto fail ;
}
2003-04-09 19:54:17 +04:00
2004-02-08 13:59:09 +03:00
if ( ! NT_STATUS_IS_OK ( nt_status = cli_nt_establish_netlogon ( cli , sec_channel ,
trust_password ) ) ) {
2003-04-09 19:54:17 +04:00
DEBUG ( 0 , ( " Error connecting to NETLOGON pipe \n " ) ) ;
2002-08-23 02:48:54 +04:00
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
2004-02-08 13:59:09 +03:00
nt_status = NT_STATUS_OK ;
2002-08-23 02:48:54 +04:00
fail :
2004-02-08 13:59:09 +03:00
cli_nt_session_close ( cli ) ;
return nt_status ;
2002-08-23 02:48:54 +04:00
}
2002-09-18 10:34:10 +04:00
/* Convert a SAM_ACCOUNT_DELTA to a SAM_ACCOUNT. */
2003-03-23 05:22:41 +03:00
# define STRING_CHANGED (old_string && !new_string) ||\
( ! old_string & & new_string ) | | \
( old_string & & new_string & & ( strcmp ( old_string , new_string ) ! = 0 ) )
2002-09-18 10:34:10 +04:00
static NTSTATUS
sam_account_from_delta ( SAM_ACCOUNT * account , SAM_ACCOUNT_INFO * delta )
{
2003-03-23 05:22:41 +03:00
const char * old_string , * new_string ;
time_t unix_time , stored_time ;
2002-09-24 10:50:11 +04:00
uchar lm_passwd [ 16 ] , nt_passwd [ 16 ] ;
2002-11-10 06:07:19 +03:00
static uchar zero_buf [ 16 ] ;
2002-09-18 10:34:10 +04:00
/* Username, fullname, home dir, dir drive, logon script, acct
desc , workstations , profile . */
2003-03-23 05:22:41 +03:00
if ( delta - > hdr_acct_name . buffer ) {
old_string = pdb_get_nt_username ( account ) ;
new_string = unistr2_static ( & delta - > uni_acct_name ) ;
if ( STRING_CHANGED ) {
pdb_set_nt_username ( account , new_string , PDB_CHANGED ) ;
}
/* Unix username is the same - for sanity */
old_string = pdb_get_username ( account ) ;
if ( STRING_CHANGED ) {
pdb_set_username ( account , new_string , PDB_CHANGED ) ;
}
}
if ( delta - > hdr_full_name . buffer ) {
old_string = pdb_get_fullname ( account ) ;
new_string = unistr2_static ( & delta - > uni_full_name ) ;
if ( STRING_CHANGED )
pdb_set_fullname ( account , new_string , PDB_CHANGED ) ;
}
2002-09-18 10:34:10 +04:00
2003-03-23 05:22:41 +03:00
if ( delta - > hdr_home_dir . buffer ) {
old_string = pdb_get_homedir ( account ) ;
new_string = unistr2_static ( & delta - > uni_home_dir ) ;
if ( STRING_CHANGED )
pdb_set_homedir ( account , new_string , PDB_CHANGED ) ;
}
2002-09-18 10:34:10 +04:00
2003-03-23 05:22:41 +03:00
if ( delta - > hdr_dir_drive . buffer ) {
old_string = pdb_get_dir_drive ( account ) ;
new_string = unistr2_static ( & delta - > uni_dir_drive ) ;
2002-09-18 10:34:10 +04:00
2003-03-23 05:22:41 +03:00
if ( STRING_CHANGED )
pdb_set_dir_drive ( account , new_string , PDB_CHANGED ) ;
}
2002-09-18 10:34:10 +04:00
2003-03-23 05:22:41 +03:00
if ( delta - > hdr_logon_script . buffer ) {
old_string = pdb_get_logon_script ( account ) ;
new_string = unistr2_static ( & delta - > uni_logon_script ) ;
2002-09-18 10:34:10 +04:00
2003-03-23 05:22:41 +03:00
if ( STRING_CHANGED )
pdb_set_logon_script ( account , new_string , PDB_CHANGED ) ;
}
2002-09-18 10:34:10 +04:00
2003-03-23 05:22:41 +03:00
if ( delta - > hdr_acct_desc . buffer ) {
old_string = pdb_get_acct_desc ( account ) ;
new_string = unistr2_static ( & delta - > uni_acct_desc ) ;
2002-09-18 10:34:10 +04:00
2003-03-23 05:22:41 +03:00
if ( STRING_CHANGED )
pdb_set_acct_desc ( account , new_string , PDB_CHANGED ) ;
}
2002-09-18 10:34:10 +04:00
2003-03-23 05:22:41 +03:00
if ( delta - > hdr_workstations . buffer ) {
old_string = pdb_get_workstations ( account ) ;
new_string = unistr2_static ( & delta - > uni_workstations ) ;
2002-09-18 10:34:10 +04:00
2003-03-23 05:22:41 +03:00
if ( STRING_CHANGED )
pdb_set_workstations ( account , new_string , PDB_CHANGED ) ;
}
2002-09-18 10:34:10 +04:00
2003-03-23 05:22:41 +03:00
if ( delta - > hdr_profile . buffer ) {
old_string = pdb_get_profile_path ( account ) ;
new_string = unistr2_static ( & delta - > uni_profile ) ;
if ( STRING_CHANGED )
pdb_set_profile_path ( account , new_string , PDB_CHANGED ) ;
}
2004-12-10 12:45:03 +03:00
if ( delta - > hdr_parameters . buffer ) {
2004-12-24 03:38:22 +03:00
DATA_BLOB mung ;
2004-12-10 12:45:03 +03:00
old_string = pdb_get_munged_dial ( account ) ;
2004-12-24 03:56:30 +03:00
mung . length = delta - > hdr_parameters . uni_str_len ;
2004-12-24 03:38:22 +03:00
mung . data = ( uint8 * ) delta - > uni_parameters . buffer ;
new_string = ( mung . length = = 0 ) ? NULL : base64_encode_data_blob ( mung ) ;
2004-12-10 12:45:03 +03:00
if ( STRING_CHANGED )
pdb_set_munged_dial ( account , new_string , PDB_CHANGED ) ;
}
2003-03-23 05:22:41 +03:00
/* User and group sid */
if ( pdb_get_user_rid ( account ) ! = delta - > user_rid )
pdb_set_user_sid_from_rid ( account , delta - > user_rid , PDB_CHANGED ) ;
if ( pdb_get_group_rid ( account ) ! = delta - > group_rid )
pdb_set_group_sid_from_rid ( account , delta - > group_rid , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
/* Logon and password information */
2003-03-23 05:22:41 +03:00
if ( ! nt_time_is_zero ( & delta - > logon_time ) ) {
unix_time = nt_time_to_unix ( & delta - > logon_time ) ;
stored_time = pdb_get_logon_time ( account ) ;
if ( stored_time ! = unix_time )
pdb_set_logon_time ( account , unix_time , PDB_CHANGED ) ;
}
2002-09-18 10:34:10 +04:00
2003-03-23 05:22:41 +03:00
if ( ! nt_time_is_zero ( & delta - > logoff_time ) ) {
unix_time = nt_time_to_unix ( & delta - > logoff_time ) ;
stored_time = pdb_get_logoff_time ( account ) ;
if ( stored_time ! = unix_time )
pdb_set_logoff_time ( account , unix_time , PDB_CHANGED ) ;
}
2004-12-24 03:08:15 +03:00
/* Logon Divs */
2003-03-23 05:22:41 +03:00
if ( pdb_get_logon_divs ( account ) ! = delta - > logon_divs )
pdb_set_logon_divs ( account , delta - > logon_divs , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
2004-12-24 03:08:15 +03:00
/* Max Logon Hours */
if ( delta - > unknown1 ! = pdb_get_unknown_6 ( account ) ) {
pdb_set_unknown_6 ( account , delta - > unknown1 , PDB_CHANGED ) ;
}
/* Logon Hours Len */
if ( delta - > buf_logon_hrs . buf_len ! = pdb_get_hours_len ( account ) ) {
pdb_set_hours_len ( account , delta - > buf_logon_hrs . buf_len , PDB_CHANGED ) ;
}
/* Logon Hours */
if ( delta - > buf_logon_hrs . buffer ) {
2005-06-25 00:25:18 +04:00
pstring oldstr , newstr ;
pdb_sethexhours ( oldstr , pdb_get_hours ( account ) ) ;
pdb_sethexhours ( newstr , delta - > buf_logon_hrs . buffer ) ;
if ( ! strequal ( oldstr , newstr ) )
2005-07-13 03:02:31 +04:00
pdb_set_hours ( account , ( const uint8 * ) delta - > buf_logon_hrs . buffer , PDB_CHANGED ) ;
2004-12-24 03:08:15 +03:00
}
2004-12-10 13:42:47 +03:00
if ( pdb_get_bad_password_count ( account ) ! = delta - > bad_pwd_count )
pdb_set_bad_password_count ( account , delta - > bad_pwd_count , PDB_CHANGED ) ;
if ( pdb_get_logon_count ( account ) ! = delta - > logon_count )
pdb_set_logon_count ( account , delta - > logon_count , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
2003-03-23 05:22:41 +03:00
if ( ! nt_time_is_zero ( & delta - > pwd_last_set_time ) ) {
unix_time = nt_time_to_unix ( & delta - > pwd_last_set_time ) ;
stored_time = pdb_get_pass_last_set_time ( account ) ;
if ( stored_time ! = unix_time )
pdb_set_pass_last_set_time ( account , unix_time , PDB_CHANGED ) ;
2005-01-05 19:02:56 +03:00
} else {
/* no last set time, make it now */
pdb_set_pass_last_set_time ( account , time ( NULL ) , PDB_CHANGED ) ;
2003-03-23 05:22:41 +03:00
}
2002-09-18 10:34:10 +04:00
2003-03-23 05:22:41 +03:00
#if 0
2003-04-14 08:00:37 +04:00
/* No kickoff time in the delta? */
2003-03-23 05:22:41 +03:00
if ( ! nt_time_is_zero ( & delta - > kickoff_time ) ) {
unix_time = nt_time_to_unix ( & delta - > kickoff_time ) ;
stored_time = pdb_get_kickoff_time ( account ) ;
if ( stored_time ! = unix_time )
pdb_set_kickoff_time ( account , unix_time , PDB_CHANGED ) ;
}
# endif
2002-09-24 10:50:11 +04:00
2002-11-10 06:07:19 +03:00
/* Decode hashes from password hash
Note that win2000 may send us all zeros for the hashes if it doesn ' t
think this channel is secure enough - don ' t set the passwords at all
in that case
2003-03-23 05:22:41 +03:00
*/
2002-11-10 06:07:19 +03:00
if ( memcmp ( delta - > pass . buf_lm_pwd , zero_buf , 16 ) ! = 0 ) {
sam_pwd_hash ( delta - > user_rid , delta - > pass . buf_lm_pwd , lm_passwd , 0 ) ;
pdb_set_lanman_passwd ( account , lm_passwd , PDB_CHANGED ) ;
}
if ( memcmp ( delta - > pass . buf_nt_pwd , zero_buf , 16 ) ! = 0 ) {
sam_pwd_hash ( delta - > user_rid , delta - > pass . buf_nt_pwd , nt_passwd , 0 ) ;
pdb_set_nt_passwd ( account , nt_passwd , PDB_CHANGED ) ;
}
2002-09-24 10:50:11 +04:00
2002-09-18 10:34:10 +04:00
/* TODO: account expiry time */
2003-03-23 05:22:41 +03:00
if ( pdb_get_acct_ctrl ( account ) ! = delta - > acb_info )
pdb_set_acct_ctrl ( account , delta - > acb_info , PDB_CHANGED ) ;
2003-03-30 20:46:04 +04:00
pdb_set_domain ( account , lp_workgroup ( ) , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
return NT_STATUS_OK ;
}
2003-07-27 04:20:45 +04:00
static NTSTATUS fetch_account_info ( uint32 rid , SAM_ACCOUNT_INFO * delta )
2002-09-18 10:34:10 +04:00
{
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 ;
2003-07-05 13:46:12 +04:00
DOM_SID user_sid ;
DOM_SID group_sid ;
2003-06-14 04:49:02 +04:00
struct passwd * passwd ;
2003-07-05 14:39:41 +04:00
fstring sid_string ;
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 ;
2003-06-14 04:49:02 +04:00
if ( ! ( passwd = Get_Pwnam ( 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 ) | |
2003-03-23 05:22:41 +03:00
( delta - > acb_info & ACB_SVRTRUST ) | |
( delta - > acb_info & ACB_DOMTRUST ) ) {
2002-09-18 10:34:10 +04:00
pstrcpy ( add_script , lp_addmachine_script ( ) ) ;
} else {
DEBUG ( 1 , ( " Unknown user type: %s \n " ,
2004-02-08 11:38:42 +03:00
pdb_encode_acct_ctrl ( delta - > acb_info , NEW_PW_FORMAT_SPACE_PADDED_LEN ) ) ) ;
2003-09-10 10:58:41 +04:00
nt_ret = NT_STATUS_UNSUCCESSFUL ;
goto done ;
2002-09-18 10:34:10 +04:00
}
if ( * add_script ) {
int add_ret ;
all_string_sub ( add_script , " %u " , account ,
sizeof ( account ) ) ;
add_ret = smbrun ( add_script , NULL ) ;
2005-02-07 21:20:06 +03:00
DEBUG ( add_ret ? 0 : 1 , ( " fetch_account: Running the command `%s' "
2002-09-18 10:34:10 +04:00
" gave %d \n " , add_script , add_ret ) ) ;
2005-05-31 06:23:47 +04:00
}
2003-07-09 20:44:47 +04:00
/* try and find the possible unix account again */
2003-09-10 10:58:41 +04:00
if ( ! ( passwd = Get_Pwnam ( account ) ) ) {
d_printf ( " Could not create posix account info for '%s' \n " , account ) ;
nt_ret = NT_STATUS_NO_SUCH_USER ;
goto done ;
}
2002-09-18 10:34:10 +04:00
}
2003-07-05 13:46:12 +04:00
sid_copy ( & user_sid , get_global_sam_sid ( ) ) ;
sid_append_rid ( & user_sid , delta - > user_rid ) ;
2002-09-18 10:34:10 +04:00
2003-07-05 14:39:41 +04:00
DEBUG ( 3 , ( " Attempting to find SID %s for user %s in the passdb \n " , sid_to_string ( sid_string , & user_sid ) , account ) ) ;
2003-07-05 13:46:12 +04:00
if ( ! pdb_getsampwsid ( sam_account , & user_sid ) ) {
sam_account_from_delta ( sam_account , delta ) ;
2003-07-05 14:39:41 +04:00
DEBUG ( 3 , ( " Attempting to add user SID %s for user %s in the passdb \n " ,
sid_to_string ( sid_string , & user_sid ) , pdb_get_username ( sam_account ) ) ) ;
2003-07-05 13:46:12 +04:00
if ( ! pdb_add_sam_account ( sam_account ) ) {
DEBUG ( 1 , ( " SAM Account for %s failed to be added to the passdb! \n " ,
account ) ) ;
return NT_STATUS_ACCESS_DENIED ;
}
} else {
sam_account_from_delta ( sam_account , delta ) ;
2003-07-05 14:39:41 +04:00
DEBUG ( 3 , ( " Attempting to update user SID %s for user %s in the passdb \n " ,
sid_to_string ( sid_string , & user_sid ) , pdb_get_username ( sam_account ) ) ) ;
2003-01-29 21:47:57 +03:00
if ( ! pdb_update_sam_account ( sam_account ) ) {
DEBUG ( 1 , ( " SAM Account for %s failed to be updated in the passdb! \n " ,
account ) ) ;
2003-06-14 04:49:02 +04:00
pdb_free_sam ( & sam_account ) ;
2003-07-05 13:46:12 +04:00
return NT_STATUS_ACCESS_DENIED ;
2003-01-29 21:47:57 +03:00
}
2002-09-24 10:50:11 +04:00
}
2003-07-05 13:46:12 +04:00
group_sid = * pdb_get_group_sid ( sam_account ) ;
2002-11-07 10:20:33 +03:00
2003-07-05 13:46:12 +04:00
if ( ! pdb_getgrsid ( & map , group_sid ) ) {
2002-09-24 10:50:11 +04:00
DEBUG ( 0 , ( " Primary group of %s has no mapping! \n " ,
pdb_get_username ( sam_account ) ) ) ;
2003-07-05 13:46:12 +04:00
} else {
if ( map . gid ! = passwd - > pw_gid ) {
if ( ! ( grp = getgrgid ( map . gid ) ) ) {
2003-07-22 08:31:20 +04:00
DEBUG ( 0 , ( " Could not find unix group %lu for user %s (group SID=%s) \n " ,
( unsigned long ) map . gid , pdb_get_username ( sam_account ) , sid_string_static ( & group_sid ) ) ) ;
2003-07-05 13:46:12 +04:00
} else {
smb_set_primary_group ( grp - > gr_name , pdb_get_username ( sam_account ) ) ;
}
}
}
2003-07-16 06:20:53 +04:00
if ( ! passwd ) {
DEBUG ( 1 , ( " No unix user for this account (%s), cannot adjust mappings \n " ,
pdb_get_username ( sam_account ) ) ) ;
2003-06-14 04:49:02 +04:00
}
2002-09-24 10:50:11 +04:00
2003-09-10 10:58:41 +04:00
done :
2002-09-18 10:34:10 +04:00
pdb_free_sam ( & sam_account ) ;
2003-06-14 04:49:02 +04:00
return nt_ret ;
2002-09-18 10:34:10 +04:00
}
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 ) ;
2003-06-18 19:24:10 +04:00
if ( pdb_getgrsid ( & map , group_sid ) ) {
2003-07-16 06:20:53 +04:00
if ( map . gid ! = - 1 )
grp = getgrgid ( map . gid ) ;
2002-11-02 06:47:48 +03:00
insert = False ;
2002-09-24 10:50:11 +04:00
}
2003-07-16 06:20:53 +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 ) {
2003-07-16 06:20:53 +04:00
2003-03-23 05:22:41 +03:00
/* No appropriate group found, create one */
2003-07-16 06:20:53 +04:00
2002-09-24 10:50:11 +04:00
d_printf ( " Creating unix group: '%s' \n " , name ) ;
2003-07-16 06:20:53 +04:00
2002-10-01 22:26:00 +04:00
if ( smb_create_group ( name , & gid ) ! = 0 )
return NT_STATUS_ACCESS_DENIED ;
2003-07-16 06:20:53 +04:00
if ( ( grp = getgrnam ( name ) ) = = 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 ) ;
2003-08-07 06:59:52 +04:00
if ( delta - > hdr_grp_desc . buffer ) {
fstrcpy ( map . comment , comment ) ;
} else {
fstrcpy ( map . comment , " " ) ;
}
2002-09-18 10:34:10 +04:00
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 ) ;
2003-06-18 19:24:10 +04:00
if ( ! get_domain_group_from_sid ( group_sid , & map ) ) {
2002-09-24 10:50:11 +04:00
DEBUG ( 0 , ( " Could not find global group %d \n " , rid ) ) ;
return NT_STATUS_NO_SUCH_GROUP ;
}
if ( ! ( grp = getgrgid ( map . gid ) ) ) {
2003-07-22 08:31:20 +04:00
DEBUG ( 0 , ( " Could not find unix group %lu \n " , ( unsigned long ) map . gid ) ) ;
2002-09-24 10:50:11 +04:00
return NT_STATUS_NO_SUCH_GROUP ;
}
d_printf ( " Group members of %s: " , grp - > gr_name ) ;
2002-12-20 23:21:31 +03:00
if ( ! ( t = talloc_init ( " fetch_group_mem_info " ) ) ) {
2002-09-24 10:50:11 +04:00
DEBUG ( 0 , ( " could not talloc_init \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
2004-12-07 21:25:53 +03:00
nt_members = TALLOC_ZERO_ARRAY ( t , char * , delta - > num_members ) ;
2002-09-24 10:50:11 +04:00
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 ) ) {
2002-11-07 10:20:33 +03:00
DEBUG ( 1 , ( " Found bogus group member: %d (member_sid=%s group=%s) \n " ,
delta - > rids [ i ] , sid_string_static ( & member_sid ) , grp - > gr_name ) ) ;
2002-09-24 10:50:11 +04:00
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 ) ;
2003-06-18 19:24:10 +04:00
if ( pdb_getgrsid ( & map , alias_sid ) ) {
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 ) {
2003-03-23 05:22:41 +03:00
/* No appropriate group found, create one */
2002-09-24 10:50:11 +04:00
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 ) ;
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 )
{
2003-04-29 18:42:49 +04:00
#if 0 /*
* commented out right now after talking to Volker . Can ' t
* do much with the membership but seemed a shame to waste
* somewhat working code . Needs testing because the membership
* that shows up surprises me . Also can ' t do much with groups
* in groups ( e . g . Domain Admins being a member of Adminsitrators ) .
* - - jerry
*/
2002-09-24 10:50:11 +04:00
2003-04-29 18:42:49 +04:00
int i ;
TALLOC_CTX * t = NULL ;
char * * nt_members = NULL ;
char * * unix_members ;
DOM_SID group_sid ;
GROUP_MAP map ;
struct group * grp ;
enum SID_NAME_USE sid_type ;
if ( delta - > num_members = = 0 ) {
return NT_STATUS_OK ;
}
sid_copy ( & group_sid , & dom_sid ) ;
sid_append_rid ( & group_sid , rid ) ;
if ( sid_equal ( & dom_sid , & global_sid_Builtin ) ) {
sid_type = SID_NAME_WKN_GRP ;
2004-01-02 08:32:07 +03:00
if ( ! get_builtin_group_from_sid ( & group_sid , & map , False ) ) {
2003-04-29 18:42:49 +04:00
DEBUG ( 0 , ( " Could not find builtin group %s \n " , sid_string_static ( & group_sid ) ) ) ;
return NT_STATUS_NO_SUCH_GROUP ;
}
} else {
sid_type = SID_NAME_ALIAS ;
2004-01-02 08:32:07 +03:00
if ( ! get_local_group_from_sid ( & group_sid , & map , False ) ) {
2003-04-29 18:42:49 +04:00
DEBUG ( 0 , ( " Could not find local group %s \n " , sid_string_static ( & group_sid ) ) ) ;
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 ( " fetch_group_mem_info " ) ) ) {
DEBUG ( 0 , ( " could not talloc_init \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
2004-12-21 00:14:28 +03:00
nt_members = TALLOC_ZERO_ARRAY ( t , char * , delta - > num_members ) ;
2003-04-29 18:42:49 +04:00
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 , & delta - > sids [ i ] . sid ) ;
if ( ! pdb_getsampwsid ( member , & member_sid ) ) {
DEBUG ( 1 , ( " Found bogus group member: (member_sid=%s group=%s) \n " ,
sid_string_static ( & member_sid ) , grp - > gr_name ) ) ;
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 ) ;
# endif /* end of fetch_alias_mem() */
2002-09-24 10:50:11 +04:00
return NT_STATUS_OK ;
}
2004-12-20 15:52:33 +03:00
static NTSTATUS fetch_domain_info ( uint32 rid , SAM_DOMAIN_INFO * delta )
{
time_t u_max_age , u_min_age , u_logout , u_lockoutreset , u_lockouttime ;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
pstring domname ;
u_max_age = nt_time_to_unix_abs ( ( NTTIME * ) & delta - > max_pwd_age ) ;
u_min_age = nt_time_to_unix_abs ( ( NTTIME * ) & delta - > min_pwd_age ) ;
u_logout = nt_time_to_unix_abs ( ( NTTIME * ) & delta - > force_logoff ) ;
u_lockoutreset = nt_time_to_unix_abs ( ( NTTIME * ) & delta - > account_lockout . reset_count ) ;
u_lockouttime = nt_time_to_unix_abs ( ( NTTIME * ) & delta - > account_lockout . lockout_duration ) ;
unistr2_to_ascii ( domname , & delta - > uni_dom_name , sizeof ( domname ) - 1 ) ;
/* we don't handle BUILTIN account policies */
if ( ! strequal ( domname , get_global_sam_name ( ) ) ) {
printf ( " skipping SAM_DOMAIN_INFO delta for '%s' (is not my domain) \n " , domname ) ;
return NT_STATUS_OK ;
}
2005-02-12 03:51:31 +03:00
if ( ! account_policy_set ( AP_PASSWORD_HISTORY , delta - > pwd_history_len ) )
2004-12-20 15:52:33 +03:00
return nt_status ;
2005-02-12 03:51:31 +03:00
if ( ! account_policy_set ( AP_MIN_PASSWORD_LEN , delta - > min_pwd_len ) )
2004-12-20 15:52:33 +03:00
return nt_status ;
2005-02-12 03:51:31 +03:00
if ( ! account_policy_set ( AP_MAX_PASSWORD_AGE , ( uint32 ) u_max_age ) )
2004-12-20 15:52:33 +03:00
return nt_status ;
2005-02-12 03:51:31 +03:00
if ( ! account_policy_set ( AP_MIN_PASSWORD_AGE , ( uint32 ) u_min_age ) )
2004-12-20 15:52:33 +03:00
return nt_status ;
2005-02-12 03:51:31 +03:00
if ( ! account_policy_set ( AP_TIME_TO_LOGOUT , ( uint32 ) u_logout ) )
2004-12-20 15:52:33 +03:00
return nt_status ;
2005-02-12 03:51:31 +03:00
if ( ! account_policy_set ( AP_BAD_ATTEMPT_LOCKOUT , delta - > account_lockout . bad_attempt_lockout ) )
2004-12-20 15:52:33 +03:00
return nt_status ;
2005-02-12 03:51:31 +03:00
if ( ! account_policy_set ( AP_RESET_COUNT_TIME , ( uint32 ) u_lockoutreset / 60 ) )
2004-12-20 15:52:33 +03:00
return nt_status ;
2005-01-21 00:42:05 +03:00
if ( u_lockouttime ! = - 1 )
u_lockouttime / = 60 ;
2005-02-12 03:51:31 +03:00
if ( ! account_policy_set ( AP_LOCK_ACCOUNT_DURATION , ( uint32 ) u_lockouttime ) )
2004-12-20 15:52:33 +03:00
return nt_status ;
2005-02-12 03:51:31 +03:00
if ( ! account_policy_set ( AP_USER_MUST_LOGON_TO_CHG_PASS , delta - > logon_chgpass ) )
2004-12-20 15:52:33 +03:00
return nt_status ;
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 ;
2003-03-31 14:47:26 +04:00
case SAM_DELTA_DOMAIN_INFO :
2004-12-20 15:52:33 +03:00
fetch_domain_info ( hdr_delta - > target_rid ,
& delta - > domain_info ) ;
2003-03-31 14:47:26 +04:00
break ;
2004-12-20 15:52:33 +03:00
/* The following types are recognised but not handled */
2003-08-07 05:04:57 +04:00
case SAM_DELTA_RENAME_GROUP :
d_printf ( " SAM_DELTA_RENAME_GROUP not handled \n " ) ;
break ;
case SAM_DELTA_RENAME_USER :
d_printf ( " SAM_DELTA_RENAME_USER not handled \n " ) ;
break ;
case SAM_DELTA_RENAME_ALIAS :
d_printf ( " SAM_DELTA_RENAME_ALIAS not handled \n " ) ;
break ;
case SAM_DELTA_POLICY_INFO :
d_printf ( " SAM_DELTA_POLICY_INFO not handled \n " ) ;
break ;
case SAM_DELTA_TRUST_DOMS :
d_printf ( " SAM_DELTA_TRUST_DOMS not handled \n " ) ;
break ;
case SAM_DELTA_PRIVS_INFO :
d_printf ( " SAM_DELTA_PRIVS_INFO not handled \n " ) ;
break ;
case SAM_DELTA_SECRET_INFO :
d_printf ( " SAM_DELTA_SECRET_INFO not handled \n " ) ;
break ;
case SAM_DELTA_DELETE_GROUP :
d_printf ( " SAM_DELTA_DELETE_GROUP not handled \n " ) ;
break ;
case SAM_DELTA_DELETE_USER :
d_printf ( " SAM_DELTA_DELETE_USER not handled \n " ) ;
break ;
case SAM_DELTA_MODIFIED_COUNT :
d_printf ( " SAM_DELTA_MODIFIED_COUNT not handled \n " ) ;
break ;
2002-09-18 10:34:10 +04:00
default :
d_printf ( " Unknown delta record type %d \n " , hdr_delta - > type ) ;
break ;
}
}
2003-06-16 09:39:26 +04:00
static NTSTATUS
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 ;
2003-06-16 09:39:26 +04:00
if ( ! ( mem_ctx = talloc_init ( " fetch_database " ) ) )
return NT_STATUS_NO_MEMORY ;
2002-09-18 10:34:10 +04:00
2003-03-31 14:47:26 +04:00
switch ( db_type ) {
case SAM_DATABASE_DOMAIN :
d_printf ( " Fetching DOMAIN database \n " ) ;
break ;
case SAM_DATABASE_BUILTIN :
d_printf ( " Fetching BUILTIN database \n " ) ;
break ;
case SAM_DATABASE_PRIVS :
d_printf ( " Fetching PRIVS databases \n " ) ;
break ;
default :
d_printf ( " Fetching unknown database type %u \n " , db_type ) ;
break ;
}
2002-09-18 10:34:10 +04:00
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 ) ;
2003-05-12 11:18:36 +04:00
if ( NT_STATUS_IS_OK ( result ) | |
NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) ) {
clnt_deal_with_creds ( cli - > sess_key , & ( cli - > clnt_cred ) ,
ret_creds ) ;
for ( i = 0 ; i < num_deltas ; i + + ) {
fetch_sam_entry ( & hdr_deltas [ i ] , & deltas [ i ] , dom_sid ) ;
}
2003-06-16 09:39:26 +04:00
} else
return result ;
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 ) ;
2003-06-16 09:39:26 +04:00
return result ;
2002-09-18 10:34:10 +04:00
}
2005-07-07 01:02:43 +04:00
static NTSTATUS
populate_ldap_for_ldif ( fstring sid , const char * suffix , const char
* builtin_sid , FILE * add_fd )
{
char * user_suffix , * group_suffix , * machine_suffix , * idmap_suffix ;
char * user_attr = NULL , * group_attr = NULL ;
char * suffix_attr ;
int len ;
/* Get the suffix attribute */
suffix_attr = sstring_sub ( suffix , ' = ' , ' , ' ) ;
if ( suffix_attr = = NULL ) {
len = strlen ( suffix ) ;
suffix_attr = ( char * ) SMB_MALLOC ( len + 1 ) ;
memcpy ( suffix_attr , suffix , len ) ;
suffix_attr [ len ] = ' \0 ' ;
}
/* Write the base */
fprintf ( add_fd , " # %s \n " , suffix ) ;
fprintf ( add_fd , " dn: %s \n " , suffix ) ;
fprintf ( add_fd , " objectClass: dcObject \n " ) ;
fprintf ( add_fd , " objectClass: organization \n " ) ;
fprintf ( add_fd , " o: %s \n " , suffix_attr ) ;
fprintf ( add_fd , " dc: %s \n " , suffix_attr ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
user_suffix = lp_ldap_user_suffix ( ) ;
/* If it exists and is distinct from other containers,
Write the Users entity */
if ( user_suffix & & * user_suffix & &
strcmp ( user_suffix , suffix ) ) {
user_attr = sstring_sub ( lp_ldap_user_suffix ( ) , ' = ' , ' , ' ) ;
fprintf ( add_fd , " # %s \n " , user_suffix ) ;
fprintf ( add_fd , " dn: %s \n " , user_suffix ) ;
fprintf ( add_fd , " objectClass: organizationalUnit \n " ) ;
fprintf ( add_fd , " ou: %s \n " , user_attr ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
}
group_suffix = lp_ldap_group_suffix ( ) ;
/* If it exists and is distinct from other containers,
Write the Groups entity */
if ( group_suffix & & * group_suffix & &
strcmp ( group_suffix , suffix ) ) {
group_attr = sstring_sub ( lp_ldap_group_suffix ( ) , ' = ' , ' , ' ) ;
fprintf ( add_fd , " # %s \n " , group_suffix ) ;
fprintf ( add_fd , " dn: %s \n " , group_suffix ) ;
fprintf ( add_fd , " objectClass: organizationalUnit \n " ) ;
fprintf ( add_fd , " ou: %s \n " , group_attr ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
}
/* If it exists and is distinct from other containers,
Write the Computers entity */
machine_suffix = lp_ldap_machine_suffix ( ) ;
if ( machine_suffix & & * machine_suffix & &
strcmp ( machine_suffix , user_suffix ) & &
strcmp ( machine_suffix , suffix ) ) {
fprintf ( add_fd , " # %s \n " , lp_ldap_machine_suffix ( ) ) ;
fprintf ( add_fd , " dn: %s \n " , lp_ldap_machine_suffix ( ) ) ;
fprintf ( add_fd , " objectClass: organizationalUnit \n " ) ;
fprintf ( add_fd , " ou: %s \n " ,
sstring_sub ( lp_ldap_machine_suffix ( ) , ' = ' , ' , ' ) ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
}
/* If it exists and is distinct from other containers,
Write the IdMap entity */
idmap_suffix = lp_ldap_idmap_suffix ( ) ;
if ( idmap_suffix & & * idmap_suffix & &
strcmp ( idmap_suffix , user_suffix ) & &
strcmp ( idmap_suffix , suffix ) ) {
fprintf ( add_fd , " # %s \n " , idmap_suffix ) ;
fprintf ( add_fd , " dn: %s \n " , idmap_suffix ) ;
fprintf ( add_fd , " ObjectClass: organizationalUnit \n " ) ;
fprintf ( add_fd , " ou: %s \n " ,
sstring_sub ( lp_ldap_idmap_suffix ( ) , ' = ' , ' , ' ) ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
}
/* Write the root entity */
fprintf ( add_fd , " # root, %s, %s \n " , user_attr , suffix ) ;
fprintf ( add_fd , " dn: uid=root,ou=%s,%s \n " , user_attr , suffix ) ;
fprintf ( add_fd , " cn: root \n " ) ;
fprintf ( add_fd , " sn: root \n " ) ;
fprintf ( add_fd , " objectClass: inetOrgPerson \n " ) ;
fprintf ( add_fd , " objectClass: sambaSAMAccount \n " ) ;
fprintf ( add_fd , " objectClass: posixAccount \n " ) ;
fprintf ( add_fd , " objectClass: shadowAccount \n " ) ;
fprintf ( add_fd , " gidNumber: 0 \n " ) ;
fprintf ( add_fd , " uid: root \n " ) ;
fprintf ( add_fd , " uidNumber: 0 \n " ) ;
fprintf ( add_fd , " homeDirectory: /home/root \n " ) ;
fprintf ( add_fd , " sambaPwdLastSet: 0 \n " ) ;
fprintf ( add_fd , " sambaLogonTime: 0 \n " ) ;
fprintf ( add_fd , " sambaLogoffTime: 2147483647 \n " ) ;
fprintf ( add_fd , " sambaKickoffTime: 2147483647 \n " ) ;
fprintf ( add_fd , " sambaPwdCanChange: 0 \n " ) ;
fprintf ( add_fd , " sambaPwdMustChange: 2147483647 \n " ) ;
fprintf ( add_fd , " sambaHomePath: \\ \\ PDC-SRV \r oot \n " ) ;
fprintf ( add_fd , " sambaHomeDrive: H: \n " ) ;
fprintf ( add_fd , " sambaProfilePath: \\ \\ PDC-SRV \\ profiles \\ root \n " ) ;
fprintf ( add_fd , " sambaprimaryGroupSID: %s-512 \n " , sid ) ;
fprintf ( add_fd , " sambaLMPassword: XXX \n " ) ;
fprintf ( add_fd , " sambaNTPassword: XXX \n " ) ;
fprintf ( add_fd , " sambaAcctFlags: [U \n " ) ;
fprintf ( add_fd , " sambaSID: %s-500 \n " , sid ) ;
fprintf ( add_fd , " loginShell: /bin/false \n " ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Write the domain entity */
fprintf ( add_fd , " # %s, %s \n " , lp_workgroup ( ) , suffix ) ;
fprintf ( add_fd , " dn: sambaDomainName=%s,%s \n " , lp_workgroup ( ) ,
suffix ) ;
fprintf ( add_fd , " objectClass: sambaDomain \n " ) ;
fprintf ( add_fd , " objectClass: sambaUnixIdPool \n " ) ;
fprintf ( add_fd , " sambaDomainName: %s \n " , lp_workgroup ( ) ) ;
fprintf ( add_fd , " sambaSID: %s \n " , sid ) ;
fprintf ( add_fd , " uidNumber: %d \n " , + + ldif_uid ) ;
fprintf ( add_fd , " gidNumber: %d \n " , + + ldif_gid ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Write user nobody entity */
fprintf ( add_fd , " # nobody, %s, %s \n " , user_attr , suffix ) ;
fprintf ( add_fd , " dn: uid=nobody,ou=%s,%s \n " , user_attr , suffix ) ;
fprintf ( add_fd , " cn: nobody \n " ) ;
fprintf ( add_fd , " sn: nobody \n " ) ;
fprintf ( add_fd , " objectClass: inetOrgPerson \n " ) ;
fprintf ( add_fd , " objectClass: sambaSAMAccount \n " ) ;
fprintf ( add_fd , " objectClass: posixAccount \n " ) ;
fprintf ( add_fd , " objectClass: shadowAccount \n " ) ;
fprintf ( add_fd , " gidNumber: 514 \n " ) ;
fprintf ( add_fd , " uid: nobody \n " ) ;
fprintf ( add_fd , " uidNumber: 999 \n " ) ;
fprintf ( add_fd , " homeDirectory: /dev/null \n " ) ;
fprintf ( add_fd , " sambaPwdLastSet: 0 \n " ) ;
fprintf ( add_fd , " sambaLogonTime: 0 \n " ) ;
fprintf ( add_fd , " sambaLogoffTime: 2147483647 \n " ) ;
fprintf ( add_fd , " sambaKickoffTime: 2147483647 \n " ) ;
fprintf ( add_fd , " sambaPwdCanChange: 0 \n " ) ;
fprintf ( add_fd , " sambaPwdMustChange: 2147483647 \n " ) ;
fprintf ( add_fd , " sambaHomePath: \\ \\ PDC-SMD3 \\ homes \\ nobody \n " ) ;
fprintf ( add_fd , " sambaHomeDrive: H: \n " ) ;
fprintf ( add_fd , " sambaProfilePath: \\ \\ PDC-SMB3 \\ profiles \\ nobody \n " ) ;
fprintf ( add_fd , " sambaprimaryGroupSID: %s-514 \n " , sid ) ;
fprintf ( add_fd , " sambaLMPassword: NOPASSWORDXXXXXXXXXXXXXXXXXXXXX \n " ) ;
fprintf ( add_fd , " sambaNTPassword: NOPASSWORDXXXXXXXXXXXXXXXXXXXXX \n " ) ;
fprintf ( add_fd , " sambaAcctFlags: [NU \n " ) ;
fprintf ( add_fd , " sambaSID: %s-2998 \n " , sid ) ;
fprintf ( add_fd , " loginShell: /bin/false \n " ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Write the Domain Admins entity */
fprintf ( add_fd , " # Domain Admins, %s, %s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " dn: cn=Domain Admins,ou=%s,%s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " objectClass: posixGroup \n " ) ;
fprintf ( add_fd , " objectClass: sambaGroupMapping \n " ) ;
fprintf ( add_fd , " cn: Domain Admins \n " ) ;
fprintf ( add_fd , " memberUid: Administrator \n " ) ;
fprintf ( add_fd , " description: Netbios Domain Administrators \n " ) ;
fprintf ( add_fd , " gidNumber: 512 \n " ) ;
fprintf ( add_fd , " sambaSID: %s-512 \n " , sid ) ;
fprintf ( add_fd , " sambaGroupType: 2 \n " ) ;
fprintf ( add_fd , " displayName: Domain Admins \n " ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Write the Domain Users entity */
fprintf ( add_fd , " # Domain Users, %s, %s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " dn: cn=Domain Users,ou=%s,%s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " objectClass: posixGroup \n " ) ;
fprintf ( add_fd , " objectClass: sambaGroupMapping \n " ) ;
fprintf ( add_fd , " cn: Domain Users \n " ) ;
fprintf ( add_fd , " description: Netbios Domain Users \n " ) ;
fprintf ( add_fd , " gidNumber: 513 \n " ) ;
fprintf ( add_fd , " sambaSID: %s-513 \n " , sid ) ;
fprintf ( add_fd , " sambaGroupType: 2 \n " ) ;
fprintf ( add_fd , " displayName: Domain Users \n " ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Write the Domain Guests entity */
fprintf ( add_fd , " # Domain Guests, %s, %s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " dn: cn=Domain Guests,ou=%s,%s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " objectClass: posixGroup \n " ) ;
fprintf ( add_fd , " objectClass: sambaGroupMapping \n " ) ;
fprintf ( add_fd , " cn: Domain Guests \n " ) ;
fprintf ( add_fd , " description: Netbios Domain Guests \n " ) ;
fprintf ( add_fd , " gidNumber: 514 \n " ) ;
fprintf ( add_fd , " sambaSID: %s-514 \n " , sid ) ;
fprintf ( add_fd , " sambaGroupType: 2 \n " ) ;
fprintf ( add_fd , " displayName: Domain Guests \n " ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Write the Domain Computers entity */
fprintf ( add_fd , " # Domain Computers, %s, %s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " dn: cn=Domain Computers,ou=%s,%s \n " ,
group_attr , suffix ) ;
fprintf ( add_fd , " objectClass: posixGroup \n " ) ;
fprintf ( add_fd , " objectClass: sambaGroupMapping \n " ) ;
fprintf ( add_fd , " gidNumber: 515 \n " ) ;
fprintf ( add_fd , " cn: Domain Computers \n " ) ;
fprintf ( add_fd , " description: Netbios Domain Computers accounts \n " ) ;
fprintf ( add_fd , " sambaSID: %s-515 \n " , sid ) ;
fprintf ( add_fd , " sambaGroupType: 2 \n " ) ;
fprintf ( add_fd , " displayName: Domain Computers \n " ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Write the Admininistrators Groups entity */
fprintf ( add_fd , " # Administrators, %s, %s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " dn: cn=Administrators,ou=%s,%s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " objectClass: posixGroup \n " ) ;
fprintf ( add_fd , " objectClass: sambaGroupMapping \n " ) ;
fprintf ( add_fd , " gidNumber: 544 \n " ) ;
fprintf ( add_fd , " cn: Administrators \n " ) ;
fprintf ( add_fd , " description: Netbios Domain Members can fully administer the computer/sambaDomainName \n " ) ;
fprintf ( add_fd , " sambaSID: %s-544 \n " , builtin_sid ) ;
fprintf ( add_fd , " sambaGroupType: 5 \n " ) ;
fprintf ( add_fd , " displayName: Administrators \n " ) ;
fprintf ( add_fd , " \n " ) ;
/* Write the Print Operator entity */
fprintf ( add_fd , " # Print Operators, %s, %s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " dn: cn=Print Operators,ou=%s,%s \n " ,
group_attr , suffix ) ;
fprintf ( add_fd , " objectClass: posixGroup \n " ) ;
fprintf ( add_fd , " objectClass: sambaGroupMapping \n " ) ;
fprintf ( add_fd , " gidNumber: 550 \n " ) ;
fprintf ( add_fd , " cn: Print Operators \n " ) ;
fprintf ( add_fd , " description: Netbios Domain Print Operators \n " ) ;
fprintf ( add_fd , " sambaSID: %s-550 \n " , builtin_sid ) ;
fprintf ( add_fd , " sambaGroupType: 5 \n " ) ;
fprintf ( add_fd , " displayName: Print Operators \n " ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Write the Backup Operators entity */
fprintf ( add_fd , " # Backup Operators, %s, %s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " dn: cn=Backup Operators,ou=%s,%s \n " ,
group_attr , suffix ) ;
fprintf ( add_fd , " objectClass: posixGroup \n " ) ;
fprintf ( add_fd , " objectClass: sambaGroupMapping \n " ) ;
fprintf ( add_fd , " gidNumber: 551 \n " ) ;
fprintf ( add_fd , " cn: Backup Operators \n " ) ;
fprintf ( add_fd , " description: Netbios Domain Members can bypass file security to back up files \n " ) ;
fprintf ( add_fd , " sambaSID: %s-551 \n " , builtin_sid ) ;
fprintf ( add_fd , " sambaGroupType: 5 \n " ) ;
fprintf ( add_fd , " displayName: Backup Operators \n " ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Write the Replicators entity */
fprintf ( add_fd , " # Replicators, %s, %s \n " , group_attr , suffix ) ;
fprintf ( add_fd , " dn: cn=Replicators,ou=%s,%s \n " , group_attr ,
suffix ) ;
fprintf ( add_fd , " objectClass: posixGroup \n " ) ;
fprintf ( add_fd , " objectClass: sambaGroupMapping \n " ) ;
fprintf ( add_fd , " gidNumber: 552 \n " ) ;
fprintf ( add_fd , " cn: Replicators \n " ) ;
fprintf ( add_fd , " description: Netbios Domain Supports file replication in a sambaDomainName \n " ) ;
fprintf ( add_fd , " sambaSID: %s-552 \n " , builtin_sid ) ;
fprintf ( add_fd , " sambaGroupType: 5 \n " ) ;
fprintf ( add_fd , " displayName: Replicators \n " ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Deallocate memory, and return */
if ( suffix_attr ! = NULL ) SAFE_FREE ( suffix_attr ) ;
return NT_STATUS_OK ;
}
static NTSTATUS
map_populate_groups ( GROUPMAP * groupmap , ACCOUNTMAP * accountmap , fstring sid ,
const char * suffix , const char * builtin_sid )
{
char * group_attr = sstring_sub ( lp_ldap_group_suffix ( ) , ' = ' , ' , ' ) ;
/* Map the groups created by populate_ldap_for_ldif */
groupmap [ 0 ] . rid = 512 ;
groupmap [ 0 ] . gidNumber = 512 ;
pstr_sprintf ( groupmap [ 0 ] . sambaSID , " %s-512 " , sid ) ;
pstr_sprintf ( groupmap [ 0 ] . group_dn , " cn=Domain Admins,ou=%s,%s " ,
group_attr , suffix ) ;
accountmap [ 0 ] . rid = 512 ;
pstr_sprintf ( accountmap [ 0 ] . cn , " %s " , " Domain Admins " ) ;
groupmap [ 1 ] . rid = 513 ;
groupmap [ 1 ] . gidNumber = 513 ;
pstr_sprintf ( groupmap [ 1 ] . sambaSID , " %s-513 " , sid ) ;
pstr_sprintf ( groupmap [ 1 ] . group_dn , " cn=Domain Users,ou=%s,%s " ,
group_attr , suffix ) ;
accountmap [ 1 ] . rid = 513 ;
pstr_sprintf ( accountmap [ 1 ] . cn , " %s " , " Domain Users " ) ;
groupmap [ 2 ] . rid = 514 ;
groupmap [ 2 ] . gidNumber = 514 ;
pstr_sprintf ( groupmap [ 2 ] . sambaSID , " %s-514 " , sid ) ;
pstr_sprintf ( groupmap [ 2 ] . group_dn , " cn=Domain Guests,ou=%s,%s " ,
group_attr , suffix ) ;
accountmap [ 2 ] . rid = 514 ;
pstr_sprintf ( accountmap [ 2 ] . cn , " %s " , " Domain Guests " ) ;
groupmap [ 3 ] . rid = 515 ;
groupmap [ 3 ] . gidNumber = 515 ;
pstr_sprintf ( groupmap [ 3 ] . sambaSID , " %s-515 " , sid ) ;
pstr_sprintf ( groupmap [ 3 ] . group_dn , " cn=Domain Computers,ou=%s,%s " ,
group_attr , suffix ) ;
accountmap [ 3 ] . rid = 515 ;
pstr_sprintf ( accountmap [ 3 ] . cn , " %s " , " Domain Computers " ) ;
groupmap [ 4 ] . rid = 544 ;
groupmap [ 4 ] . gidNumber = 544 ;
pstr_sprintf ( groupmap [ 4 ] . sambaSID , " %s-544 " , builtin_sid ) ;
pstr_sprintf ( groupmap [ 4 ] . group_dn , " cn=Administrators,ou=%s,%s " ,
group_attr , suffix ) ;
accountmap [ 4 ] . rid = 515 ;
pstr_sprintf ( accountmap [ 4 ] . cn , " %s " , " Administrators " ) ;
groupmap [ 5 ] . rid = 550 ;
groupmap [ 5 ] . gidNumber = 550 ;
pstr_sprintf ( groupmap [ 5 ] . sambaSID , " %s-550 " , builtin_sid ) ;
pstr_sprintf ( groupmap [ 5 ] . group_dn , " cn=Print Operators,ou=%s,%s " ,
group_attr , suffix ) ;
accountmap [ 5 ] . rid = 550 ;
pstr_sprintf ( accountmap [ 5 ] . cn , " %s " , " Print Operators " ) ;
groupmap [ 6 ] . rid = 551 ;
groupmap [ 6 ] . gidNumber = 551 ;
pstr_sprintf ( groupmap [ 6 ] . sambaSID , " %s-551 " , builtin_sid ) ;
pstr_sprintf ( groupmap [ 6 ] . group_dn , " cn=Backup Operators,ou=%s,%s " ,
group_attr , suffix ) ;
accountmap [ 6 ] . rid = 551 ;
pstr_sprintf ( accountmap [ 6 ] . cn , " %s " , " Backup Operators " ) ;
groupmap [ 7 ] . rid = 552 ;
groupmap [ 7 ] . gidNumber = 552 ;
pstr_sprintf ( groupmap [ 7 ] . sambaSID , " %s-552 " , builtin_sid ) ;
pstr_sprintf ( groupmap [ 7 ] . group_dn , " cn=Replicators,ou=%s,%s " ,
group_attr , suffix ) ;
accountmap [ 7 ] . rid = 551 ;
pstr_sprintf ( accountmap [ 7 ] . cn , " %s " , " Replicators " ) ;
return NT_STATUS_OK ;
}
static NTSTATUS
fetch_group_info_to_ldif ( SAM_DELTA_CTR * delta , GROUPMAP * groupmap ,
FILE * add_fd , fstring sid , char * suffix )
{
fstring groupname ;
uint32 grouptype = 0 , g_rid = 0 ;
char * group_attr = sstring_sub ( lp_ldap_group_suffix ( ) , ' = ' , ' , ' ) ;
/* Get the group name */
unistr2_to_ascii ( groupname ,
& ( delta - > group_info . uni_grp_name ) ,
sizeof ( groupname ) - 1 ) ;
/* Set up the group type (always 2 for group info) */
grouptype = 2 ;
/* These groups are entered by populate_ldap_for_ldif */
if ( strcmp ( groupname , " Domain Admins " ) = = 0 | |
strcmp ( groupname , " Domain Users " ) = = 0 | |
strcmp ( groupname , " Domain Guests " ) = = 0 | |
strcmp ( groupname , " Domain Computers " ) = = 0 | |
strcmp ( groupname , " Administrators " ) = = 0 | |
strcmp ( groupname , " Print Operators " ) = = 0 | |
strcmp ( groupname , " Backup Operators " ) = = 0 | |
strcmp ( groupname , " Replicators " ) = = 0 ) {
return NT_STATUS_OK ;
} else {
/* Increment the gid for the new group */
ldif_gid + + ;
}
/* Map the group rid, gid, and dn */
g_rid = delta - > group_info . gid . g_rid ;
groupmap - > rid = g_rid ;
groupmap - > gidNumber = ldif_gid ;
pstr_sprintf ( groupmap - > sambaSID , " %s-%d " , sid , g_rid ) ;
pstr_sprintf ( groupmap - > group_dn ,
" cn=%s,ou=%s,%s " , groupname , group_attr , suffix ) ;
/* Write the data to the temporary add ldif file */
fprintf ( add_fd , " # %s, %s, %s \n " , groupname , group_attr ,
suffix ) ;
fprintf ( add_fd , " dn: cn=%s,ou=%s,%s \n " , groupname , group_attr ,
suffix ) ;
fprintf ( add_fd , " objectClass: posixGroup \n " ) ;
fprintf ( add_fd , " objectClass: sambaGroupMapping \n " ) ;
fprintf ( add_fd , " cn: %s \n " , groupname ) ;
fprintf ( add_fd , " gidNumber: %d \n " , ldif_gid ) ;
fprintf ( add_fd , " sambaSID: %s \n " , groupmap - > sambaSID ) ;
fprintf ( add_fd , " sambaGroupType: %d \n " , grouptype ) ;
fprintf ( add_fd , " displayName: %s \n " , groupname ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Return */
return NT_STATUS_OK ;
}
static NTSTATUS
fetch_account_info_to_ldif ( SAM_DELTA_CTR * delta , GROUPMAP * groupmap ,
ACCOUNTMAP * accountmap , FILE * add_fd ,
fstring sid , char * suffix , int alloced )
{
fstring username , homedir , logonscript , homedrive , homepath ;
fstring hex_nt_passwd , hex_lm_passwd ;
fstring description , fullname , sambaSID ;
uchar lm_passwd [ 16 ] , nt_passwd [ 16 ] ;
char * flags ;
const char * blank = " " , * shell = " /bin/bash " ;
const char * nopasswd = " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX " ;
static uchar zero_buf [ 16 ] ;
uint32 rid = 0 , group_rid = 0 , gidNumber = 0 ;
time_t unix_time ;
int i ;
/* Get the username */
unistr2_to_ascii ( username ,
& ( delta - > account_info . uni_acct_name ) ,
sizeof ( username ) - 1 ) ;
/* Get the rid */
rid = delta - > account_info . user_rid ;
/* Map the rid and username for group member info later */
accountmap - > rid = rid ;
pstr_sprintf ( accountmap - > cn , " %s " , username ) ;
/* Get the home directory */
unistr2_to_ascii ( homedir , & ( delta - > account_info . uni_home_dir ) ,
sizeof ( homedir ) - 1 ) ;
if ( strcmp ( homedir , blank ) = = 0 ) {
pstr_sprintf ( homedir , " /home/%s " , username ) ;
} else {
strncpy ( homepath , homedir , sizeof ( homepath ) ) ;
}
/* Get the logon script */
unistr2_to_ascii ( logonscript , & ( delta - > account_info . uni_logon_script ) ,
sizeof ( logonscript ) - 1 ) ;
/* Get the home drive */
unistr2_to_ascii ( homedrive , & ( delta - > account_info . uni_dir_drive ) ,
sizeof ( homedrive ) - 1 ) ;
/* Get the description */
unistr2_to_ascii ( description , & ( delta - > account_info . uni_acct_desc ) ,
sizeof ( description ) - 1 ) ;
if ( strcmp ( description , blank ) = = 0 ) {
pstr_sprintf ( description , " System User " ) ;
}
/* Get the display name */
unistr2_to_ascii ( fullname , & ( delta - > account_info . uni_full_name ) ,
sizeof ( fullname ) - 1 ) ;
/* Get lm and nt password data */
if ( memcmp ( delta - > account_info . pass . buf_lm_pwd , zero_buf , 16 ) ! = 0 ) {
sam_pwd_hash ( delta - > account_info . user_rid ,
delta - > account_info . pass . buf_lm_pwd ,
lm_passwd , 0 ) ;
pdb_sethexpwd ( hex_lm_passwd , lm_passwd ,
delta - > account_info . acb_info ) ;
} else {
pdb_sethexpwd ( hex_lm_passwd , NULL , 0 ) ;
}
if ( memcmp ( delta - > account_info . pass . buf_nt_pwd , zero_buf , 16 ) ! = 0 ) {
sam_pwd_hash ( delta - > account_info . user_rid ,
delta - > account_info . pass . buf_nt_pwd ,
nt_passwd , 0 ) ;
pdb_sethexpwd ( hex_nt_passwd , nt_passwd ,
delta - > account_info . acb_info ) ;
} else {
pdb_sethexpwd ( hex_nt_passwd , NULL , 0 ) ;
}
unix_time = nt_time_to_unix ( & ( delta - > account_info . pwd_last_set_time ) ) ;
/* The nobody user is entered by populate_ldap_for_ldif */
if ( strcmp ( username , " nobody " ) = = 0 ) {
return NT_STATUS_OK ;
} else {
/* Increment the uid for the new user */
ldif_uid + + ;
}
/* Set up group id and sambaSID for the user */
group_rid = delta - > account_info . group_rid ;
for ( i = 0 ; i < alloced ; i + + ) {
if ( groupmap [ i ] . rid = = group_rid ) break ;
}
if ( i = = alloced ) {
DEBUG ( 1 , ( " Could not find rid %d in groupmap array \n " ,
group_rid ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
gidNumber = groupmap [ i ] . gidNumber ;
pstr_sprintf ( sambaSID , groupmap [ i ] . sambaSID ) ;
/* Set up sambaAcctFlags */
flags = pdb_encode_acct_ctrl ( delta - > account_info . acb_info ,
NEW_PW_FORMAT_SPACE_PADDED_LEN ) ;
/* Add the user to the temporary add ldif file */
fprintf ( add_fd , " # %s, %s, %s \n " , username ,
sstring_sub ( lp_ldap_user_suffix ( ) , ' = ' , ' , ' ) , suffix ) ;
fprintf ( add_fd , " dn: uid=%s,ou=%s,%s \n " , username ,
sstring_sub ( lp_ldap_user_suffix ( ) , ' = ' , ' , ' ) , suffix ) ;
fprintf ( add_fd , " ObjectClass: top \n " ) ;
fprintf ( add_fd , " objectClass: inetOrgPerson \n " ) ;
fprintf ( add_fd , " objectClass: posixAccount \n " ) ;
fprintf ( add_fd , " objectClass: shadowAccount \n " ) ;
fprintf ( add_fd , " objectClass: sambaSamAccount \n " ) ;
fprintf ( add_fd , " cn: %s \n " , username ) ;
fprintf ( add_fd , " sn: %s \n " , username ) ;
fprintf ( add_fd , " uid: %s \n " , username ) ;
fprintf ( add_fd , " uidNumber: %d \n " , ldif_uid ) ;
fprintf ( add_fd , " gidNumber: %d \n " , gidNumber ) ;
fprintf ( add_fd , " homeDirectory: %s \n " , homedir ) ;
if ( strcmp ( homepath , blank ) ! = 0 )
fprintf ( add_fd , " SambaHomePath: %s \n " , homepath ) ;
if ( strcmp ( homedrive , blank ) ! = 0 )
fprintf ( add_fd , " SambaHomeDrive: %s \n " , homedrive ) ;
if ( strcmp ( logonscript , blank ) ! = 0 )
fprintf ( add_fd , " SambaLogonScript: %s \n " , logonscript ) ;
fprintf ( add_fd , " loginShell: %s \n " , shell ) ;
fprintf ( add_fd , " gecos: System User \n " ) ;
fprintf ( add_fd , " description: %s \n " , description ) ;
fprintf ( add_fd , " sambaSID: %s-%d \n " , sid , rid ) ;
fprintf ( add_fd , " sambaPrimaryGroupSID: %s \n " , sambaSID ) ;
if ( strcmp ( fullname , blank ) ! = 0 )
fprintf ( add_fd , " displayName: %s \n " , fullname ) ;
if ( strcmp ( nopasswd , hex_lm_passwd ) ! = 0 )
fprintf ( add_fd , " sambaLMPassword: %s \n " , hex_lm_passwd ) ;
if ( strcmp ( nopasswd , hex_nt_passwd ) ! = 0 )
fprintf ( add_fd , " sambaNTPassword: %s \n " , hex_nt_passwd ) ;
2005-07-13 03:02:31 +04:00
fprintf ( add_fd , " sambaPwdLastSet: %d \n " , ( int ) unix_time ) ;
2005-07-07 01:02:43 +04:00
fprintf ( add_fd , " sambaAcctFlags: %s \n " , flags ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Return */
return NT_STATUS_OK ;
}
static NTSTATUS
fetch_alias_info_to_ldif ( SAM_DELTA_CTR * delta , GROUPMAP * groupmap ,
FILE * add_fd , fstring sid , char * suffix ,
unsigned db_type )
{
fstring aliasname , description ;
uint32 grouptype = 0 , g_rid = 0 ;
char * group_attr = sstring_sub ( lp_ldap_group_suffix ( ) , ' = ' , ' , ' ) ;
/* Get the alias name */
unistr2_to_ascii ( aliasname , & ( delta - > alias_info . uni_als_name ) ,
sizeof ( aliasname ) - 1 ) ;
/* Get the alias description */
unistr2_to_ascii ( description , & ( delta - > alias_info . uni_als_desc ) ,
sizeof ( description ) - 1 ) ;
/* Set up the group type */
switch ( db_type ) {
case SAM_DATABASE_DOMAIN :
grouptype = 4 ;
break ;
case SAM_DATABASE_BUILTIN :
grouptype = 5 ;
break ;
default :
grouptype = 4 ;
break ;
}
/*
These groups are entered by populate_ldap_for_ldif
Note that populate creates a group called Relicators ,
but NT returns a group called Replicator
*/
if ( strcmp ( aliasname , " Domain Admins " ) = = 0 | |
strcmp ( aliasname , " Domain Users " ) = = 0 | |
strcmp ( aliasname , " Domain Guests " ) = = 0 | |
strcmp ( aliasname , " Domain Computers " ) = = 0 | |
strcmp ( aliasname , " Administrators " ) = = 0 | |
strcmp ( aliasname , " Print Operators " ) = = 0 | |
strcmp ( aliasname , " Backup Operators " ) = = 0 | |
strcmp ( aliasname , " Replicator " ) = = 0 ) {
return NT_STATUS_OK ;
} else {
/* Increment the gid for the new group */
ldif_gid + + ;
}
/* Map the group rid and gid */
g_rid = delta - > group_info . gid . g_rid ;
groupmap - > gidNumber = ldif_gid ;
pstr_sprintf ( groupmap - > sambaSID , " %s-%d " , sid , g_rid ) ;
/* Write the data to the temporary add ldif file */
fprintf ( add_fd , " # %s, %s, %s \n " , aliasname , group_attr ,
suffix ) ;
fprintf ( add_fd , " dn: cn=%s,ou=%s,%s \n " , aliasname , group_attr ,
suffix ) ;
fprintf ( add_fd , " objectClass: posixGroup \n " ) ;
fprintf ( add_fd , " objectClass: sambaGroupMapping \n " ) ;
fprintf ( add_fd , " cn: %s \n " , aliasname ) ;
fprintf ( add_fd , " gidNumber: %d \n " , ldif_gid ) ;
fprintf ( add_fd , " sambaSID: %s \n " , groupmap - > sambaSID ) ;
fprintf ( add_fd , " sambaGroupType: %d \n " , grouptype ) ;
fprintf ( add_fd , " displayName: %s \n " , aliasname ) ;
fprintf ( add_fd , " description: %s \n " , description ) ;
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
/* Return */
return NT_STATUS_OK ;
}
static NTSTATUS
fetch_groupmem_info_to_ldif ( SAM_DELTA_CTR * delta , SAM_DELTA_HDR * hdr_delta ,
GROUPMAP * groupmap , ACCOUNTMAP * accountmap ,
FILE * mod_fd , int alloced )
{
fstring group_dn ;
uint32 group_rid = 0 , rid = 0 ;
int i , j , k ;
/* Get the dn for the group */
if ( delta - > grp_mem_info . num_members > 0 ) {
group_rid = hdr_delta - > target_rid ;
for ( j = 0 ; j < alloced ; j + + ) {
if ( groupmap [ j ] . rid = = group_rid ) break ;
}
if ( j = = alloced ) {
DEBUG ( 1 , ( " Could not find rid %d in groupmap array \n " ,
group_rid ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
pstr_sprintf ( group_dn , " %s " , groupmap [ j ] . group_dn ) ;
fprintf ( mod_fd , " dn: %s \n " , group_dn ) ;
/* Get the cn for each member */
for ( i = 0 ; i < delta - > grp_mem_info . num_members ; i + + ) {
rid = delta - > grp_mem_info . rids [ i ] ;
for ( k = 0 ; k < alloced ; k + + ) {
if ( accountmap [ k ] . rid = = rid ) break ;
}
if ( k = = alloced ) {
DEBUG ( 1 , ( " Could not find rid %d in accountmap array \n " , rid ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
fprintf ( mod_fd , " memberUid: %s \n " , accountmap [ k ] . cn ) ;
}
fprintf ( mod_fd , " \n " ) ;
}
fflush ( mod_fd ) ;
/* Return */
return NT_STATUS_OK ;
}
static NTSTATUS
fetch_database_to_ldif ( struct cli_state * cli , unsigned db_type ,
DOM_CRED * ret_creds , DOM_SID dom_sid ,
const char * user_file )
{
char * suffix ;
const char * builtin_sid = " S-1-5-32 " ;
char * ldif_file ;
fstring sid , domainname ;
unsigned sync_context = 0 ;
NTSTATUS result ;
int k ;
TALLOC_CTX * mem_ctx ;
SAM_DELTA_HDR * hdr_deltas ;
SAM_DELTA_CTR * deltas ;
uint32 num_deltas ;
const char * add_ldif = " /tmp/add.ldif " , * mod_ldif = " /tmp/mod.ldif " ;
FILE * add_fd , * mod_fd , * ldif_fd ;
char sys_cmd [ 1024 ] ;
int num_alloced = 0 , g_index = 0 , a_index = 0 ;
/* Set up array for mapping accounts to groups */
/* Array element is the group rid */
GROUPMAP * groupmap = NULL ;
/* Set up array for mapping account rid's to cn's */
/* Array element is the account rid */
ACCOUNTMAP * accountmap = NULL ;
2005-07-13 03:02:31 +04:00
if ( ! ( mem_ctx = talloc_init ( " fetch_database " ) ) ) {
return NT_STATUS_NO_MEMORY ;
}
2005-07-07 01:02:43 +04:00
/* Ensure we have an output file */
if ( user_file )
2005-07-13 03:02:31 +04:00
ldif_file = talloc_strdup ( mem_ctx , user_file ) ;
2005-07-07 01:02:43 +04:00
else
2005-07-13 03:02:31 +04:00
ldif_file = talloc_strdup ( mem_ctx , " /tmp/tmp.ldif " ) ;
if ( ldif_file = = NULL )
return NT_STATUS_NO_MEMORY ;
2005-07-07 01:02:43 +04:00
/* Open the add and mod ldif files */
add_fd = fopen ( add_ldif , " a " ) ;
mod_fd = fopen ( mod_ldif , " a " ) ;
if ( add_fd = = NULL | | mod_fd = = NULL ) {
DEBUG ( 1 , ( " Could not open %s \n " , add_ldif ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
/* Open the user's ldif file */
ldif_fd = fopen ( ldif_file , " a " ) ;
if ( ldif_fd = = NULL ) {
DEBUG ( 1 , ( " Could not open %s \n " , ldif_file ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
/* Get the sid */
sid_to_string ( sid , & dom_sid ) ;
/* Get the ldap suffix */
suffix = lp_ldap_suffix ( ) ;
if ( suffix = = NULL | | strcmp ( suffix , " " ) = = 0 ) {
DEBUG ( 0 , ( " ldap suffix missing from smb.conf--exiting \n " ) ) ;
exit ( 1 ) ;
}
/* Get other smb.conf data */
if ( ! ( lp_workgroup ( ) ) | | ! * ( lp_workgroup ( ) ) ) {
DEBUG ( 0 , ( " workgroup missing from smb.conf--exiting \n " ) ) ;
exit ( 1 ) ;
}
/* Allocate initial memory for groupmap and accountmap arrays */
if ( init_ldap = = 1 ) {
groupmap = SMB_MALLOC_ARRAY ( GROUPMAP , 8 ) ;
accountmap = SMB_MALLOC_ARRAY ( ACCOUNTMAP , 8 ) ;
if ( groupmap = = NULL | | accountmap = = NULL ) {
DEBUG ( 1 , ( " GROUPMAP malloc failed \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
/* Initialize the arrays */
memset ( groupmap , 0 , sizeof ( GROUPMAP ) * 8 ) ;
memset ( accountmap , 0 , sizeof ( ACCOUNTMAP ) * 8 ) ;
/* Remember how many we malloced */
num_alloced = 8 ;
/* Initial database population */
populate_ldap_for_ldif ( sid , suffix , builtin_sid , add_fd ) ;
map_populate_groups ( groupmap , accountmap , sid , suffix ,
builtin_sid ) ;
/* Don't do this again */
init_ldap = 0 ;
}
/* Announce what we are doing */
switch ( db_type ) {
case SAM_DATABASE_DOMAIN :
d_printf ( " Fetching DOMAIN database \n " ) ;
break ;
case SAM_DATABASE_BUILTIN :
d_printf ( " Fetching BUILTIN database \n " ) ;
break ;
case SAM_DATABASE_PRIVS :
d_printf ( " Fetching PRIVS databases \n " ) ;
break ;
default :
d_printf ( " Fetching unknown database type %u \n " , db_type ) ;
break ;
}
do {
result = cli_netlogon_sam_sync ( cli , mem_ctx , ret_creds ,
db_type , sync_context ,
& num_deltas , & hdr_deltas ,
& deltas ) ;
if ( ! NT_STATUS_IS_OK ( result ) & &
! NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) ) {
return NT_STATUS_OK ;
}
clnt_deal_with_creds ( cli - > sess_key , & ( cli - > clnt_cred ) ,
ret_creds ) ;
/* Re-allocate memory for groupmap and accountmap arrays */
groupmap = SMB_REALLOC_ARRAY ( groupmap , GROUPMAP ,
num_deltas + num_alloced ) ;
accountmap = SMB_REALLOC_ARRAY ( accountmap , ACCOUNTMAP ,
num_deltas + num_alloced ) ;
if ( groupmap = = NULL | | accountmap = = NULL ) {
DEBUG ( 1 , ( " GROUPMAP malloc failed \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
/* Initialize the new records */
memset ( & groupmap [ num_alloced ] , 0 ,
sizeof ( GROUPMAP ) * num_deltas ) ;
memset ( & accountmap [ num_alloced ] , 0 ,
sizeof ( ACCOUNTMAP ) * num_deltas ) ;
/* Remember how many we alloced this time */
num_alloced + = num_deltas ;
/* Loop through the deltas */
for ( k = 0 ; k < num_deltas ; k + + ) {
switch ( hdr_deltas [ k ] . type ) {
case SAM_DELTA_DOMAIN_INFO :
/* Is this case needed? */
unistr2_to_ascii ( domainname ,
& deltas [ k ] . domain_info . uni_dom_name ,
sizeof ( domainname ) - 1 ) ;
break ;
case SAM_DELTA_GROUP_INFO :
fetch_group_info_to_ldif (
& deltas [ k ] , & groupmap [ g_index ] ,
add_fd , sid , suffix ) ;
g_index + + ;
break ;
case SAM_DELTA_ACCOUNT_INFO :
fetch_account_info_to_ldif (
& deltas [ k ] , groupmap ,
& accountmap [ a_index ] , add_fd ,
sid , suffix , num_alloced ) ;
a_index + + ;
break ;
case SAM_DELTA_ALIAS_INFO :
fetch_alias_info_to_ldif (
& deltas [ k ] , & groupmap [ g_index ] ,
add_fd , sid , suffix , db_type ) ;
g_index + + ;
break ;
case SAM_DELTA_GROUP_MEM :
fetch_groupmem_info_to_ldif (
& deltas [ k ] , & hdr_deltas [ k ] ,
groupmap , accountmap ,
mod_fd , num_alloced ) ;
break ;
case SAM_DELTA_ALIAS_MEM :
break ;
case SAM_DELTA_POLICY_INFO :
break ;
case SAM_DELTA_PRIVS_INFO :
break ;
case SAM_DELTA_TRUST_DOMS :
/* Implemented but broken */
break ;
case SAM_DELTA_SECRET_INFO :
/* Implemented but broken */
break ;
case SAM_DELTA_RENAME_GROUP :
/* Not yet implemented */
break ;
case SAM_DELTA_RENAME_USER :
/* Not yet implemented */
break ;
case SAM_DELTA_RENAME_ALIAS :
/* Not yet implemented */
break ;
case SAM_DELTA_DELETE_GROUP :
/* Not yet implemented */
break ;
case SAM_DELTA_DELETE_USER :
/* Not yet implemented */
break ;
case SAM_DELTA_MODIFIED_COUNT :
break ;
default :
break ;
} /* end of switch */
} /* end of for loop */
/* Increment sync_context */
sync_context + = 1 ;
} while ( NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) ) ;
/* Close the ldif files */
fclose ( add_fd ) ;
fclose ( mod_fd ) ;
/* Write ldif data to the user's file */
if ( db_type = = SAM_DATABASE_DOMAIN ) {
fprintf ( ldif_fd ,
" # SAM_DATABASE_DOMAIN: ADD ENTITIES \n " ) ;
fprintf ( ldif_fd ,
" # ================================= \n \n " ) ;
fflush ( ldif_fd ) ;
} else if ( db_type = = SAM_DATABASE_BUILTIN ) {
fprintf ( ldif_fd ,
" # SAM_DATABASE_BUILTIN: ADD ENTITIES \n " ) ;
fprintf ( ldif_fd ,
" # ================================== \n \n " ) ;
fflush ( ldif_fd ) ;
}
pstr_sprintf ( sys_cmd , " cat %s >> %s " , add_ldif , ldif_file ) ;
system ( sys_cmd ) ;
if ( db_type = = SAM_DATABASE_DOMAIN ) {
fprintf ( ldif_fd ,
" # SAM_DATABASE_DOMAIN: MODIFY ENTITIES \n " ) ;
fprintf ( ldif_fd ,
" # ==================================== \n \n " ) ;
fflush ( ldif_fd ) ;
} else if ( db_type = = SAM_DATABASE_BUILTIN ) {
fprintf ( ldif_fd ,
" # SAM_DATABASE_BUILTIN: MODIFY ENTITIES \n " ) ;
fprintf ( ldif_fd ,
" # ===================================== \n \n " ) ;
fflush ( ldif_fd ) ;
}
pstr_sprintf ( sys_cmd , " cat %s >> %s " , mod_ldif , ldif_file ) ;
system ( sys_cmd ) ;
/* Delete the temporary ldif files */
pstr_sprintf ( sys_cmd , " rm -f %s %s " , add_ldif , mod_ldif ) ;
system ( sys_cmd ) ;
/* Close the ldif file */
fclose ( ldif_fd ) ;
/* Deallocate memory for the mapping arrays */
SAFE_FREE ( groupmap ) ;
SAFE_FREE ( accountmap ) ;
/* Return */
talloc_destroy ( mem_ctx ) ;
return NT_STATUS_OK ;
}
/**
* Basic usage function for ' net rpc vampire '
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
* */
int rpc_vampire_usage ( int argc , const char * * argv )
{
d_printf ( " net rpc vampire [ldif [<ldif-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 " ) ;
net_common_flags_usage ( argc , argv ) ;
return - 1 ;
}
2002-09-18 10:34:10 +04:00
/* dump sam database via samsync rpc calls */
2004-02-08 13:59:09 +03:00
NTSTATUS rpc_vampire_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli , TALLOC_CTX * mem_ctx ,
int argc , const char * * argv )
2002-09-18 10:34:10 +04:00
{
NTSTATUS result ;
uchar trust_password [ 16 ] ;
DOM_CRED ret_creds ;
2004-02-08 13:59:09 +03:00
fstring my_dom_sid_str ;
fstring rem_dom_sid_str ;
2003-04-21 18:09:03 +04:00
uint32 sec_channel ;
2002-09-18 10:34:10 +04:00
ZERO_STRUCT ( ret_creds ) ;
2004-02-08 13:59:09 +03:00
if ( ! 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_to_string ( my_dom_sid_str ,
get_global_sam_sid ( ) ) ,
domain_name , sid_to_string ( rem_dom_sid_str , domain_sid ) ,
domain_name ) ;
return NT_STATUS_UNSUCCESSFUL ;
2002-09-18 10:34:10 +04:00
}
2004-02-08 13:59:09 +03:00
fstrcpy ( cli - > domain , domain_name ) ;
2002-09-18 10:34:10 +04:00
2004-02-08 13:59:09 +03:00
if ( ! secrets_fetch_trust_account_password ( domain_name ,
2003-04-21 18:09:03 +04:00
trust_password , NULL ,
& sec_channel ) ) {
2004-02-08 13:59:09 +03:00
result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO ;
2002-11-07 10:20:33 +03:00
d_printf ( " Could not retrieve domain trust secret \n " ) ;
2002-09-18 10:34:10 +04:00
goto fail ;
}
2004-02-08 13:59:09 +03:00
result = cli_nt_establish_netlogon ( cli , sec_channel , trust_password ) ;
2003-05-12 11:18:36 +04:00
2002-09-18 10:34:10 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Failed to setup BDC creds \n " ) ;
goto fail ;
}
2005-07-07 01:02:43 +04:00
if ( argc > = 1 & & ( strcmp ( argv [ 0 ] , " ldif " ) = = 0 ) ) {
result = fetch_database_to_ldif ( cli , SAM_DATABASE_DOMAIN ,
& ret_creds , * domain_sid , argv [ 1 ] ) ;
} else {
result = fetch_database ( cli , SAM_DATABASE_DOMAIN , & ret_creds ,
* domain_sid ) ;
}
2003-06-16 09:39:26 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Failed to fetch domain database: %s \n " ,
nt_errstr ( result ) ) ;
if ( NT_STATUS_EQUAL ( result , NT_STATUS_NOT_SUPPORTED ) )
d_printf ( " Perhaps %s is a Windows 2000 native mode "
2004-02-08 13:59:09 +03:00
" domain? \n " , domain_name ) ;
2003-06-16 09:39:26 +04:00
goto fail ;
}
2002-09-24 10:50:11 +04:00
2005-07-07 01:02:43 +04:00
if ( argc > = 1 & & ( strcmp ( argv [ 0 ] , " ldif " ) = = 0 ) ) {
result = fetch_database_to_ldif ( cli , SAM_DATABASE_BUILTIN ,
& ret_creds , global_sid_Builtin ,
argv [ 1 ] ) ;
} else {
result = fetch_database ( cli , SAM_DATABASE_BUILTIN , & ret_creds ,
global_sid_Builtin ) ;
}
2003-06-16 09:39:26 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
d_printf ( " Failed to fetch builtin database: %s \n " ,
nt_errstr ( result ) ) ;
goto fail ;
2004-02-08 13:59:09 +03:00
}
2002-09-18 10:34:10 +04:00
/* Currently we crash on PRIVS somewhere in unmarshalling */
/* Dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); */
fail :
2004-02-08 13:59:09 +03:00
return result ;
2002-09-18 10:34:10 +04:00
}
2005-07-07 01:02:43 +04:00