2005-07-25 06:23:41 +04:00
/*
Unix SMB / CIFS implementation .
Extract the user / system database from a remote SamSync server
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2004 - 2005
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2005-07-25 06:23:41 +04:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-07-25 06:23:41 +04:00
*/
# include "includes.h"
# include "libnet/libnet.h"
2006-08-30 15:29:34 +04:00
# include "lib/util/dlinklist.h"
2006-01-03 20:27:33 +03:00
# include "samba3/samba3.h"
2006-04-29 21:34:49 +04:00
# include "libcli/security/security.h"
2005-07-25 06:23:41 +04:00
struct samdump_secret {
struct samdump_secret * prev , * next ;
DATA_BLOB secret ;
char * name ;
NTTIME mtime ;
} ;
struct samdump_trusted_domain {
struct samdump_trusted_domain * prev , * next ;
struct dom_sid * sid ;
char * name ;
} ;
struct samdump_state {
struct samdump_secret * secrets ;
struct samdump_trusted_domain * trusted_domains ;
} ;
static NTSTATUS vampire_samdump_handle_user ( TALLOC_CTX * mem_ctx ,
struct netr_DELTA_ENUM * delta )
{
uint32_t rid = delta - > delta_id_union . rid ;
struct netr_DELTA_USER * user = delta - > delta_union . user ;
const char * username = user - > account_name . string ;
char * hex_lm_password ;
char * hex_nt_password ;
hex_lm_password = smbpasswd_sethexpwd ( mem_ctx ,
user - > lm_password_present ? & user - > lmpassword : NULL ,
user - > acct_flags ) ;
hex_nt_password = smbpasswd_sethexpwd ( mem_ctx ,
user - > nt_password_present ? & user - > ntpassword : NULL ,
user - > acct_flags ) ;
printf ( " %s:%d:%s:%s:%s:LCT-%08X \n " , username ,
rid , hex_lm_password , hex_nt_password ,
smbpasswd_encode_acb_info ( mem_ctx , user - > acct_flags ) ,
( unsigned int ) nt_time_to_unix ( user - > last_password_change ) ) ;
return NT_STATUS_OK ;
}
static NTSTATUS vampire_samdump_handle_secret ( TALLOC_CTX * mem_ctx ,
struct samdump_state * samdump_state ,
struct netr_DELTA_ENUM * delta )
{
struct netr_DELTA_SECRET * secret = delta - > delta_union . secret ;
const char * name = delta - > delta_id_union . name ;
struct samdump_secret * new = talloc ( samdump_state , struct samdump_secret ) ;
2006-07-06 09:55:26 +04:00
new - > name = talloc_strdup ( new , name ) ;
2005-07-25 06:23:41 +04:00
new - > secret = data_blob_talloc ( new , secret - > current_cipher . cipher_data , secret - > current_cipher . maxlen ) ;
new - > mtime = secret - > current_cipher_set_time ;
DLIST_ADD ( samdump_state - > secrets , new ) ;
return NT_STATUS_OK ;
}
static NTSTATUS vampire_samdump_handle_trusted_domain ( TALLOC_CTX * mem_ctx ,
struct samdump_state * samdump_state ,
struct netr_DELTA_ENUM * delta )
{
struct netr_DELTA_TRUSTED_DOMAIN * trusted_domain = delta - > delta_union . trusted_domain ;
struct dom_sid * dom_sid = delta - > delta_id_union . sid ;
struct samdump_trusted_domain * new = talloc ( samdump_state , struct samdump_trusted_domain ) ;
2006-07-06 09:55:26 +04:00
new - > name = talloc_strdup ( new , trusted_domain - > domain_name . string ) ;
2005-07-25 06:23:41 +04:00
new - > sid = talloc_steal ( new , dom_sid ) ;
DLIST_ADD ( samdump_state - > trusted_domains , new ) ;
return NT_STATUS_OK ;
}
static NTSTATUS libnet_samdump_fn ( TALLOC_CTX * mem_ctx ,
void * private ,
enum netr_SamDatabaseID database ,
struct netr_DELTA_ENUM * delta ,
char * * error_string )
{
NTSTATUS nt_status = NT_STATUS_OK ;
struct samdump_state * samdump_state = private ;
* error_string = NULL ;
switch ( delta - > delta_type ) {
case NETR_DELTA_USER :
{
/* not interested in builtin users */
if ( database = = SAM_DATABASE_DOMAIN ) {
nt_status = vampire_samdump_handle_user ( mem_ctx ,
delta ) ;
}
2006-07-06 09:55:26 +04:00
break ;
2005-07-25 06:23:41 +04:00
}
case NETR_DELTA_SECRET :
{
nt_status = vampire_samdump_handle_secret ( mem_ctx ,
samdump_state ,
delta ) ;
break ;
}
case NETR_DELTA_TRUSTED_DOMAIN :
{
nt_status = vampire_samdump_handle_trusted_domain ( mem_ctx ,
samdump_state ,
delta ) ;
break ;
}
default :
/* Can't dump them all right now */
break ;
}
return nt_status ;
}
2007-09-07 19:35:18 +04:00
NTSTATUS libnet_SamDump ( struct libnet_context * ctx , TALLOC_CTX * mem_ctx ,
struct libnet_SamDump * r )
2005-07-25 06:23:41 +04:00
{
NTSTATUS nt_status ;
struct libnet_SamSync r2 ;
struct samdump_state * samdump_state = talloc ( mem_ctx , struct samdump_state ) ;
struct samdump_trusted_domain * t ;
struct samdump_secret * s ;
if ( ! samdump_state ) {
return NT_STATUS_NO_MEMORY ;
}
2006-01-12 12:33:49 +03:00
samdump_state - > secrets = NULL ;
2005-07-25 06:23:41 +04:00
samdump_state - > trusted_domains = NULL ;
2006-01-12 12:33:49 +03:00
r2 . out . error_string = NULL ;
r2 . in . binding_string = r - > in . binding_string ;
2007-02-12 16:34:04 +03:00
r2 . in . rid_crypt = lp_parm_bool ( - 1 , " vampire " , " rid decrypt " , True ) ;
2006-01-13 15:52:56 +03:00
r2 . in . init_fn = NULL ;
2006-01-12 12:33:49 +03:00
r2 . in . delta_fn = libnet_samdump_fn ;
r2 . in . fn_ctx = samdump_state ;
r2 . in . machine_account = r - > in . machine_account ;
nt_status = libnet_SamSync_netlogon ( ctx , samdump_state , & r2 ) ;
r - > out . error_string = r2 . out . error_string ;
2006-01-13 15:52:56 +03:00
talloc_steal ( mem_ctx , r - > out . error_string ) ;
2005-07-25 06:23:41 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
talloc_free ( samdump_state ) ;
return nt_status ;
}
printf ( " Trusted domains, sids and secrets: \n " ) ;
for ( t = samdump_state - > trusted_domains ; t ; t = t - > next ) {
char * secret_name = talloc_asprintf ( mem_ctx , " G$$%s " , t - > name ) ;
for ( s = samdump_state - > secrets ; s ; s = s - > next ) {
2006-01-12 12:33:49 +03:00
char * secret_string ;
if ( strcasecmp_m ( s - > name , secret_name ) ! = 0 ) {
continue ;
}
if ( convert_string_talloc ( mem_ctx , CH_UTF16 , CH_UNIX ,
s - > secret . data , s - > secret . length ,
( void * * ) & secret_string ) = = - 1 ) {
r - > out . error_string = talloc_asprintf ( mem_ctx ,
2006-09-18 13:54:44 +04:00
" Could not convert secret for domain %s to a string " ,
2006-01-12 12:33:49 +03:00
t - > name ) ;
talloc_free ( samdump_state ) ;
return NT_STATUS_INVALID_PARAMETER ;
2005-07-25 06:23:41 +04:00
}
2006-01-12 12:33:49 +03:00
printf ( " %s \t %s \t %s \n " ,
t - > name , dom_sid_string ( mem_ctx , t - > sid ) ,
secret_string ) ;
2005-07-25 06:23:41 +04:00
}
}
talloc_free ( samdump_state ) ;
return nt_status ;
}