2008-02-15 16:13:11 +03:00
/*
2002-08-23 02:48:54 +04:00
Unix SMB / CIFS implementation .
dump the remote SAM using rpc samsync operations
Copyright ( C ) Andrew Tridgell 2002
Copyright ( C ) Tim Potter 2001 , 2002
2005-07-07 01:02:43 +04:00
Copyright ( C ) Jim McDonough < jmcd @ us . ibm . com > 2005
2002-10-01 22:26:00 +04:00
Modified by Volker Lendecke 2002
2005-09-30 21:13:37 +04:00
Copyright ( C ) Jeremy Allison 2005.
2008-02-27 21:38:48 +03:00
Copyright ( C ) Guenther Deschner 2008.
2002-08-23 02:48:54 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2002-08-23 02:48:54 +04:00
( at your option ) any later version .
2008-02-15 16:13:11 +03:00
2002-08-23 02:48:54 +04:00
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
2008-02-15 16:13:11 +03:00
2002-08-23 02:48:54 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2002-08-23 02:48:54 +04:00
*/
# include "includes.h"
2004-10-07 08:01:18 +04:00
# include "utils/net.h"
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 ;
2006-10-07 00:09:10 +04:00
/* Keep track of ldap initialization */
2005-07-07 01:02:43 +04:00
static int init_ldap = 1 ;
2008-02-15 16:13:11 +03:00
static void display_group_mem_info ( uint32_t rid ,
struct netr_DELTA_GROUP_MEMBER * r )
2002-08-23 02:48:54 +04:00
{
int i ;
d_printf ( " Group mem %u: " , rid ) ;
2008-02-15 16:13:11 +03:00
for ( i = 0 ; i < r - > num_rids ; i + + ) {
d_printf ( " %u " , r - > rids [ i ] ) ;
2002-08-23 02:48:54 +04:00
}
d_printf ( " \n " ) ;
}
2008-02-15 16:13:11 +03:00
static void display_alias_info ( uint32_t rid ,
struct netr_DELTA_ALIAS * r )
2002-08-23 02:48:54 +04:00
{
2008-02-15 16:13:11 +03:00
d_printf ( " Alias '%s' " , r - > alias_name . string ) ;
d_printf ( " desc='%s' rid=%u \n " , r - > description . string , r - > rid ) ;
2002-08-23 02:48:54 +04:00
}
2008-02-15 16:13:11 +03:00
static void display_alias_mem ( uint32_t rid ,
struct netr_DELTA_ALIAS_MEMBER * r )
2002-08-23 02:48:54 +04:00
{
int i ;
d_printf ( " Alias rid %u: " , rid ) ;
2008-02-15 16:13:11 +03:00
for ( i = 0 ; i < r - > sids . num_sids ; i + + ) {
d_printf ( " %s " , sid_string_tos ( r - > sids . sids [ i ] . sid ) ) ;
2002-08-23 02:48:54 +04:00
}
d_printf ( " \n " ) ;
}
2008-02-15 16:13:11 +03:00
static void display_account_info ( uint32_t rid ,
struct netr_DELTA_USER * r )
2002-08-23 02:48:54 +04:00
{
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) */
2008-02-15 16:13:11 +03:00
if ( memcmp ( r - > lmpassword . hash , zero_buf , 16 ) ! = 0 ) {
sam_pwd_hash ( r - > rid , r - > lmpassword . hash , lm_passwd , 0 ) ;
pdb_sethexpwd ( hex_lm_passwd , lm_passwd , r - > acct_flags ) ;
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
}
2008-02-15 16:13:11 +03:00
if ( memcmp ( r - > ntpassword . hash , zero_buf , 16 ) ! = 0 ) {
sam_pwd_hash ( r - > rid , r - > ntpassword . hash , nt_passwd , 0 ) ;
pdb_sethexpwd ( hex_nt_passwd , nt_passwd , r - > acct_flags ) ;
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
}
2008-02-15 16:13:11 +03:00
printf ( " %s:%d:%s:%s:%s:LCT-0 \n " ,
r - > account_name . string ,
r - > rid , hex_lm_passwd , hex_nt_passwd ,
pdb_encode_acct_ctrl ( r - > acct_flags , NEW_PW_FORMAT_SPACE_PADDED_LEN ) ) ;
2002-08-23 02:48:54 +04:00
}
2006-09-06 22:32:20 +04:00
static time_t uint64s_nt_time_to_unix_abs ( const uint64 * src )
2006-07-11 22:01:26 +04:00
{
NTTIME nttime ;
2006-09-06 22:32:20 +04:00
nttime = * src ;
2006-07-11 22:01:26 +04:00
return nt_time_to_unix_abs ( & nttime ) ;
}
2008-03-27 23:55:42 +03:00
static NTSTATUS pull_netr_AcctLockStr ( TALLOC_CTX * mem_ctx ,
struct lsa_BinaryString * r ,
struct netr_AcctLockStr * * str_p )
{
struct netr_AcctLockStr * str ;
enum ndr_err_code ndr_err ;
DATA_BLOB blob ;
if ( ! mem_ctx | | ! r | | ! str_p ) {
return NT_STATUS_INVALID_PARAMETER ;
}
* str_p = NULL ;
str = TALLOC_ZERO_P ( mem_ctx , struct netr_AcctLockStr ) ;
if ( ! str ) {
return NT_STATUS_NO_MEMORY ;
}
2008-03-28 11:56:21 +03:00
blob = data_blob_const ( r - > array , r - > length ) ;
2008-03-27 23:55:42 +03:00
ndr_err = ndr_pull_struct_blob ( & blob , mem_ctx , str ,
( ndr_pull_flags_fn_t ) ndr_pull_netr_AcctLockStr ) ;
data_blob_free ( & blob ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
return ndr_map_error2ntstatus ( ndr_err ) ;
}
* str_p = str ;
return NT_STATUS_OK ;
}
2008-02-15 16:13:11 +03:00
static void display_domain_info ( struct netr_DELTA_DOMAIN * r )
2002-08-29 14:36:05 +04:00
{
2004-12-20 15:52:33 +03:00
time_t u_logout ;
2008-03-27 23:55:42 +03:00
struct netr_AcctLockStr * lockstr = NULL ;
NTSTATUS status ;
TALLOC_CTX * mem_ctx = talloc_tos ( ) ;
status = pull_netr_AcctLockStr ( mem_ctx , & r - > account_lockout ,
& lockstr ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " failed to pull account lockout string: %s \n " ,
nt_errstr ( status ) ) ;
}
2004-12-20 15:52:33 +03:00
2008-02-15 16:13:11 +03:00
u_logout = uint64s_nt_time_to_unix_abs ( ( const uint64 * ) & r - > force_logoff_time ) ;
2004-12-20 15:52:33 +03:00
2008-02-15 16:13:11 +03:00
d_printf ( " Domain name: %s \n " , r - > domain_name . string ) ;
2004-12-20 15:52:33 +03:00
2008-02-15 16:13:11 +03:00
d_printf ( " Minimal Password Length: %d \n " , r - > min_password_length ) ;
d_printf ( " Password History Length: %d \n " , r - > password_history_length ) ;
2004-12-20 15:52:33 +03:00
d_printf ( " Force Logoff: %d \n " , ( int ) u_logout ) ;
2008-02-15 16:13:11 +03:00
d_printf ( " Max Password Age: %s \n " , display_time ( r - > max_password_age ) ) ;
d_printf ( " Min Password Age: %s \n " , display_time ( r - > min_password_age ) ) ;
2004-12-20 15:52:33 +03:00
2008-03-27 23:55:42 +03:00
if ( lockstr ) {
d_printf ( " Lockout Time: %s \n " , display_time ( ( NTTIME ) lockstr - > lockout_duration ) ) ;
d_printf ( " Lockout Reset Time: %s \n " , display_time ( ( NTTIME ) lockstr - > reset_count ) ) ;
d_printf ( " Bad Attempt Lockout: %d \n " , lockstr - > bad_attempt_lockout ) ;
}
2008-02-15 16:13:11 +03:00
d_printf ( " User must logon to change password: %d \n " , r - > logon_to_chgpass ) ;
2002-08-29 14:36:05 +04:00
}
2008-02-15 16:13:11 +03:00
static void display_group_info ( uint32_t rid , struct netr_DELTA_GROUP * r )
2002-08-29 14:36:05 +04:00
{
2008-02-15 16:13:11 +03:00
d_printf ( " Group '%s' " , r - > group_name . string ) ;
d_printf ( " desc='%s', rid=%u \n " , r - > description . string , rid ) ;
2002-08-29 14:36:05 +04:00
}
2008-02-15 16:13:11 +03:00
static void display_sam_entry ( struct netr_DELTA_ENUM * r )
2002-08-23 02:48:54 +04:00
{
2008-02-15 16:13:11 +03:00
union netr_DELTA_UNION u = r - > delta_union ;
union netr_DELTA_ID_UNION id = r - > delta_id_union ;
switch ( r - > delta_type ) {
case NETR_DELTA_DOMAIN :
display_domain_info ( u . domain ) ;
break ;
case NETR_DELTA_GROUP :
display_group_info ( id . rid , u . group ) ;
break ;
#if 0
case NETR_DELTA_DELETE_GROUP :
printf ( " Delete Group: %d \n " ,
u . delete_account . unknown ) ;
break ;
case NETR_DELTA_RENAME_GROUP :
printf ( " Rename Group: %s -> %s \n " ,
u . rename_group - > OldName . string ,
u . rename_group - > NewName . string ) ;
break ;
# endif
case NETR_DELTA_USER :
display_account_info ( id . rid , u . user ) ;
break ;
#if 0
case NETR_DELTA_DELETE_USER :
printf ( " Delete User: %d \n " ,
id . rid ) ;
break ;
case NETR_DELTA_RENAME_USER :
printf ( " Rename user: %s -> %s \n " ,
u . rename_user - > OldName . string ,
u . rename_user - > NewName . string ) ;
break ;
# endif
case NETR_DELTA_GROUP_MEMBER :
display_group_mem_info ( id . rid , u . group_member ) ;
break ;
case NETR_DELTA_ALIAS :
display_alias_info ( id . rid , u . alias ) ;
break ;
#if 0
case NETR_DELTA_DELETE_ALIAS :
printf ( " Delete Alias: %d \n " ,
id . rid ) ;
break ;
case NETR_DELTA_RENAME_ALIAS :
printf ( " Rename alias: %s -> %s \n " ,
u . rename_alias - > OldName . string ,
u . rename_alias - > NewName . string ) ;
break ;
# endif
case NETR_DELTA_ALIAS_MEMBER :
display_alias_mem ( id . rid , u . alias_member ) ;
break ;
#if 0
case NETR_DELTA_POLICY :
printf ( " Policy \n " ) ;
break ;
case NETR_DELTA_TRUSTED_DOMAIN :
printf ( " Trusted Domain: %s \n " ,
u . trusted_domain - > domain_name . string ) ;
break ;
case NETR_DELTA_DELETE_TRUST :
printf ( " Delete Trust: %d \n " ,
u . delete_trust . unknown ) ;
break ;
case NETR_DELTA_ACCOUNT :
printf ( " Account \n " ) ;
break ;
case NETR_DELTA_DELETE_ACCOUNT :
printf ( " Delete Account: %d \n " ,
u . delete_account . unknown ) ;
2002-08-23 02:48:54 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_SECRET :
printf ( " Secret \n " ) ;
2002-08-23 02:48:54 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_DELETE_SECRET :
printf ( " Delete Secret: %d \n " ,
u . delete_secret . unknown ) ;
break ;
case NETR_DELTA_DELETE_GROUP2 :
printf ( " Delete Group2: %s \n " ,
u . delete_group - > account_name ) ;
break ;
case NETR_DELTA_DELETE_USER2 :
printf ( " Delete User2: %s \n " ,
u . delete_user - > account_name ) ;
break ;
case NETR_DELTA_MODIFY_COUNT :
printf ( " sam sequence update: 0x%016llx \n " ,
( unsigned long long ) * u . modified_count ) ;
break ;
# endif
/* The following types are recognised but not handled */
case NETR_DELTA_RENAME_GROUP :
d_printf ( " NETR_DELTA_RENAME_GROUP not handled \n " ) ;
2002-08-23 02:48:54 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_RENAME_USER :
d_printf ( " NETR_DELTA_RENAME_USER not handled \n " ) ;
2002-08-23 02:48:54 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_RENAME_ALIAS :
d_printf ( " NETR_DELTA_RENAME_ALIAS not handled \n " ) ;
2002-08-29 14:36:05 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_POLICY :
d_printf ( " NETR_DELTA_POLICY not handled \n " ) ;
2002-08-29 14:36:05 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_TRUSTED_DOMAIN :
d_printf ( " NETR_DELTA_TRUSTED_DOMAIN not handled \n " ) ;
2003-03-23 05:22:41 +03:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_ACCOUNT :
d_printf ( " NETR_DELTA_ACCOUNT not handled \n " ) ;
2003-03-23 05:22:41 +03:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_SECRET :
d_printf ( " NETR_DELTA_SECRET not handled \n " ) ;
2003-03-23 05:22:41 +03:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_DELETE_GROUP :
d_printf ( " NETR_DELTA_DELETE_GROUP not handled \n " ) ;
2003-03-23 05:22:41 +03:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_DELETE_USER :
d_printf ( " NETR_DELTA_DELETE_USER not handled \n " ) ;
2003-03-23 05:22:41 +03:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_MODIFY_COUNT :
d_printf ( " NETR_DELTA_MODIFY_COUNT not handled \n " ) ;
2003-03-23 05:22:41 +03:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_DELETE_ALIAS :
d_printf ( " NETR_DELTA_DELETE_ALIAS not handled \n " ) ;
2003-03-23 05:22:41 +03:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_DELETE_TRUST :
d_printf ( " NETR_DELTA_DELETE_TRUST not handled \n " ) ;
2003-03-23 05:22:41 +03:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_DELETE_ACCOUNT :
d_printf ( " NETR_DELTA_DELETE_ACCOUNT not handled \n " ) ;
2003-03-23 05:22:41 +03:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_DELETE_SECRET :
d_printf ( " NETR_DELTA_DELETE_SECRET not handled \n " ) ;
break ;
case NETR_DELTA_DELETE_GROUP2 :
d_printf ( " NETR_DELTA_DELETE_GROUP2 not handled \n " ) ;
break ;
case NETR_DELTA_DELETE_USER2 :
d_printf ( " NETR_DELTA_DELETE_USER2 not handled \n " ) ;
2003-03-23 05:22:41 +03:00
break ;
2002-08-23 02:48:54 +04:00
default :
2008-02-15 16:13:11 +03:00
printf ( " unknown delta type 0x%02x \n " ,
r - > delta_type ) ;
2002-08-23 02:48:54 +04:00
break ;
}
}
2008-03-27 23:04:31 +03:00
static void dump_database ( struct rpc_pipe_client * pipe_hnd ,
enum netr_SamDatabaseID database_id )
2002-08-23 02:48:54 +04:00
{
2002-08-29 12:00:15 +04:00
NTSTATUS result ;
int i ;
TALLOC_CTX * mem_ctx ;
2008-04-19 23:56:43 +04:00
const char * logon_server = pipe_hnd - > desthost ;
2008-02-15 16:13:11 +03:00
const char * computername = global_myname ( ) ;
struct netr_Authenticator credential ;
struct netr_Authenticator return_authenticator ;
uint16_t restart_state = 0 ;
uint32_t sync_context = 0 ;
2002-08-29 12:00:15 +04:00
2008-03-29 02:49:09 +03:00
ZERO_STRUCT ( return_authenticator ) ;
2002-12-20 23:21:31 +03:00
if ( ! ( mem_ctx = talloc_init ( " dump_database " ) ) ) {
2002-08-29 12:00:15 +04:00
return ;
}
2008-03-27 23:04:31 +03:00
switch ( database_id ) {
2003-03-23 05:22:41 +03:00
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 :
2008-03-27 23:04:31 +03:00
d_printf ( " Dumping unknown database type %u \n " ,
database_id ) ;
2003-03-23 05:22:41 +03:00
break ;
}
2002-08-29 12:00:15 +04:00
do {
2008-02-15 16:13:11 +03:00
struct netr_DELTA_ENUM_ARRAY * delta_enum_array = NULL ;
netlogon_creds_client_step ( pipe_hnd - > dc , & credential ) ;
result = rpccli_netr_DatabaseSync2 ( pipe_hnd , mem_ctx ,
logon_server ,
computername ,
& credential ,
& return_authenticator ,
database_id ,
restart_state ,
& sync_context ,
& delta_enum_array ,
0xffff ) ;
/* Check returned credentials. */
if ( ! netlogon_creds_client_check ( pipe_hnd - > dc ,
& return_authenticator . cred ) ) {
DEBUG ( 0 , ( " credentials chain check failed \n " ) ) ;
return ;
}
if ( NT_STATUS_IS_ERR ( result ) ) {
2003-10-14 07:50:27 +04:00
break ;
2008-02-15 16:13:11 +03:00
}
2003-10-14 07:50:27 +04:00
2008-02-15 16:13:11 +03:00
/* Display results */
for ( i = 0 ; i < delta_enum_array - > num_deltas ; i + + ) {
display_sam_entry ( & delta_enum_array - > delta_enum [ i ] ) ;
2002-08-29 12:00:15 +04:00
}
2008-02-15 16:13:11 +03:00
TALLOC_FREE ( delta_enum_array ) ;
2002-11-02 06:47:48 +03:00
} 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 */
2008-02-15 16:13:11 +03:00
NTSTATUS rpc_samdump_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
2005-09-30 21:13:37 +04:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-02-15 16:13:11 +03:00
TALLOC_CTX * mem_ctx ,
2005-09-30 21:13:37 +04:00
int argc ,
2008-02-15 16:13:11 +03:00
const char * * argv )
2002-08-29 12:00:15 +04:00
{
2005-09-30 21:13:37 +04:00
#if 0
/* net_rpc.c now always tries to create an schannel pipe.. */
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 ] ;
2008-04-02 04:29:48 +04:00
uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS ;
2005-09-30 21:13:37 +04:00
uint32 sec_channel_type = 0 ;
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 ,
2005-09-30 21:13:37 +04:00
NULL , & sec_channel_type ) ) {
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
2005-09-30 21:13:37 +04:00
nt_status = rpccli_netlogon_setup_creds ( pipe_hnd ,
cli - > desthost ,
domain_name ,
global_myname ( ) ,
trust_password ,
sec_channel_type ,
& neg_flags ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
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 ;
}
2005-09-30 21:13:37 +04:00
# endif
2002-08-23 02:48:54 +04:00
2005-09-30 21:13:37 +04:00
dump_database ( pipe_hnd , SAM_DATABASE_DOMAIN ) ;
dump_database ( pipe_hnd , SAM_DATABASE_BUILTIN ) ;
dump_database ( pipe_hnd , SAM_DATABASE_PRIVS ) ;
2002-08-23 02:48:54 +04:00
2005-09-30 21:13:37 +04:00
return NT_STATUS_OK ;
2002-08-23 02:48:54 +04:00
}
2002-09-18 10:34:10 +04:00
2006-02-20 23:09:36 +03:00
/* Convert a struct samu_DELTA to a struct samu. */
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
2006-03-08 11:51:19 +03:00
# define STRING_CHANGED_NC(s1,s2) ((s1) && !(s2)) ||\
( ! ( s1 ) & & ( s2 ) ) | | \
( ( s1 ) & & ( s2 ) & & ( strcmp ( ( s1 ) , ( s2 ) ) ! = 0 ) )
2008-02-15 16:13:11 +03:00
static NTSTATUS sam_account_from_delta ( struct samu * account ,
struct netr_DELTA_USER * r )
2002-09-18 10:34:10 +04:00
{
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 . */
2008-02-15 16:13:11 +03:00
if ( r - > account_name . string ) {
2003-03-23 05:22:41 +03:00
old_string = pdb_get_nt_username ( account ) ;
2008-02-15 16:13:11 +03:00
new_string = r - > account_name . string ;
2003-03-23 05:22:41 +03:00
if ( STRING_CHANGED ) {
pdb_set_nt_username ( account , new_string , PDB_CHANGED ) ;
}
2008-02-15 16:13:11 +03:00
2003-03-23 05:22:41 +03:00
/* Unix username is the same - for sanity */
old_string = pdb_get_username ( account ) ;
if ( STRING_CHANGED ) {
pdb_set_username ( account , new_string , PDB_CHANGED ) ;
}
}
2008-02-15 16:13:11 +03:00
if ( r - > full_name . string ) {
2003-03-23 05:22:41 +03:00
old_string = pdb_get_fullname ( account ) ;
2008-02-15 16:13:11 +03:00
new_string = r - > full_name . string ;
2003-03-23 05:22:41 +03:00
if ( STRING_CHANGED )
pdb_set_fullname ( account , new_string , PDB_CHANGED ) ;
}
2002-09-18 10:34:10 +04:00
2008-02-15 16:13:11 +03:00
if ( r - > home_directory . string ) {
2003-03-23 05:22:41 +03:00
old_string = pdb_get_homedir ( account ) ;
2008-02-15 16:13:11 +03:00
new_string = r - > home_directory . string ;
2003-03-23 05:22:41 +03:00
if ( STRING_CHANGED )
pdb_set_homedir ( account , new_string , PDB_CHANGED ) ;
}
2002-09-18 10:34:10 +04:00
2008-02-15 16:13:11 +03:00
if ( r - > home_drive . string ) {
2003-03-23 05:22:41 +03:00
old_string = pdb_get_dir_drive ( account ) ;
2008-02-15 16:13:11 +03:00
new_string = r - > home_drive . string ;
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
2008-02-15 16:13:11 +03:00
if ( r - > logon_script . string ) {
2003-03-23 05:22:41 +03:00
old_string = pdb_get_logon_script ( account ) ;
2008-02-15 16:13:11 +03:00
new_string = r - > logon_script . string ;
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
2008-02-15 16:13:11 +03:00
if ( r - > description . string ) {
2003-03-23 05:22:41 +03:00
old_string = pdb_get_acct_desc ( account ) ;
2008-02-15 16:13:11 +03:00
new_string = r - > description . string ;
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
2008-02-15 16:13:11 +03:00
if ( r - > workstations . string ) {
2003-03-23 05:22:41 +03:00
old_string = pdb_get_workstations ( account ) ;
2008-02-15 16:13:11 +03:00
new_string = r - > workstations . string ;
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
2008-02-15 16:13:11 +03:00
if ( r - > profile_path . string ) {
2003-03-23 05:22:41 +03:00
old_string = pdb_get_profile_path ( account ) ;
2008-02-15 16:13:11 +03:00
new_string = r - > profile_path . string ;
2003-03-23 05:22:41 +03:00
if ( STRING_CHANGED )
pdb_set_profile_path ( account , new_string , PDB_CHANGED ) ;
}
2008-02-15 16:13:11 +03:00
if ( r - > parameters . string ) {
2004-12-24 03:38:22 +03:00
DATA_BLOB mung ;
2006-03-08 11:51:19 +03:00
char * newstr ;
2004-12-10 12:45:03 +03:00
old_string = pdb_get_munged_dial ( account ) ;
2008-02-15 16:13:11 +03:00
mung . length = r - > parameters . length ;
mung . data = ( uint8 * ) r - > parameters . string ;
2008-01-19 04:12:35 +03:00
newstr = ( mung . length = = 0 ) ? NULL :
base64_encode_data_blob ( talloc_tos ( ) , mung ) ;
2004-12-10 12:45:03 +03:00
2006-03-08 11:51:19 +03:00
if ( STRING_CHANGED_NC ( old_string , newstr ) )
pdb_set_munged_dial ( account , newstr , PDB_CHANGED ) ;
2007-10-28 21:15:08 +03:00
TALLOC_FREE ( newstr ) ;
2004-12-10 12:45:03 +03:00
}
2003-03-23 05:22:41 +03:00
/* User and group sid */
2008-02-15 16:13:11 +03:00
if ( pdb_get_user_rid ( account ) ! = r - > rid )
pdb_set_user_sid_from_rid ( account , r - > rid , PDB_CHANGED ) ;
if ( pdb_get_group_rid ( account ) ! = r - > primary_gid )
pdb_set_group_sid_from_rid ( account , r - > primary_gid , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
/* Logon and password information */
2008-02-15 16:13:11 +03:00
if ( ! nt_time_is_zero ( & r - > last_logon ) ) {
unix_time = nt_time_to_unix ( r - > last_logon ) ;
2003-03-23 05:22:41 +03:00
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
2008-02-15 16:13:11 +03:00
if ( ! nt_time_is_zero ( & r - > last_logoff ) ) {
unix_time = nt_time_to_unix ( r - > last_logoff ) ;
2003-03-23 05:22:41 +03:00
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 */
2008-02-15 16:13:11 +03:00
if ( pdb_get_logon_divs ( account ) ! = r - > logon_hours . units_per_week )
pdb_set_logon_divs ( account , r - > logon_hours . units_per_week , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
2008-02-15 16:13:11 +03:00
#if 0
/* no idea what to do with this one - gd */
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 ) ;
}
2008-02-15 16:13:11 +03:00
# endif
2004-12-24 03:08:15 +03:00
/* Logon Hours Len */
2008-02-15 16:13:11 +03:00
if ( r - > logon_hours . units_per_week / 8 ! = pdb_get_hours_len ( account ) ) {
pdb_set_hours_len ( account , r - > logon_hours . units_per_week / 8 , PDB_CHANGED ) ;
2004-12-24 03:08:15 +03:00
}
/* Logon Hours */
2008-02-15 16:13:11 +03:00
if ( r - > logon_hours . bits ) {
2007-12-05 01:02:25 +03:00
char oldstr [ 44 ] , newstr [ 44 ] ;
2005-06-25 00:25:18 +04:00
pdb_sethexhours ( oldstr , pdb_get_hours ( account ) ) ;
2008-02-15 16:13:11 +03:00
pdb_sethexhours ( newstr , r - > logon_hours . bits ) ;
2005-06-25 00:25:18 +04:00
if ( ! strequal ( oldstr , newstr ) )
2008-02-15 16:13:11 +03:00
pdb_set_hours ( account , r - > logon_hours . bits , PDB_CHANGED ) ;
2004-12-24 03:08:15 +03:00
}
2008-02-15 16:13:11 +03:00
if ( pdb_get_bad_password_count ( account ) ! = r - > bad_password_count )
pdb_set_bad_password_count ( account , r - > bad_password_count , PDB_CHANGED ) ;
2004-12-10 13:42:47 +03:00
2008-02-15 16:13:11 +03:00
if ( pdb_get_logon_count ( account ) ! = r - > logon_count )
pdb_set_logon_count ( account , r - > logon_count , PDB_CHANGED ) ;
2002-09-18 10:34:10 +04:00
2008-02-15 16:13:11 +03:00
if ( ! nt_time_is_zero ( & r - > last_password_change ) ) {
unix_time = nt_time_to_unix ( r - > last_password_change ) ;
2003-03-23 05:22:41 +03:00
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
2008-02-15 16:13:11 +03:00
if ( ! nt_time_is_zero ( & r - > acct_expiry ) ) {
unix_time = nt_time_to_unix ( r - > acct_expiry ) ;
2003-03-23 05:22:41 +03:00
stored_time = pdb_get_kickoff_time ( account ) ;
if ( stored_time ! = unix_time )
pdb_set_kickoff_time ( account , unix_time , PDB_CHANGED ) ;
}
2002-09-24 10:50:11 +04:00
2008-02-15 16:13:11 +03:00
/* Decode hashes from password hash
Note that win2000 may send us all zeros for the hashes if it doesn ' t
2002-11-10 06:07:19 +03:00
think this channel is secure enough - don ' t set the passwords at all
in that case
2003-03-23 05:22:41 +03:00
*/
2008-02-15 16:13:11 +03:00
if ( memcmp ( r - > ntpassword . hash , zero_buf , 16 ) ! = 0 ) {
sam_pwd_hash ( r - > rid , r - > ntpassword . hash , lm_passwd , 0 ) ;
2002-11-10 06:07:19 +03:00
pdb_set_lanman_passwd ( account , lm_passwd , PDB_CHANGED ) ;
}
2008-02-15 16:13:11 +03:00
if ( memcmp ( r - > lmpassword . hash , zero_buf , 16 ) ! = 0 ) {
sam_pwd_hash ( r - > rid , r - > lmpassword . hash , nt_passwd , 0 ) ;
2002-11-10 06:07:19 +03:00
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 */
2008-02-15 16:13:11 +03:00
pdb_set_acct_ctrl ( account , r - > acct_flags , PDB_CHANGED ) ;
2003-03-23 05:22:41 +03:00
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 ;
}
2008-02-15 16:13:11 +03:00
static NTSTATUS fetch_account_info ( uint32_t rid ,
struct netr_DELTA_USER * r )
2002-09-18 10:34:10 +04:00
{
2008-02-15 16:13:11 +03:00
2006-03-07 19:29:25 +03:00
NTSTATUS nt_ret = NT_STATUS_UNSUCCESSFUL ;
2002-09-18 10:34:10 +04:00
fstring account ;
2007-12-05 01:02:25 +03:00
char * add_script = NULL ;
2006-02-20 23:09:36 +03:00
struct samu * 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
2008-02-15 16:13:11 +03:00
fstrcpy ( account , r - > account_name . string ) ;
2002-09-18 10:34:10 +04:00
d_printf ( " Creating account: %s \n " , account ) ;
2006-02-21 17:34:11 +03:00
if ( ! ( sam_account = samu_new ( NULL ) ) ) {
return NT_STATUS_NO_MEMORY ;
}
2002-09-18 10:34:10 +04:00
2007-12-19 17:02:59 +03:00
if ( ! ( passwd = Get_Pwnam_alloc ( sam_account , account ) ) ) {
2002-09-18 10:34:10 +04:00
/* Create appropriate user */
2008-02-15 16:13:11 +03:00
if ( r - > acct_flags & ACB_NORMAL ) {
2007-12-05 01:02:25 +03:00
add_script = talloc_strdup ( sam_account ,
lp_adduser_script ( ) ) ;
2008-02-15 16:13:11 +03:00
} else if ( ( r - > acct_flags & ACB_WSTRUST ) | |
( r - > acct_flags & ACB_SVRTRUST ) | |
( r - > acct_flags & ACB_DOMTRUST ) ) {
2007-12-05 01:02:25 +03:00
add_script = talloc_strdup ( sam_account ,
lp_addmachine_script ( ) ) ;
2002-09-18 10:34:10 +04:00
} else {
DEBUG ( 1 , ( " Unknown user type: %s \n " ,
2008-02-15 16:13:11 +03:00
pdb_encode_acct_ctrl ( r - > acct_flags , 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
}
2007-12-05 01:02:25 +03:00
if ( ! add_script ) {
nt_ret = NT_STATUS_NO_MEMORY ;
goto done ;
}
2002-09-18 10:34:10 +04:00
if ( * add_script ) {
int add_ret ;
2007-12-05 01:02:25 +03:00
add_script = talloc_all_string_sub ( sam_account ,
add_script ,
" %u " ,
account ) ;
if ( ! add_script ) {
nt_ret = NT_STATUS_NO_MEMORY ;
goto done ;
}
2002-09-18 10:34:10 +04:00
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 ) ) ;
2006-09-20 04:15:50 +04:00
if ( add_ret = = 0 ) {
smb_nscd_flush_user_cache ( ) ;
}
2005-09-30 21:13:37 +04:00
}
2007-12-05 01:02:25 +03:00
2003-07-09 20:44:47 +04:00
/* try and find the possible unix account again */
2007-12-19 17:02:59 +03:00
if ( ! ( passwd = Get_Pwnam_alloc ( sam_account , account ) ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not create posix account info for '%s' \n " , account ) ;
2003-09-10 10:58:41 +04:00
nt_ret = NT_STATUS_NO_SUCH_USER ;
goto done ;
}
2002-09-18 10:34:10 +04:00
}
2007-12-05 01:02:25 +03:00
2003-07-05 13:46:12 +04:00
sid_copy ( & user_sid , get_global_sam_sid ( ) ) ;
2008-02-15 16:13:11 +03:00
sid_append_rid ( & user_sid , r - > rid ) ;
2002-09-18 10:34:10 +04:00
2007-12-16 00:47:30 +03:00
DEBUG ( 3 , ( " Attempting to find SID %s for user %s in the passdb \n " ,
sid_to_fstring ( sid_string , & user_sid ) , account ) ) ;
2003-07-05 13:46:12 +04:00
if ( ! pdb_getsampwsid ( sam_account , & user_sid ) ) {
2008-02-15 16:13:11 +03:00
sam_account_from_delta ( sam_account , r ) ;
DEBUG ( 3 , ( " Attempting to add user SID %s for user %s in the passdb \n " ,
2007-12-16 00:47:30 +03:00
sid_to_fstring ( sid_string , & user_sid ) ,
pdb_get_username ( sam_account ) ) ) ;
2006-02-13 20:08:25 +03:00
if ( ! NT_STATUS_IS_OK ( pdb_add_sam_account ( sam_account ) ) ) {
2003-07-05 13:46:12 +04:00
DEBUG ( 1 , ( " SAM Account for %s failed to be added to the passdb! \n " ,
account ) ) ;
2008-02-15 16:13:11 +03:00
return NT_STATUS_ACCESS_DENIED ;
2003-07-05 13:46:12 +04:00
}
} else {
2008-02-15 16:13:11 +03:00
sam_account_from_delta ( sam_account , r ) ;
DEBUG ( 3 , ( " Attempting to update user SID %s for user %s in the passdb \n " ,
2007-12-16 00:47:30 +03:00
sid_to_fstring ( sid_string , & user_sid ) ,
pdb_get_username ( sam_account ) ) ) ;
2006-02-04 01:19:41 +03:00
if ( ! NT_STATUS_IS_OK ( pdb_update_sam_account ( sam_account ) ) ) {
2003-01-29 21:47:57 +03:00
DEBUG ( 1 , ( " SAM Account for %s failed to be updated in the passdb! \n " ,
account ) ) ;
2006-02-20 23:09:36 +03:00
TALLOC_FREE ( sam_account ) ;
2008-02-15 16:13:11 +03:00
return NT_STATUS_ACCESS_DENIED ;
2003-01-29 21:47:57 +03:00
}
2002-09-24 10:50:11 +04:00
}
2006-06-19 23:07:39 +04:00
if ( pdb_get_group_sid ( sam_account ) = = NULL ) {
return NT_STATUS_UNSUCCESSFUL ;
}
2003-07-05 13:46:12 +04:00
group_sid = * pdb_get_group_sid ( sam_account ) ;
2002-11-07 10:20:33 +03:00
2006-08-15 18:07:15 +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 ) ) ) {
2008-02-15 16:13:11 +03:00
DEBUG ( 0 , ( " Could not find unix group %lu for user %s (group SID=%s) \n " ,
2007-12-15 23:53:26 +03:00
( unsigned long ) map . gid , pdb_get_username ( sam_account ) , sid_string_tos ( & group_sid ) ) ) ;
2003-07-05 13:46:12 +04:00
} else {
smb_set_primary_group ( grp - > gr_name , pdb_get_username ( sam_account ) ) ;
}
}
2007-12-05 01:02:25 +03:00
}
2003-07-05 13:46:12 +04:00
2003-07-16 06:20:53 +04:00
if ( ! passwd ) {
2008-02-15 16:13:11 +03:00
DEBUG ( 1 , ( " No unix user for this account (%s), cannot adjust mappings \n " ,
2003-07-16 06:20:53 +04:00
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 :
2006-02-20 23:09:36 +03:00
TALLOC_FREE ( sam_account ) ;
2003-06-14 04:49:02 +04:00
return nt_ret ;
2002-09-18 10:34:10 +04:00
}
2008-02-15 16:13:11 +03:00
static NTSTATUS fetch_group_info ( uint32_t rid ,
struct netr_DELTA_GROUP * r )
2002-09-18 10:34:10 +04:00
{
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 ;
2007-10-19 04:40:25 +04:00
bool insert = True ;
2002-09-18 10:34:10 +04:00
2008-02-15 16:13:11 +03:00
fstrcpy ( name , r - > group_name . string ) ;
fstrcpy ( comment , r - > description . string ) ;
2002-09-18 10:34:10 +04:00
/* add the group to the mapping table */
sid_copy ( & group_sid , get_global_sam_sid ( ) ) ;
sid_append_rid ( & group_sid , rid ) ;
2007-12-16 00:47:30 +03:00
sid_to_fstring ( sid_string , & group_sid ) ;
2002-09-18 10:34:10 +04:00
2006-08-15 18:07:15 +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 ) {
2008-02-15 16:13:11 +03:00
2003-03-23 05:22:41 +03:00
/* No appropriate group found, create one */
2008-02-15 16:13:11 +03:00
2002-09-24 10:50:11 +04:00
d_printf ( " Creating unix group: '%s' \n " , name ) ;
2008-02-15 16:13:11 +03:00
2002-10-01 22:26:00 +04:00
if ( smb_create_group ( name , & gid ) ! = 0 )
return NT_STATUS_ACCESS_DENIED ;
2008-02-15 16:13:11 +03:00
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 ) ;
2008-02-15 16:13:11 +03:00
if ( r - > description . string ) {
2003-08-07 06:59:52 +04:00
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 ;
}
2008-02-15 16:13:11 +03:00
static NTSTATUS fetch_group_mem_info ( uint32_t rid ,
struct netr_DELTA_GROUP_MEMBER * r )
2002-09-24 10:50:11 +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 ;
2008-02-15 16:13:11 +03:00
if ( r - > num_rids = = 0 ) {
2002-09-24 10:50:11 +04:00
return NT_STATUS_OK ;
}
sid_copy ( & group_sid , get_global_sam_sid ( ) ) ;
sid_append_rid ( & group_sid , rid ) ;
2006-08-15 18:07:15 +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 ;
}
2008-02-15 16:13:11 +03:00
if ( r - > num_rids ) {
if ( ( nt_members = TALLOC_ZERO_ARRAY ( t , char * , r - > num_rids ) ) = = NULL ) {
2007-04-30 06:51:26 +04:00
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
talloc_free ( t ) ;
return NT_STATUS_NO_MEMORY ;
}
} else {
nt_members = NULL ;
2006-06-19 23:07:39 +04:00
}
2002-09-24 10:50:11 +04:00
2008-02-15 16:13:11 +03:00
for ( i = 0 ; i < r - > num_rids ; i + + ) {
2006-02-20 23:09:36 +03:00
struct samu * member = NULL ;
2002-09-24 10:50:11 +04:00
DOM_SID member_sid ;
2006-02-21 17:34:11 +03:00
if ( ! ( member = samu_new ( t ) ) ) {
2002-09-24 10:50:11 +04:00
talloc_destroy ( t ) ;
2006-02-21 17:34:11 +03:00
return NT_STATUS_NO_MEMORY ;
2002-09-24 10:50:11 +04:00
}
sid_copy ( & member_sid , get_global_sam_sid ( ) ) ;
2008-02-15 16:13:11 +03:00
sid_append_rid ( & member_sid , r - > rids [ i ] ) ;
2002-09-24 10:50:11 +04:00
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 " ,
2008-02-15 16:13:11 +03:00
r - > rids [ i ] , sid_string_tos ( & member_sid ) , grp - > gr_name ) ) ;
2006-02-20 23:09:36 +03:00
TALLOC_FREE ( member ) ;
2002-09-24 10:50:11 +04:00
continue ;
}
if ( pdb_get_group_rid ( member ) = = rid ) {
d_printf ( " %s(primary), " , pdb_get_username ( member ) ) ;
2006-02-20 23:09:36 +03:00
TALLOC_FREE ( member ) ;
2002-09-24 10:50:11 +04:00
continue ;
}
2008-02-15 16:13:11 +03:00
2002-09-24 10:50:11 +04:00
d_printf ( " %s, " , pdb_get_username ( member ) ) ;
nt_members [ i ] = talloc_strdup ( t , pdb_get_username ( member ) ) ;
2006-02-20 23:09:36 +03:00
TALLOC_FREE ( member ) ;
2002-09-24 10:50:11 +04:00
}
d_printf ( " \n " ) ;
unix_members = grp - > gr_mem ;
while ( * unix_members ) {
2007-10-19 04:40:25 +04:00
bool is_nt_member = False ;
2008-02-15 16:13:11 +03:00
for ( i = 0 ; i < r - > num_rids ; i + + ) {
2002-09-24 10:50:11 +04:00
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 ;
}
2008-02-15 16:13:11 +03:00
for ( i = 0 ; i < r - > num_rids ; i + + ) {
2007-10-19 04:40:25 +04:00
bool is_unix_member = False ;
2002-09-24 10:50:11 +04:00
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 ] ) ;
}
}
2008-02-15 16:13:11 +03:00
2002-09-24 10:50:11 +04:00
talloc_destroy ( t ) ;
return NT_STATUS_OK ;
}
2008-02-15 16:13:11 +03:00
static NTSTATUS fetch_alias_info ( uint32_t rid ,
struct netr_DELTA_ALIAS * r ,
2002-09-24 10:50:11 +04:00
DOM_SID dom_sid )
{
fstring name ;
fstring comment ;
struct group * grp = NULL ;
DOM_SID alias_sid ;
2006-08-15 18:07:15 +04:00
fstring sid_string ;
2002-09-24 10:50:11 +04:00
GROUP_MAP map ;
2007-10-19 04:40:25 +04:00
bool insert = True ;
2002-09-24 10:50:11 +04:00
2008-02-15 16:13:11 +03:00
fstrcpy ( name , r - > alias_name . string ) ;
fstrcpy ( comment , r - > description . string ) ;
2002-09-24 10:50:11 +04:00
/* Find out whether the group is already mapped */
sid_copy ( & alias_sid , & dom_sid ) ;
sid_append_rid ( & alias_sid , rid ) ;
2007-12-16 00:47:30 +03:00
sid_to_fstring ( sid_string , & alias_sid ) ;
2002-09-24 10:50:11 +04:00
2006-08-15 18:07:15 +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 ;
}
2008-02-15 16:13:11 +03:00
static NTSTATUS fetch_alias_mem ( uint32_t rid ,
struct netr_DELTA_ALIAS_MEMBER * r ,
DOM_SID dom_sid )
2002-09-24 10:50:11 +04:00
{
return NT_STATUS_OK ;
}
2008-02-15 16:13:11 +03:00
static NTSTATUS fetch_domain_info ( uint32_t rid ,
struct netr_DELTA_DOMAIN * r )
2004-12-20 15:52:33 +03:00
{
2008-02-23 03:19:59 +03:00
time_t u_max_age , u_min_age , u_logout ;
2004-12-20 15:52:33 +03:00
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
2008-02-15 16:13:11 +03:00
const char * domname ;
2008-03-27 23:55:42 +03:00
struct netr_AcctLockStr * lockstr = NULL ;
NTSTATUS status ;
TALLOC_CTX * mem_ctx = talloc_tos ( ) ;
status = pull_netr_AcctLockStr ( mem_ctx , & r - > account_lockout ,
& lockstr ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " failed to pull account lockout string: %s \n " ,
nt_errstr ( status ) ) ;
}
2004-12-20 15:52:33 +03:00
2008-02-15 16:13:11 +03:00
u_max_age = uint64s_nt_time_to_unix_abs ( ( uint64 * ) & r - > max_password_age ) ;
u_min_age = uint64s_nt_time_to_unix_abs ( ( uint64 * ) & r - > min_password_age ) ;
u_logout = uint64s_nt_time_to_unix_abs ( ( uint64 * ) & r - > force_logoff_time ) ;
2008-03-27 23:55:42 +03:00
2008-02-15 16:13:11 +03:00
domname = r - > domain_name . string ;
2007-12-05 01:02:25 +03:00
if ( ! domname ) {
return NT_STATUS_NO_MEMORY ;
}
2004-12-20 15:52:33 +03:00
2007-12-05 01:02:25 +03:00
/* we don't handle BUILTIN account policies */
2004-12-20 15:52:33 +03:00
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 ;
}
2008-02-15 16:13:11 +03:00
if ( ! pdb_set_account_policy ( AP_PASSWORD_HISTORY ,
r - > password_history_length ) )
2004-12-20 15:52:33 +03:00
return nt_status ;
2008-02-15 16:13:11 +03:00
if ( ! pdb_set_account_policy ( AP_MIN_PASSWORD_LEN ,
r - > min_password_length ) )
2004-12-20 15:52:33 +03:00
return nt_status ;
2005-09-30 21:13:37 +04:00
if ( ! pdb_set_account_policy ( AP_MAX_PASSWORD_AGE , ( uint32 ) u_max_age ) )
2004-12-20 15:52:33 +03:00
return nt_status ;
2005-09-30 21:13:37 +04:00
if ( ! pdb_set_account_policy ( AP_MIN_PASSWORD_AGE , ( uint32 ) u_min_age ) )
2004-12-20 15:52:33 +03:00
return nt_status ;
2005-09-30 21:13:37 +04:00
if ( ! pdb_set_account_policy ( AP_TIME_TO_LOGOUT , ( uint32 ) u_logout ) )
2004-12-20 15:52:33 +03:00
return nt_status ;
2008-03-27 23:55:42 +03:00
if ( lockstr ) {
2008-04-17 19:02:46 +04:00
time_t u_lockoutreset , u_lockouttime ;
u_lockoutreset = uint64s_nt_time_to_unix_abs ( & lockstr - > reset_count ) ;
u_lockouttime = uint64s_nt_time_to_unix_abs ( ( uint64_t * ) & lockstr - > lockout_duration ) ;
2008-03-27 23:55:42 +03:00
if ( ! pdb_set_account_policy ( AP_BAD_ATTEMPT_LOCKOUT ,
lockstr - > bad_attempt_lockout ) )
return nt_status ;
2004-12-20 15:52:33 +03:00
2008-03-27 23:55:42 +03:00
if ( ! pdb_set_account_policy ( AP_RESET_COUNT_TIME , ( uint32_t ) u_lockoutreset / 60 ) )
return nt_status ;
2005-01-21 00:42:05 +03:00
2008-03-27 23:55:42 +03:00
if ( u_lockouttime ! = - 1 )
u_lockouttime / = 60 ;
if ( ! pdb_set_account_policy ( AP_LOCK_ACCOUNT_DURATION , ( uint32_t ) u_lockouttime ) )
return nt_status ;
}
2004-12-20 15:52:33 +03:00
2008-02-15 16:13:11 +03:00
if ( ! pdb_set_account_policy ( AP_USER_MUST_LOGON_TO_CHG_PASS ,
r - > logon_to_chgpass ) )
2004-12-20 15:52:33 +03:00
return nt_status ;
return NT_STATUS_OK ;
}
2008-02-15 16:13:11 +03:00
static void fetch_sam_entry ( struct netr_DELTA_ENUM * r , DOM_SID dom_sid )
2002-09-18 10:34:10 +04:00
{
2008-02-15 16:13:11 +03:00
switch ( r - > delta_type ) {
case NETR_DELTA_USER :
fetch_account_info ( r - > delta_id_union . rid ,
r - > delta_union . user ) ;
2002-09-18 10:34:10 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_GROUP :
fetch_group_info ( r - > delta_id_union . rid ,
r - > delta_union . group ) ;
2002-09-18 10:34:10 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_GROUP_MEMBER :
fetch_group_mem_info ( r - > delta_id_union . rid ,
r - > delta_union . group_member ) ;
2002-09-24 10:50:11 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_ALIAS :
fetch_alias_info ( r - > delta_id_union . rid ,
r - > delta_union . alias ,
dom_sid ) ;
2002-09-24 10:50:11 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_ALIAS_MEMBER :
fetch_alias_mem ( r - > delta_id_union . rid ,
r - > delta_union . alias_member ,
dom_sid ) ;
2002-09-24 10:50:11 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_DOMAIN :
fetch_domain_info ( r - > delta_id_union . rid ,
r - > delta_union . domain ) ;
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 */
2008-02-15 16:13:11 +03:00
case NETR_DELTA_RENAME_GROUP :
d_printf ( " NETR_DELTA_RENAME_GROUP not handled \n " ) ;
break ;
case NETR_DELTA_RENAME_USER :
d_printf ( " NETR_DELTA_RENAME_USER not handled \n " ) ;
break ;
case NETR_DELTA_RENAME_ALIAS :
d_printf ( " NETR_DELTA_RENAME_ALIAS not handled \n " ) ;
break ;
case NETR_DELTA_POLICY :
d_printf ( " NETR_DELTA_POLICY not handled \n " ) ;
2003-08-07 05:04:57 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_TRUSTED_DOMAIN :
d_printf ( " NETR_DELTA_TRUSTED_DOMAIN not handled \n " ) ;
2003-08-07 05:04:57 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_ACCOUNT :
d_printf ( " NETR_DELTA_ACCOUNT not handled \n " ) ;
2003-08-07 05:04:57 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_SECRET :
d_printf ( " NETR_DELTA_SECRET not handled \n " ) ;
2003-08-07 05:04:57 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_DELETE_GROUP :
d_printf ( " NETR_DELTA_DELETE_GROUP not handled \n " ) ;
2003-08-07 05:04:57 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_DELETE_USER :
d_printf ( " NETR_DELTA_DELETE_USER not handled \n " ) ;
2003-08-07 05:04:57 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_MODIFY_COUNT :
d_printf ( " NETR_DELTA_MODIFY_COUNT not handled \n " ) ;
2003-08-07 05:04:57 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_DELETE_ALIAS :
d_printf ( " NETR_DELTA_DELETE_ALIAS not handled \n " ) ;
2003-08-07 05:04:57 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_DELETE_TRUST :
d_printf ( " NETR_DELTA_DELETE_TRUST not handled \n " ) ;
2003-08-07 05:04:57 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_DELETE_ACCOUNT :
d_printf ( " NETR_DELTA_DELETE_ACCOUNT not handled \n " ) ;
break ;
case NETR_DELTA_DELETE_SECRET :
d_printf ( " NETR_DELTA_DELETE_SECRET not handled \n " ) ;
break ;
case NETR_DELTA_DELETE_GROUP2 :
d_printf ( " NETR_DELTA_DELETE_GROUP2 not handled \n " ) ;
break ;
case NETR_DELTA_DELETE_USER2 :
d_printf ( " NETR_DELTA_DELETE_USER2 not handled \n " ) ;
2003-08-07 05:04:57 +04:00
break ;
2002-09-18 10:34:10 +04:00
default :
2008-02-15 16:13:11 +03:00
d_printf ( " Unknown delta record type %d \n " , r - > delta_type ) ;
2002-09-18 10:34:10 +04:00
break ;
}
}
2005-09-30 21:13:37 +04:00
static NTSTATUS fetch_database ( struct rpc_pipe_client * pipe_hnd , uint32 db_type , DOM_SID dom_sid )
2002-09-18 10:34:10 +04:00
{
NTSTATUS result ;
int i ;
TALLOC_CTX * mem_ctx ;
2008-04-19 23:56:43 +04:00
const char * logon_server = pipe_hnd - > desthost ;
2008-02-15 16:13:11 +03:00
const char * computername = global_myname ( ) ;
struct netr_Authenticator credential ;
struct netr_Authenticator return_authenticator ;
enum netr_SamDatabaseID database_id = db_type ;
uint16_t restart_state = 0 ;
uint32_t sync_context = 0 ;
2002-09-18 10:34:10 +04:00
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 {
2008-02-15 16:13:11 +03:00
struct netr_DELTA_ENUM_ARRAY * delta_enum_array = NULL ;
netlogon_creds_client_step ( pipe_hnd - > dc , & credential ) ;
result = rpccli_netr_DatabaseSync2 ( pipe_hnd , mem_ctx ,
logon_server ,
computername ,
& credential ,
& return_authenticator ,
database_id ,
restart_state ,
& sync_context ,
& delta_enum_array ,
0xffff ) ;
/* Check returned credentials. */
if ( ! netlogon_creds_client_check ( pipe_hnd - > dc ,
& return_authenticator . cred ) ) {
DEBUG ( 0 , ( " credentials chain check failed \n " ) ) ;
return NT_STATUS_ACCESS_DENIED ;
}
if ( NT_STATUS_IS_ERR ( result ) ) {
break ;
}
for ( i = 0 ; i < delta_enum_array - > num_deltas ; i + + ) {
fetch_sam_entry ( & delta_enum_array - > delta_enum [ i ] , dom_sid ) ;
}
2003-06-16 09:39:26 +04:00
2002-11-02 06:47:48 +03:00
} 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
}
2008-02-15 16:13:11 +03:00
static NTSTATUS populate_ldap_for_ldif ( fstring sid , const char * suffix , const char
2005-07-07 01:02:43 +04:00
* builtin_sid , FILE * add_fd )
{
2006-06-21 00:43:05 +04:00
const char * user_suffix , * group_suffix , * machine_suffix , * idmap_suffix ;
2005-07-07 01:02:43 +04:00
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 ( ) ;
2006-05-13 21:10:20 +04:00
if ( user_suffix = = NULL ) {
2006-05-15 07:51:45 +04:00
SAFE_FREE ( suffix_attr ) ;
2006-05-13 21:10:20 +04:00
return NT_STATUS_NO_MEMORY ;
}
2008-02-15 16:13:11 +03:00
/* If it exists and is distinct from other containers,
2005-07-07 01:02:43 +04:00
Write the Users entity */
2006-05-13 21:10:20 +04:00
if ( * user_suffix & & strcmp ( user_suffix , suffix ) ) {
2005-07-07 01:02:43 +04:00
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 ( ) ;
2006-05-13 21:10:20 +04:00
if ( group_suffix = = NULL ) {
2006-05-15 07:51:45 +04:00
SAFE_FREE ( suffix_attr ) ;
SAFE_FREE ( user_attr ) ;
2006-05-13 21:10:20 +04:00
return NT_STATUS_NO_MEMORY ;
}
2008-02-15 16:13:11 +03:00
/* If it exists and is distinct from other containers,
2005-07-07 01:02:43 +04:00
Write the Groups entity */
2006-05-13 21:10:20 +04:00
if ( * group_suffix & & strcmp ( group_suffix , suffix ) ) {
2005-07-07 01:02:43 +04:00
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 ) ;
}
2008-02-15 16:13:11 +03:00
/* If it exists and is distinct from other containers,
2005-07-07 01:02:43 +04:00
Write the Computers entity */
machine_suffix = lp_ldap_machine_suffix ( ) ;
2006-05-13 21:10:20 +04:00
if ( machine_suffix = = NULL ) {
2006-05-15 07:51:45 +04:00
SAFE_FREE ( suffix_attr ) ;
SAFE_FREE ( user_attr ) ;
SAFE_FREE ( group_attr ) ;
2006-05-13 21:10:20 +04:00
return NT_STATUS_NO_MEMORY ;
}
if ( * machine_suffix & & strcmp ( machine_suffix , user_suffix ) & &
2005-07-07 01:02:43 +04:00
strcmp ( machine_suffix , suffix ) ) {
2006-03-10 16:33:02 +03:00
char * machine_ou = NULL ;
fprintf ( add_fd , " # %s \n " , machine_suffix ) ;
fprintf ( add_fd , " dn: %s \n " , machine_suffix ) ;
2005-07-07 01:02:43 +04:00
fprintf ( add_fd , " objectClass: organizationalUnit \n " ) ;
2006-03-10 16:33:02 +03:00
/* this isn't totally correct as it assumes that
there _must_ be an ou . just fixing memleak now . jmcd */
machine_ou = sstring_sub ( lp_ldap_machine_suffix ( ) , ' = ' , ' , ' ) ;
fprintf ( add_fd , " ou: %s \n " , machine_ou ) ;
SAFE_FREE ( machine_ou ) ;
2005-07-07 01:02:43 +04:00
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
}
2008-02-15 16:13:11 +03:00
/* If it exists and is distinct from other containers,
2005-07-07 01:02:43 +04:00
Write the IdMap entity */
idmap_suffix = lp_ldap_idmap_suffix ( ) ;
2006-05-13 21:10:20 +04:00
if ( idmap_suffix = = NULL ) {
2006-05-15 07:51:45 +04:00
SAFE_FREE ( suffix_attr ) ;
SAFE_FREE ( user_attr ) ;
SAFE_FREE ( group_attr ) ;
2006-05-13 21:10:20 +04:00
return NT_STATUS_NO_MEMORY ;
}
if ( * idmap_suffix & &
2005-07-07 01:02:43 +04:00
strcmp ( idmap_suffix , user_suffix ) & &
strcmp ( idmap_suffix , suffix ) ) {
2006-03-08 11:51:19 +03:00
char * s ;
2005-07-07 01:02:43 +04:00
fprintf ( add_fd , " # %s \n " , idmap_suffix ) ;
fprintf ( add_fd , " dn: %s \n " , idmap_suffix ) ;
fprintf ( add_fd , " ObjectClass: organizationalUnit \n " ) ;
2006-03-08 11:51:19 +03:00
s = sstring_sub ( lp_ldap_idmap_suffix ( ) , ' = ' , ' , ' ) ;
fprintf ( add_fd , " ou: %s \n " , s ) ;
SAFE_FREE ( s ) ;
2005-07-07 01:02:43 +04:00
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 ) ;
2008-02-15 16:13:11 +03:00
/* Write the Domain Admins entity */
2005-07-07 01:02:43 +04:00
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 ) ;
2008-02-15 16:13:11 +03:00
/* Write the Domain Users entity */
2005-07-07 01:02:43 +04:00
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 ) ;
2008-02-15 16:13:11 +03:00
/* Write the Domain Guests entity */
2005-07-07 01:02:43 +04:00
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 */
2006-03-10 17:09:34 +03:00
SAFE_FREE ( suffix_attr ) ;
SAFE_FREE ( user_attr ) ;
SAFE_FREE ( group_attr ) ;
2005-07-07 01:02:43 +04:00
return NT_STATUS_OK ;
}
2008-02-15 16:13:11 +03:00
static NTSTATUS map_populate_groups ( GROUPMAP * groupmap , ACCOUNTMAP * accountmap , fstring sid ,
2005-07-07 01:02:43 +04:00
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 ;
2007-12-05 01:31:57 +03:00
snprintf ( groupmap [ 0 ] . sambaSID , sizeof ( groupmap [ 0 ] . sambaSID ) ,
" %s-512 " , sid ) ;
snprintf ( groupmap [ 0 ] . group_dn , sizeof ( groupmap [ 0 ] . group_dn ) ,
" cn=Domain Admins,ou=%s,%s " ,
group_attr , suffix ) ;
2005-07-07 01:02:43 +04:00
accountmap [ 0 ] . rid = 512 ;
2007-12-05 01:31:57 +03:00
snprintf ( accountmap [ 0 ] . cn , sizeof ( accountmap [ 0 ] . cn ) ,
" %s " , " Domain Admins " ) ;
2005-07-07 01:02:43 +04:00
groupmap [ 1 ] . rid = 513 ;
groupmap [ 1 ] . gidNumber = 513 ;
2007-12-05 01:31:57 +03:00
snprintf ( groupmap [ 1 ] . sambaSID , sizeof ( groupmap [ 1 ] . sambaSID ) ,
" %s-513 " , sid ) ;
snprintf ( groupmap [ 1 ] . group_dn , sizeof ( groupmap [ 1 ] . group_dn ) ,
" cn=Domain Users,ou=%s,%s " ,
group_attr , suffix ) ;
2005-07-07 01:02:43 +04:00
accountmap [ 1 ] . rid = 513 ;
2007-12-05 01:31:57 +03:00
snprintf ( accountmap [ 1 ] . cn , sizeof ( accountmap [ 1 ] . cn ) ,
" %s " , " Domain Users " ) ;
2005-07-07 01:02:43 +04:00
groupmap [ 2 ] . rid = 514 ;
groupmap [ 2 ] . gidNumber = 514 ;
2007-12-05 01:31:57 +03:00
snprintf ( groupmap [ 2 ] . sambaSID , sizeof ( groupmap [ 2 ] . sambaSID ) ,
" %s-514 " , sid ) ;
snprintf ( groupmap [ 2 ] . group_dn , sizeof ( groupmap [ 2 ] . group_dn ) ,
" cn=Domain Guests,ou=%s,%s " ,
group_attr , suffix ) ;
2005-07-07 01:02:43 +04:00
accountmap [ 2 ] . rid = 514 ;
2007-12-05 01:31:57 +03:00
snprintf ( accountmap [ 2 ] . cn , sizeof ( accountmap [ 2 ] . cn ) ,
" %s " , " Domain Guests " ) ;
2005-07-07 01:02:43 +04:00
groupmap [ 3 ] . rid = 515 ;
groupmap [ 3 ] . gidNumber = 515 ;
2007-12-05 01:31:57 +03:00
snprintf ( groupmap [ 3 ] . sambaSID , sizeof ( groupmap [ 3 ] . sambaSID ) ,
" %s-515 " , sid ) ;
snprintf ( groupmap [ 3 ] . group_dn , sizeof ( groupmap [ 3 ] . group_dn ) ,
" cn=Domain Computers,ou=%s,%s " ,
group_attr , suffix ) ;
2005-07-07 01:02:43 +04:00
accountmap [ 3 ] . rid = 515 ;
2007-12-05 01:31:57 +03:00
snprintf ( accountmap [ 3 ] . cn , sizeof ( accountmap [ 3 ] . cn ) ,
" %s " , " Domain Computers " ) ;
2005-07-07 01:02:43 +04:00
groupmap [ 4 ] . rid = 544 ;
groupmap [ 4 ] . gidNumber = 544 ;
2007-12-05 01:31:57 +03:00
snprintf ( groupmap [ 4 ] . sambaSID , sizeof ( groupmap [ 4 ] . sambaSID ) ,
" %s-544 " , builtin_sid ) ;
snprintf ( groupmap [ 4 ] . group_dn , sizeof ( groupmap [ 4 ] . group_dn ) ,
" cn=Administrators,ou=%s,%s " ,
group_attr , suffix ) ;
2005-07-07 01:02:43 +04:00
accountmap [ 4 ] . rid = 515 ;
2007-12-05 01:31:57 +03:00
snprintf ( accountmap [ 4 ] . cn , sizeof ( accountmap [ 4 ] . cn ) ,
" %s " , " Administrators " ) ;
2005-07-07 01:02:43 +04:00
groupmap [ 5 ] . rid = 550 ;
groupmap [ 5 ] . gidNumber = 550 ;
2007-12-05 01:31:57 +03:00
snprintf ( groupmap [ 5 ] . sambaSID , sizeof ( groupmap [ 5 ] . sambaSID ) ,
" %s-550 " , builtin_sid ) ;
snprintf ( groupmap [ 5 ] . group_dn , sizeof ( groupmap [ 5 ] . group_dn ) ,
" cn=Print Operators,ou=%s,%s " ,
group_attr , suffix ) ;
2005-07-07 01:02:43 +04:00
accountmap [ 5 ] . rid = 550 ;
2007-12-05 01:31:57 +03:00
snprintf ( accountmap [ 5 ] . cn , sizeof ( accountmap [ 5 ] . cn ) ,
" %s " , " Print Operators " ) ;
2005-07-07 01:02:43 +04:00
groupmap [ 6 ] . rid = 551 ;
groupmap [ 6 ] . gidNumber = 551 ;
2007-12-05 01:31:57 +03:00
snprintf ( groupmap [ 6 ] . sambaSID , sizeof ( groupmap [ 6 ] . sambaSID ) ,
" %s-551 " , builtin_sid ) ;
snprintf ( groupmap [ 6 ] . group_dn , sizeof ( groupmap [ 6 ] . group_dn ) ,
" cn=Backup Operators,ou=%s,%s " ,
group_attr , suffix ) ;
2005-07-07 01:02:43 +04:00
accountmap [ 6 ] . rid = 551 ;
2007-12-05 01:31:57 +03:00
snprintf ( accountmap [ 6 ] . cn , sizeof ( accountmap [ 6 ] . cn ) ,
" %s " , " Backup Operators " ) ;
2005-07-07 01:02:43 +04:00
groupmap [ 7 ] . rid = 552 ;
groupmap [ 7 ] . gidNumber = 552 ;
2007-12-05 01:31:57 +03:00
snprintf ( groupmap [ 7 ] . sambaSID , sizeof ( groupmap [ 7 ] . sambaSID ) ,
" %s-552 " , builtin_sid ) ;
snprintf ( groupmap [ 7 ] . group_dn , sizeof ( groupmap [ 7 ] . group_dn ) ,
" cn=Replicators,ou=%s,%s " ,
group_attr , suffix ) ;
2005-07-07 01:02:43 +04:00
accountmap [ 7 ] . rid = 551 ;
2007-12-05 01:31:57 +03:00
snprintf ( accountmap [ 7 ] . cn , sizeof ( accountmap [ 7 ] . cn ) ,
" %s " , " Replicators " ) ;
2006-03-10 17:14:23 +03:00
SAFE_FREE ( group_attr ) ;
2005-07-07 01:02:43 +04:00
return NT_STATUS_OK ;
}
2006-07-29 21:33:48 +04:00
/*
* This is a crap routine , but I think it ' s the quickest way to solve the
* UTF8 - > base64 problem .
*/
static int fprintf_attr ( FILE * add_fd , const char * attr_name ,
const char * fmt , . . . )
{
va_list ap ;
char * value , * p , * base64 ;
DATA_BLOB base64_blob ;
2007-10-19 04:40:25 +04:00
bool do_base64 = False ;
2006-07-29 21:33:48 +04:00
int res ;
va_start ( ap , fmt ) ;
value = talloc_vasprintf ( NULL , fmt , ap ) ;
va_end ( ap ) ;
SMB_ASSERT ( value ! = NULL ) ;
for ( p = value ; * p ; p + + ) {
if ( * p & 0x80 ) {
2006-08-02 13:32:18 +04:00
do_base64 = True ;
2006-07-29 21:33:48 +04:00
break ;
}
}
2006-08-02 13:32:18 +04:00
if ( ! do_base64 ) {
2007-10-19 04:40:25 +04:00
bool only_whitespace = True ;
2006-08-02 13:32:18 +04:00
for ( p = value ; * p ; p + + ) {
/*
* I know that this not multibyte safe , but we break
* on the first non - whitespace character anyway .
*/
if ( ! isspace ( * p ) ) {
only_whitespace = False ;
break ;
}
}
if ( only_whitespace ) {
do_base64 = True ;
}
}
if ( ! do_base64 ) {
2006-07-29 21:33:48 +04:00
res = fprintf ( add_fd , " %s: %s \n " , attr_name , value ) ;
TALLOC_FREE ( value ) ;
return res ;
}
base64_blob . data = ( unsigned char * ) value ;
base64_blob . length = strlen ( value ) ;
2008-01-19 04:12:35 +03:00
base64 = base64_encode_data_blob ( value , base64_blob ) ;
2006-07-29 21:33:48 +04:00
SMB_ASSERT ( base64 ! = NULL ) ;
res = fprintf ( add_fd , " %s:: %s \n " , attr_name , base64 ) ;
TALLOC_FREE ( value ) ;
return res ;
}
2008-02-15 16:13:11 +03:00
static NTSTATUS fetch_group_info_to_ldif ( struct netr_DELTA_GROUP * r , GROUPMAP * groupmap ,
2005-07-07 01:02:43 +04:00
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 */
2008-02-15 16:13:11 +03:00
fstrcpy ( groupname , r - > group_name . string ) ;
2005-07-07 01:02:43 +04:00
/* 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 ) {
2006-03-10 17:17:44 +03:00
SAFE_FREE ( group_attr ) ;
2005-07-07 01:02:43 +04:00
return NT_STATUS_OK ;
} else {
/* Increment the gid for the new group */
ldif_gid + + ;
}
/* Map the group rid, gid, and dn */
2008-02-15 16:13:11 +03:00
g_rid = r - > rid ;
2005-07-07 01:02:43 +04:00
groupmap - > rid = g_rid ;
groupmap - > gidNumber = ldif_gid ;
2007-12-05 01:31:57 +03:00
snprintf ( groupmap - > sambaSID , sizeof ( groupmap - > sambaSID ) ,
" %s-%d " , sid , g_rid ) ;
snprintf ( groupmap - > group_dn , sizeof ( groupmap - > group_dn ) ,
2005-07-07 01:02:43 +04:00
" 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 ) ;
2006-07-29 21:33:48 +04:00
fprintf_attr ( add_fd , " dn " , " cn=%s,ou=%s,%s " , groupname , group_attr ,
suffix ) ;
2005-07-07 01:02:43 +04:00
fprintf ( add_fd , " objectClass: posixGroup \n " ) ;
fprintf ( add_fd , " objectClass: sambaGroupMapping \n " ) ;
2006-07-29 21:33:48 +04:00
fprintf_attr ( add_fd , " cn " , " %s " , groupname ) ;
2005-07-07 01:02:43 +04:00
fprintf ( add_fd , " gidNumber: %d \n " , ldif_gid ) ;
fprintf ( add_fd , " sambaSID: %s \n " , groupmap - > sambaSID ) ;
fprintf ( add_fd , " sambaGroupType: %d \n " , grouptype ) ;
2006-07-29 21:33:48 +04:00
fprintf_attr ( add_fd , " displayName " , " %s " , groupname ) ;
2005-07-07 01:02:43 +04:00
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
2006-03-10 17:17:44 +03:00
SAFE_FREE ( group_attr ) ;
2005-07-07 01:02:43 +04:00
/* Return */
return NT_STATUS_OK ;
}
2008-02-15 16:13:11 +03:00
static NTSTATUS fetch_account_info_to_ldif ( struct netr_DELTA_USER * r ,
2006-07-29 19:45:19 +04:00
GROUPMAP * groupmap ,
ACCOUNTMAP * accountmap ,
FILE * add_fd ,
fstring sid , char * suffix ,
int alloced )
2005-07-07 01:02:43 +04:00
{
2006-03-07 19:29:25 +03:00
fstring username , logonscript , homedrive , homepath = " " , homedir = " " ;
2005-07-07 01:02:43 +04:00
fstring hex_nt_passwd , hex_lm_passwd ;
2006-08-02 12:53:22 +04:00
fstring description , profilepath , fullname , sambaSID ;
2005-07-07 01:02:43 +04:00
uchar lm_passwd [ 16 ] , nt_passwd [ 16 ] ;
2006-03-10 17:28:51 +03:00
char * flags , * user_rdn ;
2006-07-31 10:01:54 +04:00
const char * ou ;
2005-07-07 01:02:43 +04:00
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 */
2008-02-15 16:13:11 +03:00
fstrcpy ( username , r - > account_name . string ) ;
2005-07-07 01:02:43 +04:00
/* Get the rid */
2008-02-15 16:13:11 +03:00
rid = r - > rid ;
2005-07-07 01:02:43 +04:00
/* Map the rid and username for group member info later */
accountmap - > rid = rid ;
2007-12-05 01:31:57 +03:00
snprintf ( accountmap - > cn , sizeof ( accountmap - > cn ) , " %s " , username ) ;
2005-07-07 01:02:43 +04:00
/* Get the home directory */
2008-02-15 16:13:11 +03:00
if ( r - > acct_flags & ACB_NORMAL ) {
fstrcpy ( homedir , r - > home_directory . string ) ;
2006-03-07 19:29:25 +03:00
if ( ! * homedir ) {
2007-12-05 01:31:57 +03:00
snprintf ( homedir , sizeof ( homedir ) , " /home/%s " , username ) ;
2006-03-07 19:29:25 +03:00
} else {
2007-12-05 01:31:57 +03:00
snprintf ( homedir , sizeof ( homedir ) , " /nobodyshomedir " ) ;
2006-03-07 19:29:25 +03:00
}
2006-07-31 10:01:54 +04:00
ou = lp_ldap_user_suffix ( ) ;
} else {
ou = lp_ldap_machine_suffix ( ) ;
2007-12-05 01:31:57 +03:00
snprintf ( homedir , sizeof ( homedir ) , " /machinehomedir " ) ;
2006-07-31 10:01:54 +04:00
}
2005-07-07 01:02:43 +04:00
/* Get the logon script */
2008-02-15 16:13:11 +03:00
fstrcpy ( logonscript , r - > logon_script . string ) ;
2005-07-07 01:02:43 +04:00
/* Get the home drive */
2008-02-15 16:13:11 +03:00
fstrcpy ( homedrive , r - > home_drive . string ) ;
2005-07-07 01:02:43 +04:00
2006-08-01 13:06:18 +04:00
/* Get the home path */
2008-02-15 16:13:11 +03:00
fstrcpy ( homepath , r - > home_directory . string ) ;
2006-08-01 13:06:18 +04:00
2005-07-07 01:02:43 +04:00
/* Get the description */
2008-02-15 16:13:11 +03:00
fstrcpy ( description , r - > description . string ) ;
2005-07-07 01:02:43 +04:00
/* Get the display name */
2008-02-15 16:13:11 +03:00
fstrcpy ( fullname , r - > full_name . string ) ;
2005-07-07 01:02:43 +04:00
2006-08-02 12:53:22 +04:00
/* Get the profile path */
2008-02-15 16:13:11 +03:00
fstrcpy ( profilepath , r - > profile_path . string ) ;
2006-08-02 12:53:22 +04:00
2005-07-07 01:02:43 +04:00
/* Get lm and nt password data */
2008-02-15 16:13:11 +03:00
if ( memcmp ( r - > lmpassword . hash , zero_buf , 16 ) ! = 0 ) {
sam_pwd_hash ( r - > rid , r - > lmpassword . hash , lm_passwd , 0 ) ;
pdb_sethexpwd ( hex_lm_passwd , lm_passwd , r - > acct_flags ) ;
2005-07-07 01:02:43 +04:00
} else {
pdb_sethexpwd ( hex_lm_passwd , NULL , 0 ) ;
}
2008-02-15 16:13:11 +03:00
if ( memcmp ( r - > ntpassword . hash , zero_buf , 16 ) ! = 0 ) {
sam_pwd_hash ( r - > rid , r - > ntpassword . hash , nt_passwd , 0 ) ;
pdb_sethexpwd ( hex_nt_passwd , nt_passwd , r - > acct_flags ) ;
2005-07-07 01:02:43 +04:00
} else {
pdb_sethexpwd ( hex_nt_passwd , NULL , 0 ) ;
}
2008-02-15 16:13:11 +03:00
unix_time = nt_time_to_unix ( r - > last_password_change ) ;
2005-07-07 01:02:43 +04:00
2006-11-29 09:26:12 +03:00
/* Increment the uid for the new user */
ldif_uid + + ;
2005-07-07 01:02:43 +04:00
/* Set up group id and sambaSID for the user */
2008-02-15 16:13:11 +03:00
group_rid = r - > primary_gid ;
2005-07-07 01:02:43 +04:00
for ( i = 0 ; i < alloced ; i + + ) {
if ( groupmap [ i ] . rid = = group_rid ) break ;
}
if ( i = = alloced ) {
2008-02-15 16:13:11 +03:00
DEBUG ( 1 , ( " Could not find rid %d in groupmap array \n " ,
2005-07-07 01:02:43 +04:00
group_rid ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
gidNumber = groupmap [ i ] . gidNumber ;
2007-12-05 01:31:57 +03:00
snprintf ( sambaSID , sizeof ( sambaSID ) , groupmap [ i ] . sambaSID ) ;
2005-07-07 01:02:43 +04:00
/* Set up sambaAcctFlags */
2008-02-15 16:13:11 +03:00
flags = pdb_encode_acct_ctrl ( r - > acct_flags ,
2005-07-07 01:02:43 +04:00
NEW_PW_FORMAT_SPACE_PADDED_LEN ) ;
/* Add the user to the temporary add ldif file */
2006-03-10 17:28:51 +03:00
/* this isn't quite right...we can't assume there's just OU=. jmcd */
2006-07-31 10:01:54 +04:00
user_rdn = sstring_sub ( ou , ' = ' , ' , ' ) ;
2006-03-10 17:28:51 +03:00
fprintf ( add_fd , " # %s, %s, %s \n " , username , user_rdn , suffix ) ;
2006-07-29 21:33:48 +04:00
fprintf_attr ( add_fd , " dn " , " uid=%s,ou=%s,%s " , username , user_rdn ,
suffix ) ;
2006-03-10 17:28:51 +03:00
SAFE_FREE ( user_rdn ) ;
2005-07-07 01:02:43 +04:00
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 " ) ;
2006-07-29 21:33:48 +04:00
fprintf_attr ( add_fd , " cn " , " %s " , username ) ;
fprintf_attr ( add_fd , " sn " , " %s " , username ) ;
2006-07-31 10:01:54 +04:00
fprintf_attr ( add_fd , " uid " , " %s " , username ) ;
2005-07-07 01:02:43 +04:00
fprintf ( add_fd , " uidNumber: %d \n " , ldif_uid ) ;
fprintf ( add_fd , " gidNumber: %d \n " , gidNumber ) ;
2006-07-31 10:01:54 +04:00
fprintf_attr ( add_fd , " homeDirectory " , " %s " , homedir ) ;
2006-03-07 19:29:25 +03:00
if ( * homepath )
2006-07-29 21:33:48 +04:00
fprintf_attr ( add_fd , " sambaHomePath " , " %s " , homepath ) ;
2006-03-07 19:29:25 +03:00
if ( * homedrive )
2006-07-29 21:33:48 +04:00
fprintf_attr ( add_fd , " sambaHomeDrive " , " %s " , homedrive ) ;
2006-03-07 19:29:25 +03:00
if ( * logonscript )
2006-07-29 21:33:48 +04:00
fprintf_attr ( add_fd , " sambaLogonScript " , " %s " , logonscript ) ;
2008-02-15 16:13:11 +03:00
fprintf ( add_fd , " loginShell: %s \n " ,
( ( r - > acct_flags & ACB_NORMAL ) ?
2006-03-07 19:29:25 +03:00
" /bin/bash " : " /bin/false " ) ) ;
2005-07-07 01:02:43 +04:00
fprintf ( add_fd , " gecos: System User \n " ) ;
2006-08-02 12:53:22 +04:00
if ( * description )
fprintf_attr ( add_fd , " description " , " %s " , description ) ;
2005-07-07 01:02:43 +04:00
fprintf ( add_fd , " sambaSID: %s-%d \n " , sid , rid ) ;
fprintf ( add_fd , " sambaPrimaryGroupSID: %s \n " , sambaSID ) ;
2006-03-07 19:29:25 +03:00
if ( * fullname )
2006-07-29 21:33:48 +04:00
fprintf_attr ( add_fd , " displayName " , " %s " , fullname ) ;
2006-08-02 12:53:22 +04:00
if ( * profilepath )
fprintf_attr ( add_fd , " sambaProfilePath " , " %s " , profilepath ) ;
2005-07-07 01:02:43 +04:00
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 ;
}
2008-02-15 16:13:11 +03:00
static NTSTATUS fetch_alias_info_to_ldif ( struct netr_DELTA_ALIAS * r ,
2006-07-29 19:45:19 +04:00
GROUPMAP * groupmap ,
FILE * add_fd , fstring sid ,
2008-02-15 16:13:11 +03:00
char * suffix ,
2006-07-29 19:45:19 +04:00
unsigned db_type )
2005-07-07 01:02:43 +04:00
{
fstring aliasname , description ;
uint32 grouptype = 0 , g_rid = 0 ;
char * group_attr = sstring_sub ( lp_ldap_group_suffix ( ) , ' = ' , ' , ' ) ;
/* Get the alias name */
2008-02-15 16:13:11 +03:00
fstrcpy ( aliasname , r - > alias_name . string ) ;
2005-07-07 01:02:43 +04:00
/* Get the alias description */
2008-02-15 16:13:11 +03:00
fstrcpy ( description , r - > description . string ) ;
2005-07-07 01:02:43 +04:00
/* Set up the group type */
switch ( db_type ) {
2006-07-29 19:45:19 +04:00
case SAM_DATABASE_DOMAIN :
grouptype = 4 ;
break ;
case SAM_DATABASE_BUILTIN :
grouptype = 5 ;
break ;
default :
grouptype = 4 ;
break ;
2005-07-07 01:02:43 +04:00
}
/*
2006-07-29 19:45:19 +04:00
These groups are entered by populate_ldap_for_ldif
2008-02-15 16:13:11 +03:00
Note that populate creates a group called Relicators ,
2006-07-29 19:45:19 +04:00
but NT returns a group called Replicator
2005-07-07 01:02:43 +04:00
*/
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 ) {
2006-03-10 17:20:09 +03:00
SAFE_FREE ( group_attr ) ;
2005-07-07 01:02:43 +04:00
return NT_STATUS_OK ;
} else {
/* Increment the gid for the new group */
ldif_gid + + ;
}
/* Map the group rid and gid */
2008-02-15 16:13:11 +03:00
g_rid = r - > rid ;
2005-07-07 01:02:43 +04:00
groupmap - > gidNumber = ldif_gid ;
2007-12-05 01:31:57 +03:00
snprintf ( groupmap - > sambaSID , sizeof ( groupmap - > sambaSID ) ,
" %s-%d " , sid , g_rid ) ;
2005-07-07 01:02:43 +04:00
/* Write the data to the temporary add ldif file */
fprintf ( add_fd , " # %s, %s, %s \n " , aliasname , group_attr ,
suffix ) ;
2006-07-31 10:01:54 +04:00
fprintf_attr ( add_fd , " dn " , " cn=%s,ou=%s,%s " , aliasname , group_attr ,
suffix ) ;
2005-07-07 01:02:43 +04:00
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 ) ;
2006-07-31 10:01:54 +04:00
fprintf_attr ( add_fd , " displayName " , " %s " , aliasname ) ;
if ( description [ 0 ] )
fprintf_attr ( add_fd , " description " , " %s " , description ) ;
2005-07-07 01:02:43 +04:00
fprintf ( add_fd , " \n " ) ;
fflush ( add_fd ) ;
2006-03-10 17:20:09 +03:00
SAFE_FREE ( group_attr ) ;
2005-07-07 01:02:43 +04:00
/* Return */
return NT_STATUS_OK ;
}
2008-02-15 16:13:11 +03:00
static NTSTATUS fetch_groupmem_info_to_ldif ( struct netr_DELTA_GROUP_MEMBER * r ,
uint32_t id_rid ,
2006-07-29 19:45:19 +04:00
GROUPMAP * groupmap ,
2007-12-05 01:31:57 +03:00
ACCOUNTMAP * accountmap ,
2006-07-29 19:45:19 +04:00
FILE * mod_fd , int alloced )
2005-07-07 01:02:43 +04:00
{
fstring group_dn ;
uint32 group_rid = 0 , rid = 0 ;
int i , j , k ;
/* Get the dn for the group */
2008-02-15 16:13:11 +03:00
if ( r - > num_rids > 0 ) {
group_rid = id_rid ;
2005-07-07 01:02:43 +04:00
for ( j = 0 ; j < alloced ; j + + ) {
if ( groupmap [ j ] . rid = = group_rid ) break ;
}
if ( j = = alloced ) {
2007-12-05 01:31:57 +03:00
DEBUG ( 1 , ( " Could not find rid %d in groupmap array \n " ,
2005-07-07 01:02:43 +04:00
group_rid ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
2007-12-05 01:31:57 +03:00
snprintf ( group_dn , sizeof ( group_dn ) , " %s " , groupmap [ j ] . group_dn ) ;
2005-07-07 01:02:43 +04:00
fprintf ( mod_fd , " dn: %s \n " , group_dn ) ;
/* Get the cn for each member */
2008-02-15 16:13:11 +03:00
for ( i = 0 ; i < r - > num_rids ; i + + ) {
rid = r - > rids [ i ] ;
2005-07-07 01:02:43 +04:00
for ( k = 0 ; k < alloced ; k + + ) {
if ( accountmap [ k ] . rid = = rid ) break ;
}
if ( k = = alloced ) {
2006-07-29 19:45:19 +04:00
DEBUG ( 1 , ( " Could not find rid %d in "
" accountmap array \n " , rid ) ) ;
2005-07-07 01:02:43 +04:00
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 ;
}
2005-09-30 21:13:37 +04:00
static NTSTATUS fetch_database_to_ldif ( struct rpc_pipe_client * pipe_hnd ,
2006-07-29 19:45:19 +04:00
uint32 db_type ,
DOM_SID dom_sid ,
const char * user_file )
2005-07-07 01:02:43 +04:00
{
char * suffix ;
const char * builtin_sid = " S-1-5-32 " ;
2006-03-23 21:35:15 +03:00
char * add_name = NULL , * mod_name = NULL ;
2006-03-23 19:39:37 +03:00
const char * add_template = " /tmp/add.ldif.XXXXXX " ;
const char * mod_template = " /tmp/mod.ldif.XXXXXX " ;
2005-07-07 01:02:43 +04:00
fstring sid , domainname ;
2006-03-10 12:41:08 +03:00
NTSTATUS ret = NT_STATUS_OK , result ;
2005-07-07 01:02:43 +04:00
int k ;
TALLOC_CTX * mem_ctx ;
uint32 num_deltas ;
2006-03-23 21:35:15 +03:00
FILE * add_file = NULL , * mod_file = NULL , * ldif_file = NULL ;
int num_alloced = 0 , g_index = 0 , a_index = 0 ;
2008-04-19 23:56:43 +04:00
const char * logon_server = pipe_hnd - > desthost ;
2008-02-15 16:13:11 +03:00
const char * computername = global_myname ( ) ;
struct netr_Authenticator credential ;
struct netr_Authenticator return_authenticator ;
enum netr_SamDatabaseID database_id = db_type ;
uint16_t restart_state = 0 ;
uint32_t sync_context = 0 ;
2005-07-07 01:02:43 +04:00
/* 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 */
2008-02-15 16:13:11 +03:00
ACCOUNTMAP * accountmap = NULL ;
2005-07-07 01:02:43 +04:00
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 )
2006-03-23 21:35:15 +03:00
ldif_file = fopen ( user_file , " a " ) ;
2005-07-07 01:02:43 +04:00
else
2006-03-23 21:35:15 +03:00
ldif_file = stdout ;
if ( ! ldif_file ) {
fprintf ( stderr , " Could not open %s \n " , user_file ) ;
DEBUG ( 1 , ( " Could not open %s \n " , user_file ) ) ;
ret = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
add_name = talloc_strdup ( mem_ctx , add_template ) ;
mod_name = talloc_strdup ( mem_ctx , mod_template ) ;
if ( ! add_name | | ! mod_name ) {
2006-03-10 12:41:08 +03:00
ret = NT_STATUS_NO_MEMORY ;
goto done ;
}
2005-07-07 01:02:43 +04:00
/* Open the add and mod ldif files */
2006-03-23 21:35:15 +03:00
if ( ! ( add_file = fdopen ( smb_mkstemp ( add_name ) , " w " ) ) ) {
DEBUG ( 1 , ( " Could not open %s \n " , add_name ) ) ;
2006-03-10 12:41:08 +03:00
ret = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2006-03-23 21:35:15 +03:00
if ( ! ( mod_file = fdopen ( smb_mkstemp ( mod_name ) , " w " ) ) ) {
DEBUG ( 1 , ( " Could not open %s \n " , mod_name ) ) ;
2006-03-10 12:41:08 +03:00
ret = NT_STATUS_UNSUCCESSFUL ;
goto done ;
2008-02-15 16:13:11 +03:00
}
2005-07-07 01:02:43 +04:00
/* Get the sid */
2007-12-16 00:47:30 +03:00
sid_to_fstring ( sid , & dom_sid ) ;
2005-07-07 01:02:43 +04:00
/* 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 " ) ) ;
2006-03-10 12:41:08 +03:00
ret = NT_STATUS_NO_MEMORY ;
goto done ;
2005-07-07 01:02:43 +04:00
}
/* 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 */
2006-03-23 21:35:15 +03:00
populate_ldap_for_ldif ( sid , suffix , builtin_sid , add_file ) ;
2005-07-07 01:02:43 +04:00
map_populate_groups ( groupmap , accountmap , sid , suffix ,
2006-07-29 19:45:19 +04:00
builtin_sid ) ;
2005-07-07 01:02:43 +04:00
/* Don't do this again */
init_ldap = 0 ;
}
/* Announce what we are doing */
switch ( db_type ) {
2006-07-29 19:45:19 +04:00
case SAM_DATABASE_DOMAIN :
d_fprintf ( stderr , " Fetching DOMAIN database \n " ) ;
break ;
case SAM_DATABASE_BUILTIN :
d_fprintf ( stderr , " Fetching BUILTIN database \n " ) ;
break ;
case SAM_DATABASE_PRIVS :
d_fprintf ( stderr , " Fetching PRIVS databases \n " ) ;
break ;
default :
2008-02-15 16:13:11 +03:00
d_fprintf ( stderr ,
" Fetching unknown database type %u \n " ,
2006-07-29 19:45:19 +04:00
db_type ) ;
break ;
2005-07-07 01:02:43 +04:00
}
do {
2008-02-15 16:13:11 +03:00
struct netr_DELTA_ENUM_ARRAY * delta_enum_array = NULL ;
netlogon_creds_client_step ( pipe_hnd - > dc , & credential ) ;
result = rpccli_netr_DatabaseSync2 ( pipe_hnd , mem_ctx ,
logon_server ,
computername ,
& credential ,
& return_authenticator ,
database_id ,
restart_state ,
& sync_context ,
& delta_enum_array ,
0xffff ) ;
/* Check returned credentials. */
if ( ! netlogon_creds_client_check ( pipe_hnd - > dc ,
& return_authenticator . cred ) ) {
DEBUG ( 0 , ( " credentials chain check failed \n " ) ) ;
return NT_STATUS_ACCESS_DENIED ;
2005-07-07 01:02:43 +04:00
}
2008-02-15 16:13:11 +03:00
if ( NT_STATUS_IS_ERR ( result ) ) {
break ;
}
num_deltas = delta_enum_array - > num_deltas ;
2005-07-07 01:02:43 +04:00
/* Re-allocate memory for groupmap and accountmap arrays */
groupmap = SMB_REALLOC_ARRAY ( groupmap , GROUPMAP ,
2006-07-29 19:45:19 +04:00
num_deltas + num_alloced ) ;
2005-07-07 01:02:43 +04:00
accountmap = SMB_REALLOC_ARRAY ( accountmap , ACCOUNTMAP ,
2006-07-29 19:45:19 +04:00
num_deltas + num_alloced ) ;
2005-07-07 01:02:43 +04:00
if ( groupmap = = NULL | | accountmap = = NULL ) {
DEBUG ( 1 , ( " GROUPMAP malloc failed \n " ) ) ;
2006-03-10 12:41:08 +03:00
ret = NT_STATUS_NO_MEMORY ;
goto done ;
2005-07-07 01:02:43 +04:00
}
/* Initialize the new records */
2008-02-15 16:13:11 +03:00
memset ( & groupmap [ num_alloced ] , 0 ,
2005-07-07 01:02:43 +04:00
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 + + ) {
2008-02-15 16:13:11 +03:00
union netr_DELTA_UNION u =
delta_enum_array - > delta_enum [ k ] . delta_union ;
union netr_DELTA_ID_UNION id =
delta_enum_array - > delta_enum [ k ] . delta_id_union ;
switch ( delta_enum_array - > delta_enum [ k ] . delta_type ) {
case NETR_DELTA_DOMAIN :
2006-07-29 19:45:19 +04:00
/* Is this case needed? */
2008-02-15 16:13:11 +03:00
fstrcpy ( domainname ,
u . domain - > domain_name . string ) ;
2006-07-29 19:45:19 +04:00
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_GROUP :
2006-07-29 19:45:19 +04:00
fetch_group_info_to_ldif (
2008-02-15 16:13:11 +03:00
u . group ,
& groupmap [ g_index ] ,
2006-07-29 19:45:19 +04:00
add_file , sid , suffix ) ;
g_index + + ;
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_USER :
2006-07-29 19:45:19 +04:00
fetch_account_info_to_ldif (
2008-02-15 16:13:11 +03:00
u . user , groupmap ,
2006-07-29 19:45:19 +04:00
& accountmap [ a_index ] , add_file ,
sid , suffix , num_alloced ) ;
a_index + + ;
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_ALIAS :
2006-07-29 19:45:19 +04:00
fetch_alias_info_to_ldif (
2008-02-15 16:13:11 +03:00
u . alias , & groupmap [ g_index ] ,
2006-07-29 19:45:19 +04:00
add_file , sid , suffix , db_type ) ;
g_index + + ;
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_GROUP_MEMBER :
2006-07-29 19:45:19 +04:00
fetch_groupmem_info_to_ldif (
2008-02-15 16:13:11 +03:00
u . group_member , id . rid ,
groupmap , accountmap ,
2006-07-29 19:45:19 +04:00
mod_file , num_alloced ) ;
break ;
2008-02-15 16:13:11 +03:00
case NETR_DELTA_ALIAS_MEMBER :
case NETR_DELTA_POLICY :
case NETR_DELTA_ACCOUNT :
case NETR_DELTA_TRUSTED_DOMAIN :
case NETR_DELTA_SECRET :
case NETR_DELTA_RENAME_GROUP :
case NETR_DELTA_RENAME_USER :
case NETR_DELTA_RENAME_ALIAS :
case NETR_DELTA_DELETE_GROUP :
case NETR_DELTA_DELETE_USER :
case NETR_DELTA_MODIFY_COUNT :
2006-07-29 19:45:19 +04:00
default :
2005-07-07 01:02:43 +04:00
break ;
} /* end of switch */
} /* end of for loop */
/* Increment sync_context */
sync_context + = 1 ;
} while ( NT_STATUS_EQUAL ( result , STATUS_MORE_ENTRIES ) ) ;
/* Write ldif data to the user's file */
if ( db_type = = SAM_DATABASE_DOMAIN ) {
2006-03-23 21:35:15 +03:00
fprintf ( ldif_file ,
2005-07-07 01:02:43 +04:00
" # SAM_DATABASE_DOMAIN: ADD ENTITIES \n " ) ;
2006-03-23 21:35:15 +03:00
fprintf ( ldif_file ,
2005-07-07 01:02:43 +04:00
" # ================================= \n \n " ) ;
2006-03-23 21:35:15 +03:00
fflush ( ldif_file ) ;
2005-07-07 01:02:43 +04:00
} else if ( db_type = = SAM_DATABASE_BUILTIN ) {
2006-03-23 21:35:15 +03:00
fprintf ( ldif_file ,
2005-07-07 01:02:43 +04:00
" # SAM_DATABASE_BUILTIN: ADD ENTITIES \n " ) ;
2006-03-23 21:35:15 +03:00
fprintf ( ldif_file ,
2005-07-07 01:02:43 +04:00
" # ================================== \n \n " ) ;
2006-03-23 21:35:15 +03:00
fflush ( ldif_file ) ;
2006-01-18 00:22:00 +03:00
}
2006-03-23 21:35:15 +03:00
fseek ( add_file , 0 , SEEK_SET ) ;
transfer_file ( fileno ( add_file ) , fileno ( ldif_file ) , ( size_t ) - 1 ) ;
2005-07-07 01:02:43 +04:00
if ( db_type = = SAM_DATABASE_DOMAIN ) {
2006-03-23 21:35:15 +03:00
fprintf ( ldif_file ,
2005-07-07 01:02:43 +04:00
" # SAM_DATABASE_DOMAIN: MODIFY ENTITIES \n " ) ;
2006-03-23 21:35:15 +03:00
fprintf ( ldif_file ,
2005-07-07 01:02:43 +04:00
" # ==================================== \n \n " ) ;
2006-03-23 21:35:15 +03:00
fflush ( ldif_file ) ;
2005-07-07 01:02:43 +04:00
} else if ( db_type = = SAM_DATABASE_BUILTIN ) {
2006-03-23 21:35:15 +03:00
fprintf ( ldif_file ,
2005-07-07 01:02:43 +04:00
" # SAM_DATABASE_BUILTIN: MODIFY ENTITIES \n " ) ;
2006-03-23 21:35:15 +03:00
fprintf ( ldif_file ,
2005-07-07 01:02:43 +04:00
" # ===================================== \n \n " ) ;
2006-03-23 21:35:15 +03:00
fflush ( ldif_file ) ;
2006-01-18 00:22:00 +03:00
}
2006-03-23 21:35:15 +03:00
fseek ( mod_file , 0 , SEEK_SET ) ;
transfer_file ( fileno ( mod_file ) , fileno ( ldif_file ) , ( size_t ) - 1 ) ;
2005-07-07 01:02:43 +04:00
2006-07-29 19:45:19 +04:00
done :
2006-03-23 19:39:37 +03:00
/* Close and delete the ldif files */
2006-03-27 06:51:25 +04:00
if ( add_file ) {
2006-03-23 21:35:15 +03:00
fclose ( add_file ) ;
2006-03-27 06:51:25 +04:00
}
2006-07-29 19:45:19 +04:00
if ( ( add_name ! = NULL ) & &
strcmp ( add_name , add_template ) & & ( unlink ( add_name ) ) ) {
2006-03-23 19:39:37 +03:00
DEBUG ( 1 , ( " unlink(%s) failed, error was (%s) \n " ,
2006-03-23 21:35:15 +03:00
add_name , strerror ( errno ) ) ) ;
2006-03-23 19:39:37 +03:00
}
2006-03-27 06:51:25 +04:00
if ( mod_file ) {
2006-03-23 21:35:15 +03:00
fclose ( mod_file ) ;
2006-03-27 06:51:25 +04:00
}
2006-07-29 19:45:19 +04:00
if ( ( mod_name ! = NULL ) & &
strcmp ( mod_name , mod_template ) & & ( unlink ( mod_name ) ) ) {
2006-03-23 19:39:37 +03:00
DEBUG ( 1 , ( " unlink(%s) failed, error was (%s) \n " ,
2006-03-23 21:35:15 +03:00
mod_name , strerror ( errno ) ) ) ;
2006-03-23 19:39:37 +03:00
}
2008-02-15 16:13:11 +03:00
2006-03-27 06:51:25 +04:00
if ( ldif_file & & ( ldif_file ! = stdout ) ) {
2006-03-23 21:35:15 +03:00
fclose ( ldif_file ) ;
2006-03-27 06:51:25 +04:00
}
2005-07-07 01:02:43 +04:00
/* Deallocate memory for the mapping arrays */
SAFE_FREE ( groupmap ) ;
SAFE_FREE ( accountmap ) ;
/* Return */
talloc_destroy ( mem_ctx ) ;
2006-03-10 12:41:08 +03:00
return ret ;
2005-07-07 01:02:43 +04:00
}
2008-02-15 16:13:11 +03:00
/**
2005-07-07 01:02:43 +04:00
* Basic usage function for ' net rpc vampire '
* @ param argc Standard main ( ) style argc
* @ param argc Standard main ( ) style argv . Initial components are already
* stripped
* */
2008-02-15 16:13:11 +03:00
int rpc_vampire_usage ( int argc , const char * * argv )
{
2006-07-29 19:45:19 +04:00
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 " ) ;
2005-07-07 01:02:43 +04:00
net_common_flags_usage ( argc , argv ) ;
return - 1 ;
}
2002-09-18 10:34:10 +04:00
/* dump sam database via samsync rpc calls */
2008-02-15 16:13:11 +03:00
NTSTATUS rpc_vampire_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
2005-09-30 21:13:37 +04:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-02-15 16:13:11 +03:00
TALLOC_CTX * mem_ctx ,
2005-09-30 21:13:37 +04:00
int argc ,
2008-02-15 16:13:11 +03:00
const char * * argv )
2002-09-18 10:34:10 +04:00
{
NTSTATUS result ;
2004-02-08 13:59:09 +03:00
fstring my_dom_sid_str ;
fstring rem_dom_sid_str ;
2002-09-18 10:34:10 +04:00
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 "
2006-07-29 19:45:19 +04:00
" Perhaps you need to set: \n \n \t security=user \n \t "
" workgroup=%s \n \n in your smb.conf? \n " ,
2004-02-08 13:59:09 +03:00
domain_name ,
2006-07-29 19:45:19 +04:00
get_global_sam_name ( ) ,
2008-02-15 16:13:11 +03:00
sid_to_fstring ( my_dom_sid_str ,
2007-12-16 00:47:30 +03:00
get_global_sam_sid ( ) ) ,
domain_name , sid_to_fstring ( rem_dom_sid_str ,
domain_sid ) ,
2004-02-08 13:59:09 +03:00
domain_name ) ;
return NT_STATUS_UNSUCCESSFUL ;
2002-09-18 10:34:10 +04:00
}
2005-07-07 01:02:43 +04:00
if ( argc > = 1 & & ( strcmp ( argv [ 0 ] , " ldif " ) = = 0 ) ) {
2005-09-30 21:13:37 +04:00
result = fetch_database_to_ldif ( pipe_hnd , SAM_DATABASE_DOMAIN ,
2006-07-29 19:45:19 +04:00
* domain_sid , argv [ 1 ] ) ;
2005-07-07 01:02:43 +04:00
} else {
2006-07-29 19:45:19 +04:00
result = fetch_database ( pipe_hnd , SAM_DATABASE_DOMAIN ,
* domain_sid ) ;
2005-07-07 01:02:43 +04:00
}
2003-06-16 09:39:26 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Failed to fetch domain database: %s \n " ,
2006-07-29 19:45:19 +04:00
nt_errstr ( result ) ) ;
2003-06-16 09:39:26 +04:00
if ( NT_STATUS_EQUAL ( result , NT_STATUS_NOT_SUPPORTED ) )
2006-07-29 19:45:19 +04:00
d_fprintf ( stderr , " Perhaps %s is a Windows 2000 "
" native mode 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 ) ) {
2006-07-29 19:45:19 +04:00
result = fetch_database_to_ldif ( pipe_hnd , SAM_DATABASE_BUILTIN ,
global_sid_Builtin , argv [ 1 ] ) ;
2005-07-07 01:02:43 +04:00
} else {
2006-07-29 19:45:19 +04:00
result = fetch_database ( pipe_hnd , SAM_DATABASE_BUILTIN ,
global_sid_Builtin ) ;
2005-07-07 01:02:43 +04:00
}
2003-06-16 09:39:26 +04:00
if ( ! NT_STATUS_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Failed to fetch builtin database: %s \n " ,
2006-07-29 19:45:19 +04:00
nt_errstr ( result ) ) ;
2003-06-16 09:39:26 +04:00
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); */
2006-07-29 19:45:19 +04:00
fail :
2004-02-08 13:59:09 +03:00
return result ;
2002-09-18 10:34:10 +04:00
}