2007-09-07 13:14:44 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2001-11-24 17:16:41 +03:00
Copyright ( C ) Andrew Tridgell 1992 - 2001
2002-07-15 14:35:28 +04:00
Copyright ( C ) Andrew Bartlett 2002
Copyright ( C ) Rafal Szczesniak 2002
2004-01-07 13:11:24 +03:00
Copyright ( C ) Tim Potter 2001
2000-05-08 22:14:25 +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
2000-05-08 22:14:25 +04:00
( at your option ) any later version .
2007-09-07 13:14:44 +04:00
2000-05-08 22:14:25 +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 .
2007-09-07 13:14:44 +04:00
2000-05-08 22:14:25 +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/>.
2000-05-08 22:14:25 +04:00
*/
2000-05-15 21:13:50 +04:00
/* the Samba secrets database stores any generated, private information
2000-05-08 22:14:25 +04:00
such as the local SID and machine trust password */
# include "includes.h"
2002-07-15 14:35:28 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_PASSDB
2008-03-11 14:30:46 +03:00
static struct db_context * db_ctx ;
2000-05-08 22:14:25 +04:00
2005-09-30 21:13:37 +04:00
/* Urrrg. global.... */
2007-10-19 04:40:25 +04:00
bool global_machine_password_needs_changing ;
2005-09-30 21:13:37 +04:00
2004-07-14 08:36:01 +04:00
/**
* Use a TDB to store an incrementing random seed .
*
* Initialised to the current pid , the very first time Samba starts ,
2007-09-07 13:14:44 +04:00
* and incremented by one each time it is needed .
*
2004-07-14 08:36:01 +04:00
* @ note Not called by systems with a working / dev / urandom .
*/
2008-10-23 20:46:35 +04:00
static void get_rand_seed ( void * userdata , int * new_seed )
2004-07-14 08:36:01 +04:00
{
* new_seed = sys_getpid ( ) ;
2008-03-11 14:30:46 +03:00
if ( db_ctx ) {
dbwrap_change_int32_atomic ( db_ctx , " INFO/random_seed " ,
new_seed , 1 ) ;
2004-07-14 08:36:01 +04:00
}
}
2000-05-08 22:14:25 +04:00
/* open up the secrets database */
2007-10-19 04:40:25 +04:00
bool secrets_init ( void )
2000-05-08 22:14:25 +04:00
{
2007-11-21 04:18:16 +03:00
char * fname = NULL ;
2004-11-25 03:25:53 +03:00
unsigned char dummy ;
2000-05-08 22:14:25 +04:00
2008-03-11 14:30:46 +03:00
if ( db_ctx ! = NULL )
2001-11-17 06:19:17 +03:00
return True ;
2000-05-08 22:14:25 +04:00
2008-03-09 13:17:48 +03:00
fname = talloc_asprintf ( talloc_tos ( ) , " %s/secrets.tdb " ,
lp_private_dir ( ) ) ;
if ( fname = = NULL ) {
2007-11-21 04:18:16 +03:00
return false ;
}
2000-05-08 22:14:25 +04:00
2008-08-07 10:20:05 +04:00
db_ctx = db_open ( NULL , fname , 0 ,
TDB_DEFAULT , O_RDWR | O_CREAT , 0600 ) ;
2000-05-08 22:14:25 +04:00
2008-03-11 14:30:46 +03:00
if ( db_ctx = = NULL ) {
2000-05-08 22:14:25 +04:00
DEBUG ( 0 , ( " Failed to open %s \n " , fname ) ) ;
2008-03-09 13:17:48 +03:00
TALLOC_FREE ( fname ) ;
2000-05-08 22:14:25 +04:00
return False ;
}
2004-07-14 08:36:01 +04:00
2008-03-09 13:17:48 +03:00
TALLOC_FREE ( fname ) ;
2007-11-21 04:18:16 +03:00
2004-07-14 08:36:01 +04:00
/**
2007-09-07 13:14:44 +04:00
* Set a reseed function for the crypto random generator
*
2004-07-14 08:36:01 +04:00
* This avoids a problem where systems without / dev / urandom
* could send the same challenge to multiple clients
*/
2008-10-23 20:46:35 +04:00
set_rand_reseed_callback ( get_rand_seed , NULL ) ;
2004-07-14 08:36:01 +04:00
/* Ensure that the reseed is done now, while we are root, etc */
generate_random_buffer ( & dummy , sizeof ( dummy ) ) ;
2000-05-08 22:14:25 +04:00
return True ;
}
2008-04-01 13:00:59 +04:00
struct db_context * secrets_db_ctx ( void )
{
if ( ! secrets_init ( ) ) {
return NULL ;
}
return db_ctx ;
}
2008-01-07 14:42:16 +03:00
/*
* close secrets . tdb
*/
void secrets_shutdown ( void )
{
2008-03-11 14:30:46 +03:00
TALLOC_FREE ( db_ctx ) ;
2008-01-07 14:42:16 +03:00
}
2000-05-08 22:14:25 +04:00
/* read a entry from the secrets database - the caller must free the result
if size is non - null then the size of the entry is put in there
*/
2002-07-15 14:35:28 +04:00
void * secrets_fetch ( const char * key , size_t * size )
2000-05-08 22:14:25 +04:00
{
2005-03-12 12:49:23 +03:00
TDB_DATA dbuf ;
2008-03-11 14:30:46 +03:00
void * result ;
2008-02-09 01:12:53 +03:00
if ( ! secrets_init ( ) ) {
2001-11-24 17:16:41 +03:00
return NULL ;
2008-02-09 01:12:53 +03:00
}
2008-03-11 14:30:46 +03:00
if ( db_ctx - > fetch ( db_ctx , talloc_tos ( ) , string_tdb_data ( key ) ,
& dbuf ) ! = 0 ) {
return NULL ;
}
result = memdup ( dbuf . dptr , dbuf . dsize ) ;
if ( result = = NULL ) {
return NULL ;
}
TALLOC_FREE ( dbuf . dptr ) ;
2008-02-09 01:12:53 +03:00
if ( size ) {
2001-11-17 06:19:17 +03:00
* size = dbuf . dsize ;
2008-02-09 01:12:53 +03:00
}
2008-03-11 14:30:46 +03:00
return result ;
2000-05-08 22:14:25 +04:00
}
2007-09-07 13:14:44 +04:00
/* store a secrets entry
2000-05-08 22:14:25 +04:00
*/
2007-10-19 04:40:25 +04:00
bool secrets_store ( const char * key , const void * data , size_t size )
2000-05-08 22:14:25 +04:00
{
2008-03-28 13:53:00 +03:00
NTSTATUS status ;
2008-02-09 01:12:53 +03:00
if ( ! secrets_init ( ) ) {
return false ;
}
2008-03-28 13:53:00 +03:00
status = dbwrap_trans_store ( db_ctx , string_tdb_data ( key ) ,
make_tdb_data ( ( const uint8 * ) data , size ) ,
TDB_REPLACE ) ;
return NT_STATUS_IS_OK ( status ) ;
2000-05-08 22:14:25 +04:00
}
/* delete a secets database entry
*/
2007-10-19 04:40:25 +04:00
bool secrets_delete ( const char * key )
2000-05-08 22:14:25 +04:00
{
2008-03-28 13:57:54 +03:00
NTSTATUS status ;
2008-02-09 01:12:53 +03:00
if ( ! secrets_init ( ) ) {
return false ;
}
2008-03-28 13:57:54 +03:00
status = dbwrap_trans_delete ( db_ctx , string_tdb_data ( key ) ) ;
return NT_STATUS_IS_OK ( status ) ;
2000-05-08 22:14:25 +04:00
}
2000-05-29 05:23:48 +04:00
2007-12-19 12:58:58 +03:00
/**
* Form a key for fetching the domain sid
*
* @ param domain domain name
*
* @ return keystring
* */
static const char * domain_sid_keystr ( const char * domain )
{
char * keystr ;
2008-03-09 13:26:50 +03:00
keystr = talloc_asprintf_strupper_m ( talloc_tos ( ) , " %s/%s " ,
SECRETS_DOMAIN_SID , domain ) ;
2007-12-19 12:58:58 +03:00
SMB_ASSERT ( keystr ! = NULL ) ;
return keystr ;
}
2007-10-19 04:40:25 +04:00
bool secrets_store_domain_sid ( const char * domain , const DOM_SID * sid )
2000-05-29 05:23:48 +04:00
{
2007-10-19 04:40:25 +04:00
bool ret ;
2000-05-29 05:23:48 +04:00
2007-12-19 12:58:58 +03:00
ret = secrets_store ( domain_sid_keystr ( domain ) , sid , sizeof ( DOM_SID ) ) ;
2004-02-08 14:05:34 +03:00
/* Force a re-query, in case we modified our domain */
if ( ret )
reset_global_sam_sid ( ) ;
return ret ;
2000-05-29 05:23:48 +04:00
}
2007-10-19 04:40:25 +04:00
bool secrets_fetch_domain_sid ( const char * domain , DOM_SID * sid )
2000-05-29 05:23:48 +04:00
{
DOM_SID * dyn_sid ;
2005-12-03 09:46:46 +03:00
size_t size = 0 ;
2000-05-29 05:23:48 +04:00
2007-12-19 12:58:58 +03:00
dyn_sid = ( DOM_SID * ) secrets_fetch ( domain_sid_keystr ( domain ) , & size ) ;
2000-05-29 05:23:48 +04:00
if ( dyn_sid = = NULL )
return False ;
2007-09-07 13:14:44 +04:00
if ( size ! = sizeof ( DOM_SID ) ) {
2001-09-17 09:04:17 +04:00
SAFE_FREE ( dyn_sid ) ;
2000-05-29 05:23:48 +04:00
return False ;
}
* sid = * dyn_sid ;
2001-09-17 09:04:17 +04:00
SAFE_FREE ( dyn_sid ) ;
2000-05-29 05:23:48 +04:00
return True ;
}
2007-10-19 04:40:25 +04:00
bool secrets_store_domain_guid ( const char * domain , struct GUID * guid )
2002-08-17 21:00:51 +04:00
{
fstring key ;
slprintf ( key , sizeof ( key ) - 1 , " %s/%s " , SECRETS_DOMAIN_GUID , domain ) ;
2003-07-03 23:11:31 +04:00
strupper_m ( key ) ;
2006-09-19 04:12:11 +04:00
return secrets_store ( key , guid , sizeof ( struct GUID ) ) ;
2002-08-17 21:00:51 +04:00
}
2007-10-19 04:40:25 +04:00
bool secrets_fetch_domain_guid ( const char * domain , struct GUID * guid )
2002-08-17 21:00:51 +04:00
{
2006-09-19 04:12:11 +04:00
struct GUID * dyn_guid ;
2002-08-17 21:00:51 +04:00
fstring key ;
2005-12-03 09:46:46 +03:00
size_t size = 0 ;
2006-09-19 04:12:11 +04:00
struct GUID new_guid ;
2002-08-17 21:00:51 +04:00
slprintf ( key , sizeof ( key ) - 1 , " %s/%s " , SECRETS_DOMAIN_GUID , domain ) ;
2003-07-03 23:11:31 +04:00
strupper_m ( key ) ;
2006-09-19 04:12:11 +04:00
dyn_guid = ( struct GUID * ) secrets_fetch ( key , & size ) ;
2002-08-17 21:00:51 +04:00
2006-03-09 22:03:31 +03:00
if ( ! dyn_guid ) {
if ( lp_server_role ( ) = = ROLE_DOMAIN_PDC ) {
2008-10-14 04:41:20 +04:00
new_guid = GUID_random ( ) ;
2006-03-09 22:03:31 +03:00
if ( ! secrets_store_domain_guid ( domain , & new_guid ) )
return False ;
2006-09-19 04:12:11 +04:00
dyn_guid = ( struct GUID * ) secrets_fetch ( key , & size ) ;
2006-03-09 22:03:31 +03:00
}
if ( dyn_guid = = NULL ) {
2002-08-17 21:00:51 +04:00
return False ;
2006-03-09 22:03:31 +03:00
}
2002-08-17 21:00:51 +04:00
}
2007-09-07 13:14:44 +04:00
if ( size ! = sizeof ( struct GUID ) ) {
2004-04-13 18:39:48 +04:00
DEBUG ( 1 , ( " UUID size %d is wrong! \n " , ( int ) size ) ) ;
2002-08-17 21:00:51 +04:00
SAFE_FREE ( dyn_guid ) ;
return False ;
}
* guid = * dyn_guid ;
SAFE_FREE ( dyn_guid ) ;
return True ;
}
2000-06-03 10:16:11 +04:00
2008-09-22 21:23:21 +04:00
bool secrets_store_local_schannel_key ( uint8_t schannel_key [ 16 ] )
{
return secrets_store ( SECRETS_LOCAL_SCHANNEL_KEY , schannel_key , 16 ) ;
}
bool secrets_fetch_local_schannel_key ( uint8_t schannel_key [ 16 ] )
{
size_t size = 0 ;
uint8_t * key ;
key = ( uint8_t * ) secrets_fetch ( SECRETS_LOCAL_SCHANNEL_KEY , & size ) ;
if ( key = = NULL ) {
return false ;
}
if ( size ! = 16 ) {
SAFE_FREE ( key ) ;
return false ;
}
memcpy ( schannel_key , key , 16 ) ;
SAFE_FREE ( key ) ;
return true ;
}
2007-12-19 12:58:58 +03:00
/**
* Form a key for fetching the machine trust account sec channel type
*
* @ param domain domain name
*
* @ return keystring
* */
static const char * machine_sec_channel_type_keystr ( const char * domain )
{
char * keystr ;
2008-03-09 13:26:50 +03:00
keystr = talloc_asprintf_strupper_m ( talloc_tos ( ) , " %s/%s " ,
SECRETS_MACHINE_SEC_CHANNEL_TYPE ,
domain ) ;
2007-12-19 12:58:58 +03:00
SMB_ASSERT ( keystr ! = NULL ) ;
return keystr ;
}
/**
* Form a key for fetching the machine trust account last change time
*
* @ param domain domain name
*
* @ return keystring
* */
static const char * machine_last_change_time_keystr ( const char * domain )
{
char * keystr ;
2008-03-09 13:26:50 +03:00
keystr = talloc_asprintf_strupper_m ( talloc_tos ( ) , " %s/%s " ,
SECRETS_MACHINE_LAST_CHANGE_TIME ,
domain ) ;
2007-12-19 12:58:58 +03:00
SMB_ASSERT ( keystr ! = NULL ) ;
return keystr ;
}
/**
* Form a key for fetching the machine trust account password
*
* @ param domain domain name
*
* @ return keystring
* */
static const char * machine_password_keystr ( const char * domain )
{
char * keystr ;
2008-03-09 13:26:50 +03:00
keystr = talloc_asprintf_strupper_m ( talloc_tos ( ) , " %s/%s " ,
SECRETS_MACHINE_PASSWORD , domain ) ;
2007-12-19 12:58:58 +03:00
SMB_ASSERT ( keystr ! = NULL ) ;
return keystr ;
}
2002-07-15 14:35:28 +04:00
/**
* Form a key for fetching the machine trust account password
*
* @ param domain domain name
*
* @ return stored password ' s key
* */
2007-01-10 10:56:43 +03:00
static const char * trust_keystr ( const char * domain )
2000-06-03 10:16:11 +04:00
{
2007-11-04 20:15:37 +03:00
char * keystr ;
2008-03-09 13:26:50 +03:00
keystr = talloc_asprintf_strupper_m ( talloc_tos ( ) , " %s/%s " ,
SECRETS_MACHINE_ACCT_PASS , domain ) ;
2007-11-04 20:15:37 +03:00
SMB_ASSERT ( keystr ! = NULL ) ;
2000-06-03 10:16:11 +04:00
return keystr ;
}
2002-03-01 05:56:35 +03:00
/**
* Form a key for fetching a trusted domain password
*
2002-07-15 14:35:28 +04:00
* @ param domain trusted domain name
2002-03-01 05:56:35 +03:00
*
* @ return stored password ' s key
* */
2003-07-19 15:28:15 +04:00
static char * trustdom_keystr ( const char * domain )
2002-03-01 05:56:35 +03:00
{
2007-11-04 20:15:37 +03:00
char * keystr ;
2002-03-01 05:56:35 +03:00
2008-03-09 13:26:50 +03:00
keystr = talloc_asprintf_strupper_m ( talloc_tos ( ) , " %s/%s " ,
SECRETS_DOMTRUST_ACCT_PASS ,
domain ) ;
2007-11-04 20:15:37 +03:00
SMB_ASSERT ( keystr ! = NULL ) ;
2002-03-01 05:56:35 +03:00
return keystr ;
}
2000-06-03 10:16:11 +04:00
/************************************************************************
2002-09-25 19:19:00 +04:00
Lock the trust password entry .
2000-06-03 10:16:11 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-25 19:19:00 +04:00
2008-03-10 17:48:04 +03:00
void * secrets_get_trust_account_lock ( TALLOC_CTX * mem_ctx , const char * domain )
2002-09-25 19:19:00 +04:00
{
2008-03-10 17:48:04 +03:00
if ( ! secrets_init ( ) ) {
return NULL ;
}
2008-03-11 14:30:46 +03:00
return db_ctx - > fetch_locked (
db_ctx , mem_ctx , string_term_tdb_data ( trust_keystr ( domain ) ) ) ;
2002-09-25 19:19:00 +04:00
}
2003-04-21 18:09:03 +04:00
/************************************************************************
Routine to get the default secure channel type for trust accounts
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-09-07 13:14:44 +04:00
uint32 get_default_sec_channel ( void )
2003-04-21 18:09:03 +04:00
{
2007-09-07 13:14:44 +04:00
if ( lp_server_role ( ) = = ROLE_DOMAIN_BDC | |
2003-04-21 18:09:03 +04:00
lp_server_role ( ) = = ROLE_DOMAIN_PDC ) {
return SEC_CHAN_BDC ;
} else {
return SEC_CHAN_WKSTA ;
}
}
2002-09-25 19:19:00 +04:00
/************************************************************************
Routine to get the trust account password for a domain .
2007-12-11 16:02:45 +03:00
This only tries to get the legacy hashed version of the password .
2002-09-25 19:19:00 +04:00
The user of this function must have locked the trust password file using
2004-04-13 18:39:48 +04:00
the above secrets_lock_trust_account_password ( ) .
2002-09-25 19:19:00 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-12-11 16:02:45 +03:00
bool secrets_fetch_trust_account_password_legacy ( const char * domain ,
uint8 ret_pwd [ 16 ] ,
time_t * pass_last_set_time ,
uint32 * channel )
2000-06-03 10:16:11 +04:00
{
struct machine_acct_pass * pass ;
2005-12-03 09:46:46 +03:00
size_t size = 0 ;
2000-06-03 10:16:11 +04:00
2006-07-11 22:01:26 +04:00
if ( ! ( pass = ( struct machine_acct_pass * ) secrets_fetch (
trust_keystr ( domain ) , & size ) ) ) {
2001-12-05 13:52:13 +03:00
DEBUG ( 5 , ( " secrets_fetch failed! \n " ) ) ;
2000-11-28 02:59:42 +03:00
return False ;
2001-12-05 13:52:13 +03:00
}
2007-09-07 13:14:44 +04:00
2001-12-05 13:52:13 +03:00
if ( size ! = sizeof ( * pass ) ) {
DEBUG ( 0 , ( " secrets were of incorrect size! \n " ) ) ;
2008-06-07 10:50:02 +04:00
SAFE_FREE ( pass ) ;
2001-12-05 13:52:13 +03:00
return False ;
}
2000-06-03 10:16:11 +04:00
2005-09-30 21:13:37 +04:00
if ( pass_last_set_time ) {
* pass_last_set_time = pass - > mod_time ;
}
2000-06-03 10:16:11 +04:00
memcpy ( ret_pwd , pass - > hash , 16 ) ;
2003-04-21 18:09:03 +04:00
2005-09-30 21:13:37 +04:00
if ( channel ) {
2003-04-21 18:09:03 +04:00
* channel = get_default_sec_channel ( ) ;
2005-09-30 21:13:37 +04:00
}
/* Test if machine password has expired and needs to be changed */
if ( lp_machine_password_timeout ( ) ) {
if ( pass - > mod_time > 0 & & time ( NULL ) > ( pass - > mod_time +
2006-06-07 08:45:50 +04:00
( time_t ) lp_machine_password_timeout ( ) ) ) {
2005-09-30 21:13:37 +04:00
global_machine_password_needs_changing = True ;
}
}
2003-04-21 18:09:03 +04:00
2006-01-27 22:24:37 +03:00
SAFE_FREE ( pass ) ;
2000-06-03 10:16:11 +04:00
return True ;
}
2007-12-11 16:02:45 +03:00
/************************************************************************
Routine to get the trust account password for a domain .
The user of this function must have locked the trust password file using
the above secrets_lock_trust_account_password ( ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool secrets_fetch_trust_account_password ( const char * domain , uint8 ret_pwd [ 16 ] ,
time_t * pass_last_set_time ,
uint32 * channel )
{
char * plaintext ;
plaintext = secrets_fetch_machine_password ( domain , pass_last_set_time ,
channel ) ;
if ( plaintext ) {
DEBUG ( 4 , ( " Using cleartext machine password \n " ) ) ;
E_md4hash ( plaintext , ret_pwd ) ;
SAFE_FREE ( plaintext ) ;
return True ;
}
return secrets_fetch_trust_account_password_legacy ( domain , ret_pwd ,
pass_last_set_time ,
channel ) ;
}
2006-07-11 22:01:26 +04:00
/**
* Pack SID passed by pointer
*
* @ param pack_buf pointer to buffer which is to be filled with packed data
* @ param bufsize size of packing buffer
* @ param sid pointer to sid to be packed
*
* @ return length of the packed representation of the whole structure
* */
2007-03-29 13:35:51 +04:00
static size_t tdb_sid_pack ( uint8 * pack_buf , int bufsize , DOM_SID * sid )
2006-07-11 22:01:26 +04:00
{
int idx ;
size_t len = 0 ;
2007-11-21 04:18:16 +03:00
uint8 * p = pack_buf ;
int remaining_space = pack_buf ? bufsize : 0 ;
2007-09-07 13:14:44 +04:00
2007-11-21 04:18:16 +03:00
if ( ! sid ) {
return - 1 ;
}
2007-09-07 13:14:44 +04:00
2007-11-21 04:18:16 +03:00
len + = tdb_pack ( p , remaining_space , " bb " , sid - > sid_rev_num ,
2006-07-11 22:01:26 +04:00
sid - > num_auths ) ;
2007-11-21 04:18:16 +03:00
if ( pack_buf ) {
2007-12-12 15:50:48 +03:00
p = pack_buf + len ;
remaining_space = bufsize - len ;
2007-11-21 04:18:16 +03:00
}
2007-09-07 13:14:44 +04:00
2006-07-11 22:01:26 +04:00
for ( idx = 0 ; idx < 6 ; idx + + ) {
2007-11-21 04:18:16 +03:00
len + = tdb_pack ( p , remaining_space , " b " ,
2006-07-11 22:01:26 +04:00
sid - > id_auth [ idx ] ) ;
2007-11-21 04:18:16 +03:00
if ( pack_buf ) {
2007-12-12 15:50:48 +03:00
p = pack_buf + len ;
remaining_space = bufsize - len ;
2007-11-21 04:18:16 +03:00
}
2006-07-11 22:01:26 +04:00
}
2007-09-07 13:14:44 +04:00
2006-07-11 22:01:26 +04:00
for ( idx = 0 ; idx < MAXSUBAUTHS ; idx + + ) {
2007-11-21 04:18:16 +03:00
len + = tdb_pack ( p , remaining_space , " d " ,
2006-07-11 22:01:26 +04:00
sid - > sub_auths [ idx ] ) ;
2007-11-21 04:18:16 +03:00
if ( pack_buf ) {
2007-12-12 15:50:48 +03:00
p = pack_buf + len ;
remaining_space = bufsize - len ;
2007-11-21 04:18:16 +03:00
}
2006-07-11 22:01:26 +04:00
}
2007-09-07 13:14:44 +04:00
2006-07-11 22:01:26 +04:00
return len ;
}
/**
* Unpack SID into a pointer
*
* @ param pack_buf pointer to buffer with packed representation
* @ param bufsize size of the buffer
* @ param sid pointer to sid structure to be filled with unpacked data
*
* @ return size of structure unpacked from buffer
* */
2007-03-29 13:35:51 +04:00
static size_t tdb_sid_unpack ( uint8 * pack_buf , int bufsize , DOM_SID * sid )
2006-07-11 22:01:26 +04:00
{
int idx , len = 0 ;
2007-09-07 13:14:44 +04:00
2006-07-11 22:01:26 +04:00
if ( ! sid | | ! pack_buf ) return - 1 ;
len + = tdb_unpack ( pack_buf + len , bufsize - len , " bb " ,
& sid - > sid_rev_num , & sid - > num_auths ) ;
2007-09-07 13:14:44 +04:00
2006-07-11 22:01:26 +04:00
for ( idx = 0 ; idx < 6 ; idx + + ) {
len + = tdb_unpack ( pack_buf + len , bufsize - len , " b " ,
& sid - > id_auth [ idx ] ) ;
}
2007-09-07 13:14:44 +04:00
2006-07-11 22:01:26 +04:00
for ( idx = 0 ; idx < MAXSUBAUTHS ; idx + + ) {
len + = tdb_unpack ( pack_buf + len , bufsize - len , " d " ,
& sid - > sub_auths [ idx ] ) ;
}
2007-09-07 13:14:44 +04:00
2006-07-11 22:01:26 +04:00
return len ;
}
/**
* Pack TRUSTED_DOM_PASS passed by pointer
*
* @ param pack_buf pointer to buffer which is to be filled with packed data
* @ param bufsize size of the buffer
* @ param pass pointer to trusted domain password to be packed
*
* @ return length of the packed representation of the whole structure
* */
2007-03-29 13:35:51 +04:00
static size_t tdb_trusted_dom_pass_pack ( uint8 * pack_buf , int bufsize ,
2006-07-11 22:01:26 +04:00
TRUSTED_DOM_PASS * pass )
{
int idx , len = 0 ;
2007-11-21 04:18:16 +03:00
uint8 * p = pack_buf ;
int remaining_space = pack_buf ? bufsize : 0 ;
2007-09-07 13:14:44 +04:00
2007-11-21 04:18:16 +03:00
if ( ! pass ) {
return - 1 ;
}
2007-09-07 13:14:44 +04:00
2006-07-11 22:01:26 +04:00
/* packing unicode domain name and password */
2007-11-21 04:18:16 +03:00
len + = tdb_pack ( p , remaining_space , " d " ,
2006-07-11 22:01:26 +04:00
pass - > uni_name_len ) ;
2007-11-21 04:18:16 +03:00
if ( pack_buf ) {
2007-12-12 15:50:48 +03:00
p = pack_buf + len ;
remaining_space = bufsize - len ;
2007-11-21 04:18:16 +03:00
}
2007-09-07 13:14:44 +04:00
2007-11-21 04:18:16 +03:00
for ( idx = 0 ; idx < 32 ; idx + + ) {
len + = tdb_pack ( p , remaining_space , " w " ,
2006-07-11 22:01:26 +04:00
pass - > uni_name [ idx ] ) ;
2007-11-21 04:18:16 +03:00
if ( pack_buf ) {
2007-12-12 15:50:48 +03:00
p = pack_buf + len ;
remaining_space = bufsize - len ;
2007-11-21 04:18:16 +03:00
}
}
2007-09-07 13:14:44 +04:00
2007-11-21 04:18:16 +03:00
len + = tdb_pack ( p , remaining_space , " dPd " , pass - > pass_len ,
2006-07-11 22:01:26 +04:00
pass - > pass , pass - > mod_time ) ;
2007-11-21 04:18:16 +03:00
if ( pack_buf ) {
2007-12-12 15:50:48 +03:00
p = pack_buf + len ;
remaining_space = bufsize - len ;
2007-11-21 04:18:16 +03:00
}
2006-07-11 22:01:26 +04:00
/* packing SID structure */
2007-11-21 04:18:16 +03:00
len + = tdb_sid_pack ( p , remaining_space , & pass - > domain_sid ) ;
if ( pack_buf ) {
2007-12-12 15:50:48 +03:00
p = pack_buf + len ;
remaining_space = bufsize - len ;
2007-11-21 04:18:16 +03:00
}
2006-07-11 22:01:26 +04:00
return len ;
}
/**
* Unpack TRUSTED_DOM_PASS passed by pointer
*
* @ param pack_buf pointer to buffer with packed representation
* @ param bufsize size of the buffer
* @ param pass pointer to trusted domain password to be filled with unpacked data
*
* @ return size of structure unpacked from buffer
* */
2007-03-29 13:35:51 +04:00
static size_t tdb_trusted_dom_pass_unpack ( uint8 * pack_buf , int bufsize ,
2007-01-10 10:56:43 +03:00
TRUSTED_DOM_PASS * pass )
2006-07-11 22:01:26 +04:00
{
int idx , len = 0 ;
2007-12-04 01:54:06 +03:00
char * passp = NULL ;
2007-09-07 13:14:44 +04:00
2006-07-11 22:01:26 +04:00
if ( ! pack_buf | | ! pass ) return - 1 ;
/* unpack unicode domain name and plaintext password */
len + = tdb_unpack ( pack_buf , bufsize - len , " d " , & pass - > uni_name_len ) ;
2007-09-07 13:14:44 +04:00
2006-07-11 22:01:26 +04:00
for ( idx = 0 ; idx < 32 ; idx + + )
len + = tdb_unpack ( pack_buf + len , bufsize - len , " w " ,
& pass - > uni_name [ idx ] ) ;
len + = tdb_unpack ( pack_buf + len , bufsize - len , " dPd " ,
2007-12-04 01:54:06 +03:00
& pass - > pass_len , & passp , & pass - > mod_time ) ;
if ( passp ) {
fstrcpy ( pass - > pass , passp ) ;
}
SAFE_FREE ( passp ) ;
2007-09-07 13:14:44 +04:00
2006-07-11 22:01:26 +04:00
/* unpack domain sid */
len + = tdb_sid_unpack ( pack_buf + len , bufsize - len ,
& pass - > domain_sid ) ;
2007-09-07 13:14:44 +04:00
return len ;
2006-07-11 22:01:26 +04:00
}
2002-03-01 05:56:35 +03:00
/************************************************************************
Routine to get account password to trusted domain
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-25 19:19:00 +04:00
2007-10-19 04:40:25 +04:00
bool secrets_fetch_trusted_domain_password ( const char * domain , char * * pwd ,
2003-04-22 17:10:02 +04:00
DOM_SID * sid , time_t * pass_last_set_time )
2002-03-01 05:56:35 +03:00
{
2003-04-22 17:10:02 +04:00
struct trusted_dom_pass pass ;
2005-12-03 09:46:46 +03:00
size_t size = 0 ;
2007-09-07 13:14:44 +04:00
2003-04-22 17:10:02 +04:00
/* unpacking structures */
2007-03-29 13:35:51 +04:00
uint8 * pass_buf ;
2003-04-22 17:10:02 +04:00
int pass_len = 0 ;
ZERO_STRUCT ( pass ) ;
2002-03-01 05:56:35 +03:00
2002-07-15 14:35:28 +04:00
/* fetching trusted domain password structure */
2007-03-29 13:35:51 +04:00
if ( ! ( pass_buf = ( uint8 * ) secrets_fetch ( trustdom_keystr ( domain ) ,
2006-07-11 22:01:26 +04:00
& size ) ) ) {
2002-03-01 05:56:35 +03:00
DEBUG ( 5 , ( " secrets_fetch failed! \n " ) ) ;
return False ;
}
2002-07-15 14:35:28 +04:00
2003-04-22 17:10:02 +04:00
/* unpack trusted domain password */
pass_len = tdb_trusted_dom_pass_unpack ( pass_buf , size , & pass ) ;
SAFE_FREE ( pass_buf ) ;
if ( pass_len ! = size ) {
DEBUG ( 5 , ( " Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure. \n " ) ) ;
2002-03-01 05:56:35 +03:00
return False ;
}
2007-09-07 13:14:44 +04:00
/* the trust's password */
2002-03-02 07:45:29 +03:00
if ( pwd ) {
2004-12-07 21:25:53 +03:00
* pwd = SMB_STRDUP ( pass . pass ) ;
2002-03-02 07:45:29 +03:00
if ( ! * pwd ) {
return False ;
}
}
2002-03-01 05:56:35 +03:00
2002-07-15 14:35:28 +04:00
/* last change time */
2003-04-22 17:10:02 +04:00
if ( pass_last_set_time ) * pass_last_set_time = pass . mod_time ;
2002-03-01 05:56:35 +03:00
2002-07-15 14:35:28 +04:00
/* domain sid */
2005-12-03 21:34:13 +03:00
if ( sid ! = NULL ) sid_copy ( sid , & pass . domain_sid ) ;
2007-09-07 13:14:44 +04:00
2002-03-01 05:56:35 +03:00
return True ;
}
2000-06-03 10:16:11 +04:00
2002-03-01 05:56:35 +03:00
/**
2003-04-22 17:10:02 +04:00
* Routine to store the password for trusted domain
2002-03-01 05:56:35 +03:00
*
* @ param domain remote domain name
* @ param pwd plain text password of trust relationship
* @ param sid remote domain sid
*
* @ return true if succeeded
* */
2007-10-19 04:40:25 +04:00
bool secrets_store_trusted_domain_password ( const char * domain , const char * pwd ,
2006-02-04 01:19:41 +03:00
const DOM_SID * sid )
{
smb_ucs2_t * uni_dom_name ;
2007-11-21 04:18:16 +03:00
bool ret ;
2008-04-30 01:36:24 +04:00
size_t converted_size ;
2006-02-04 01:19:41 +03:00
2003-04-22 17:10:02 +04:00
/* packing structures */
2007-11-21 04:18:16 +03:00
uint8 * pass_buf = NULL ;
2003-04-22 17:10:02 +04:00
int pass_len = 0 ;
2007-09-07 13:14:44 +04:00
2002-03-01 05:56:35 +03:00
struct trusted_dom_pass pass ;
2002-03-02 07:45:29 +03:00
ZERO_STRUCT ( pass ) ;
2006-02-04 01:19:41 +03:00
2008-04-30 01:36:24 +04:00
if ( ! push_ucs2_allocate ( & uni_dom_name , domain , & converted_size ) ) {
2006-02-04 01:19:41 +03:00
DEBUG ( 0 , ( " Could not convert domain name %s to unicode \n " ,
domain ) ) ;
2002-07-15 14:35:28 +04:00
return False ;
2006-02-04 01:19:41 +03:00
}
2007-09-07 13:14:44 +04:00
2002-07-15 14:35:28 +04:00
strncpy_w ( pass . uni_name , uni_dom_name , sizeof ( pass . uni_name ) - 1 ) ;
2006-02-04 01:19:41 +03:00
pass . uni_name_len = strlen_w ( uni_dom_name ) + 1 ;
2006-03-10 00:15:10 +03:00
SAFE_FREE ( uni_dom_name ) ;
2002-07-15 14:35:28 +04:00
/* last change time */
2002-03-01 05:56:35 +03:00
pass . mod_time = time ( NULL ) ;
2002-07-15 14:35:28 +04:00
/* password of the trust */
2002-03-01 05:56:35 +03:00
pass . pass_len = strlen ( pwd ) ;
2002-03-02 07:45:29 +03:00
fstrcpy ( pass . pass , pwd ) ;
2002-03-01 05:56:35 +03:00
2002-07-15 14:35:28 +04:00
/* domain sid */
2006-02-04 01:19:41 +03:00
sid_copy ( & pass . domain_sid , sid ) ;
2007-09-07 13:14:44 +04:00
2007-11-21 04:18:16 +03:00
/* Calculate the length. */
pass_len = tdb_trusted_dom_pass_pack ( NULL , 0 , & pass ) ;
pass_buf = SMB_MALLOC_ARRAY ( uint8 , pass_len ) ;
if ( ! pass_buf ) {
return false ;
}
pass_len = tdb_trusted_dom_pass_pack ( pass_buf , pass_len , & pass ) ;
2007-12-12 15:37:46 +03:00
ret = secrets_store ( trustdom_keystr ( domain ) , ( void * ) pass_buf ,
2007-11-21 04:18:16 +03:00
pass_len ) ;
SAFE_FREE ( pass_buf ) ;
return ret ;
2002-03-01 05:56:35 +03:00
}
2007-12-19 12:58:58 +03:00
/************************************************************************
Routine to delete the plaintext machine account password
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool secrets_delete_machine_password ( const char * domain )
{
return secrets_delete ( machine_password_keystr ( domain ) ) ;
}
/************************************************************************
Routine to delete the plaintext machine account password , sec channel type and
last change time from secrets database
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool secrets_delete_machine_password_ex ( const char * domain )
{
if ( ! secrets_delete ( machine_password_keystr ( domain ) ) ) {
return false ;
}
if ( ! secrets_delete ( machine_sec_channel_type_keystr ( domain ) ) ) {
return false ;
}
return secrets_delete ( machine_last_change_time_keystr ( domain ) ) ;
}
/************************************************************************
Routine to delete the domain sid
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool secrets_delete_domain_sid ( const char * domain )
{
return secrets_delete ( domain_sid_keystr ( domain ) ) ;
}
2001-11-24 17:16:41 +03:00
/************************************************************************
Routine to set the plaintext machine account password for a realm
the password is assumed to be a null terminated ascii string
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-09 02:08:59 +03:00
2007-10-19 04:40:25 +04:00
bool secrets_store_machine_password ( const char * pass , const char * domain , uint32 sec_channel )
2001-11-24 17:16:41 +03:00
{
2007-10-19 04:40:25 +04:00
bool ret ;
2003-04-21 18:09:03 +04:00
uint32 last_change_time ;
uint32 sec_channel_type ;
2007-12-19 12:58:58 +03:00
ret = secrets_store ( machine_password_keystr ( domain ) , pass , strlen ( pass ) + 1 ) ;
2007-10-11 00:34:30 +04:00
if ( ! ret )
return ret ;
2007-09-07 13:14:44 +04:00
2003-04-21 18:09:03 +04:00
SIVAL ( & last_change_time , 0 , time ( NULL ) ) ;
2007-12-19 12:58:58 +03:00
ret = secrets_store ( machine_last_change_time_keystr ( domain ) , & last_change_time , sizeof ( last_change_time ) ) ;
2003-04-21 18:09:03 +04:00
SIVAL ( & sec_channel_type , 0 , sec_channel ) ;
2007-12-19 12:58:58 +03:00
ret = secrets_store ( machine_sec_channel_type_keystr ( domain ) , & sec_channel_type , sizeof ( sec_channel_type ) ) ;
2003-04-21 18:09:03 +04:00
2007-10-11 00:34:30 +04:00
return ret ;
2001-11-24 17:16:41 +03:00
}
/************************************************************************
Routine to fetch the plaintext machine account password for a realm
2005-09-30 21:13:37 +04:00
the password is assumed to be a null terminated ascii string .
2001-11-24 17:16:41 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
2007-09-07 13:14:44 +04:00
char * secrets_fetch_machine_password ( const char * domain ,
2003-04-21 18:09:03 +04:00
time_t * pass_last_set_time ,
uint32 * channel )
2001-11-24 17:16:41 +03:00
{
2002-02-22 06:18:37 +03:00
char * ret ;
2007-12-19 12:58:58 +03:00
ret = ( char * ) secrets_fetch ( machine_password_keystr ( domain ) , NULL ) ;
2007-09-07 13:14:44 +04:00
2003-04-21 18:09:03 +04:00
if ( pass_last_set_time ) {
size_t size ;
uint32 * last_set_time ;
2007-12-19 12:58:58 +03:00
last_set_time = ( unsigned int * ) secrets_fetch ( machine_last_change_time_keystr ( domain ) , & size ) ;
2003-04-21 18:09:03 +04:00
if ( last_set_time ) {
* pass_last_set_time = IVAL ( last_set_time , 0 ) ;
2003-06-21 18:28:18 +04:00
SAFE_FREE ( last_set_time ) ;
2003-04-21 18:09:03 +04:00
} else {
* pass_last_set_time = 0 ;
}
}
2007-09-07 13:14:44 +04:00
2003-04-21 18:09:03 +04:00
if ( channel ) {
size_t size ;
uint32 * channel_type ;
2007-12-19 12:58:58 +03:00
channel_type = ( unsigned int * ) secrets_fetch ( machine_sec_channel_type_keystr ( domain ) , & size ) ;
2003-04-21 18:09:03 +04:00
if ( channel_type ) {
* channel = IVAL ( channel_type , 0 ) ;
2003-06-21 18:28:18 +04:00
SAFE_FREE ( channel_type ) ;
2003-04-21 18:09:03 +04:00
} else {
* channel = get_default_sec_channel ( ) ;
}
}
2007-09-07 13:14:44 +04:00
2002-02-22 06:18:37 +03:00
return ret ;
2001-11-24 17:16:41 +03:00
}
2002-03-01 05:56:35 +03:00
/************************************************************************
Routine to delete the password for trusted domain
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-09 02:08:59 +03:00
2007-10-19 04:40:25 +04:00
bool trusted_domain_password_delete ( const char * domain )
2002-03-01 05:56:35 +03:00
{
return secrets_delete ( trustdom_keystr ( domain ) ) ;
}
2007-10-19 04:40:25 +04:00
bool secrets_store_ldap_pw ( const char * dn , char * pw )
2001-12-13 21:09:29 +03:00
{
2002-07-15 14:35:28 +04:00
char * key = NULL ;
2007-10-19 04:40:25 +04:00
bool ret ;
2007-09-07 13:14:44 +04:00
2002-07-15 14:35:28 +04:00
if ( asprintf ( & key , " %s/%s " , SECRETS_LDAP_BIND_PW , dn ) < 0 ) {
DEBUG ( 0 , ( " secrets_store_ldap_pw: asprintf failed! \n " ) ) ;
return False ;
}
2007-09-07 13:14:44 +04:00
2002-07-15 14:35:28 +04:00
ret = secrets_store ( key , pw , strlen ( pw ) + 1 ) ;
2007-09-07 13:14:44 +04:00
2002-07-15 14:35:28 +04:00
SAFE_FREE ( key ) ;
return ret ;
}
2005-05-31 17:46:45 +04:00
/*******************************************************************
2005-09-30 21:13:37 +04:00
Find the ldap password .
2005-05-31 17:46:45 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
2007-10-19 04:40:25 +04:00
bool fetch_ldap_pw ( char * * dn , char * * pw )
2005-05-31 17:46:45 +04:00
{
char * key = NULL ;
2005-12-03 09:46:46 +03:00
size_t size = 0 ;
2007-09-07 13:14:44 +04:00
2005-05-31 17:46:45 +04:00
* dn = smb_xstrdup ( lp_ldap_admin_dn ( ) ) ;
2007-09-07 13:14:44 +04:00
2005-05-31 17:46:45 +04:00
if ( asprintf ( & key , " %s/%s " , SECRETS_LDAP_BIND_PW , * dn ) < 0 ) {
SAFE_FREE ( * dn ) ;
DEBUG ( 0 , ( " fetch_ldap_pw: asprintf failed! \n " ) ) ;
}
2007-09-07 13:14:44 +04:00
2006-07-11 22:01:26 +04:00
* pw = ( char * ) secrets_fetch ( key , & size ) ;
2005-05-31 17:46:45 +04:00
SAFE_FREE ( key ) ;
if ( ! size ) {
/* Upgrade 2.2 style entry */
char * p ;
char * old_style_key = SMB_STRDUP ( * dn ) ;
char * data ;
fstring old_style_pw ;
2007-09-07 13:14:44 +04:00
2005-05-31 17:46:45 +04:00
if ( ! old_style_key ) {
DEBUG ( 0 , ( " fetch_ldap_pw: strdup failed! \n " ) ) ;
return False ;
}
for ( p = old_style_key ; * p ; p + + )
if ( * p = = ' , ' ) * p = ' / ' ;
2007-09-07 13:14:44 +04:00
2006-07-11 22:01:26 +04:00
data = ( char * ) secrets_fetch ( old_style_key , & size ) ;
2008-06-07 10:48:13 +04:00
if ( ( data = = NULL ) | | ( size < sizeof ( old_style_pw ) ) ) {
2005-05-31 17:46:45 +04:00
DEBUG ( 0 , ( " fetch_ldap_pw: neither ldap secret retrieved! \n " ) ) ;
SAFE_FREE ( old_style_key ) ;
SAFE_FREE ( * dn ) ;
2008-06-07 10:48:13 +04:00
SAFE_FREE ( data ) ;
2005-05-31 17:46:45 +04:00
return False ;
}
size = MIN ( size , sizeof ( fstring ) - 1 ) ;
strncpy ( old_style_pw , data , size ) ;
old_style_pw [ size ] = 0 ;
SAFE_FREE ( data ) ;
if ( ! secrets_store_ldap_pw ( * dn , old_style_pw ) ) {
DEBUG ( 0 , ( " fetch_ldap_pw: ldap secret could not be upgraded! \n " ) ) ;
SAFE_FREE ( old_style_key ) ;
SAFE_FREE ( * dn ) ;
2007-09-07 13:14:44 +04:00
return False ;
2005-05-31 17:46:45 +04:00
}
if ( ! secrets_delete ( old_style_key ) ) {
DEBUG ( 0 , ( " fetch_ldap_pw: old ldap secret could not be deleted! \n " ) ) ;
}
SAFE_FREE ( old_style_key ) ;
2007-09-07 13:14:44 +04:00
* pw = smb_xstrdup ( old_style_pw ) ;
2005-05-31 17:46:45 +04:00
}
2007-09-07 13:14:44 +04:00
2005-05-31 17:46:45 +04:00
return True ;
}
2002-07-15 14:35:28 +04:00
/**
2002-08-17 21:00:51 +04:00
* Get trusted domains info from secrets . tdb .
2007-09-07 13:14:44 +04:00
* */
2002-07-15 14:35:28 +04:00
2008-03-11 14:30:46 +03:00
struct list_trusted_domains_state {
uint32 num_domains ;
struct trustdom_info * * domains ;
} ;
static int list_trusted_domain ( struct db_record * rec , void * private_data )
2002-07-15 14:35:28 +04:00
{
2008-03-11 14:30:46 +03:00
const size_t prefix_len = strlen ( SECRETS_DOMTRUST_ACCT_PASS ) ;
2008-04-30 01:36:24 +04:00
size_t converted_size , packed_size = 0 ;
2008-03-11 14:30:46 +03:00
struct trusted_dom_pass pass ;
struct trustdom_info * dom_info ;
2006-07-11 22:01:26 +04:00
2008-03-11 14:30:46 +03:00
struct list_trusted_domains_state * state =
( struct list_trusted_domains_state * ) private_data ;
2002-07-15 14:35:28 +04:00
2008-03-11 14:30:46 +03:00
if ( ( rec - > key . dsize < prefix_len )
| | ( strncmp ( ( char * ) rec - > key . dptr , SECRETS_DOMTRUST_ACCT_PASS ,
prefix_len ) ! = 0 ) ) {
return 0 ;
2008-02-09 01:12:53 +03:00
}
2007-09-07 13:14:44 +04:00
2008-03-11 14:30:46 +03:00
packed_size = tdb_trusted_dom_pass_unpack (
rec - > value . dptr , rec - > value . dsize , & pass ) ;
if ( rec - > value . dsize ! = packed_size ) {
DEBUG ( 2 , ( " Secrets record is invalid! \n " ) ) ;
return 0 ;
2002-07-15 14:35:28 +04:00
}
2008-03-11 14:30:46 +03:00
if ( pass . domain_sid . num_auths ! = 4 ) {
DEBUG ( 0 , ( " SID %s is not a domain sid, has %d "
" auths instead of 4 \n " ,
sid_string_dbg ( & pass . domain_sid ) ,
pass . domain_sid . num_auths ) ) ;
return 0 ;
}
2002-07-15 14:35:28 +04:00
2008-03-11 14:30:46 +03:00
if ( ! ( dom_info = TALLOC_P ( state - > domains , struct trustdom_info ) ) ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
return 0 ;
}
2006-07-11 22:01:26 +04:00
2008-04-30 01:36:24 +04:00
if ( ! pull_ucs2_talloc ( dom_info , & dom_info - > name , pass . uni_name ,
& converted_size ) ) {
2008-03-11 14:30:46 +03:00
DEBUG ( 2 , ( " pull_ucs2_talloc failed \n " ) ) ;
TALLOC_FREE ( dom_info ) ;
return 0 ;
2006-07-11 22:01:26 +04:00
}
2008-03-11 14:30:46 +03:00
sid_copy ( & dom_info - > sid , & pass . domain_sid ) ;
2003-07-01 16:40:52 +04:00
2008-03-11 14:30:46 +03:00
ADD_TO_ARRAY ( state - > domains , struct trustdom_info * , dom_info ,
& state - > domains , & state - > num_domains ) ;
2007-09-07 13:14:44 +04:00
2008-03-11 14:30:46 +03:00
if ( state - > domains = = NULL ) {
state - > num_domains = 0 ;
return - 1 ;
}
return 0 ;
}
2002-07-15 14:35:28 +04:00
2008-03-11 14:30:46 +03:00
NTSTATUS secrets_trusted_domains ( TALLOC_CTX * mem_ctx , uint32 * num_domains ,
struct trustdom_info * * * domains )
{
struct list_trusted_domains_state state ;
2006-02-04 01:19:41 +03:00
2008-03-11 14:30:46 +03:00
secrets_init ( ) ;
2006-02-04 01:19:41 +03:00
2008-03-11 14:30:46 +03:00
if ( db_ctx = = NULL ) {
return NT_STATUS_ACCESS_DENIED ;
}
2006-02-04 01:19:41 +03:00
2008-03-11 14:30:46 +03:00
state . num_domains = 0 ;
2006-02-04 01:19:41 +03:00
2008-03-11 14:30:46 +03:00
/*
* Make sure that a talloc context for the trustdom_info structs
* exists
*/
2006-02-04 01:19:41 +03:00
2008-03-11 14:30:46 +03:00
if ( ! ( state . domains = TALLOC_ARRAY (
mem_ctx , struct trustdom_info * , 1 ) ) ) {
return NT_STATUS_NO_MEMORY ;
2002-07-15 14:35:28 +04:00
}
2007-09-07 13:14:44 +04:00
2008-03-20 16:26:46 +03:00
db_ctx - > traverse_read ( db_ctx , list_trusted_domain , ( void * ) & state ) ;
2002-07-15 14:35:28 +04:00
2008-03-11 14:30:46 +03:00
* num_domains = state . num_domains ;
* domains = state . domains ;
2006-02-04 01:19:41 +03:00
return NT_STATUS_OK ;
2001-12-13 21:09:29 +03:00
}
2003-09-07 20:36:13 +04:00
/*******************************************************************************
Store a complete AFS keyfile into secrets . tdb .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
bool secrets_store_afs_keyfile ( const char * cell , const struct afs_keyfile * keyfile )
2003-09-07 20:36:13 +04:00
{
fstring key ;
if ( ( cell = = NULL ) | | ( keyfile = = NULL ) )
return False ;
if ( ntohl ( keyfile - > nkeys ) > SECRETS_AFS_MAXKEYS )
return False ;
slprintf ( key , sizeof ( key ) - 1 , " %s/%s " , SECRETS_AFS_KEYFILE , cell ) ;
return secrets_store ( key , keyfile , sizeof ( struct afs_keyfile ) ) ;
}
/*******************************************************************************
Fetch the current ( highest ) AFS key from secrets . tdb
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
bool secrets_fetch_afs_key ( const char * cell , struct afs_key * result )
2003-09-07 20:36:13 +04:00
{
fstring key ;
struct afs_keyfile * keyfile ;
2005-12-03 09:46:46 +03:00
size_t size = 0 ;
2003-09-07 20:36:13 +04:00
uint32 i ;
slprintf ( key , sizeof ( key ) - 1 , " %s/%s " , SECRETS_AFS_KEYFILE , cell ) ;
keyfile = ( struct afs_keyfile * ) secrets_fetch ( key , & size ) ;
if ( keyfile = = NULL )
return False ;
if ( size ! = sizeof ( struct afs_keyfile ) ) {
SAFE_FREE ( keyfile ) ;
return False ;
}
i = ntohl ( keyfile - > nkeys ) ;
if ( i > SECRETS_AFS_MAXKEYS ) {
SAFE_FREE ( keyfile ) ;
return False ;
}
* result = keyfile - > entry [ i - 1 ] ;
result - > kvno = ntohl ( result - > kvno ) ;
2008-06-07 10:51:35 +04:00
SAFE_FREE ( keyfile ) ;
2003-09-07 20:36:13 +04:00
return True ;
}
2004-01-07 13:11:24 +03:00
/******************************************************************************
When kerberos is not available , choose between anonymous or
2007-09-07 13:14:44 +04:00
authenticated connections .
2004-01-07 13:11:24 +03:00
We need to use an authenticated connection if DCs have the
RestrictAnonymous registry entry set > 0 , or the " Additional
restrictions for anonymous connections " set in the win2k Local
Security Policy .
Caller to free ( ) result in domain , username , password
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void secrets_fetch_ipc_userpass ( char * * username , char * * domain , char * * password )
{
2006-07-11 22:01:26 +04:00
* username = ( char * ) secrets_fetch ( SECRETS_AUTH_USER , NULL ) ;
* domain = ( char * ) secrets_fetch ( SECRETS_AUTH_DOMAIN , NULL ) ;
* password = ( char * ) secrets_fetch ( SECRETS_AUTH_PASSWORD , NULL ) ;
2007-09-07 13:14:44 +04:00
2004-01-07 13:11:24 +03:00
if ( * username & & * * username ) {
if ( ! * domain | | ! * * domain )
* domain = smb_xstrdup ( lp_workgroup ( ) ) ;
2007-09-07 13:14:44 +04:00
2004-01-07 13:11:24 +03:00
if ( ! * password | | ! * * password )
* password = smb_xstrdup ( " " ) ;
2007-09-07 13:14:44 +04:00
DEBUG ( 3 , ( " IPC$ connections done by user %s \\ %s \n " ,
2004-01-07 13:11:24 +03:00
* domain , * username ) ) ;
} else {
DEBUG ( 3 , ( " IPC$ connections done anonymously \n " ) ) ;
* username = smb_xstrdup ( " " ) ;
* domain = smb_xstrdup ( " " ) ;
* password = smb_xstrdup ( " " ) ;
}
}
2005-10-07 05:46:19 +04:00
/******************************************************************************
Open or create the schannel session store tdb .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static TDB_CONTEXT * open_schannel_session_store ( TALLOC_CTX * mem_ctx )
{
TDB_DATA vers ;
uint32 ver ;
TDB_CONTEXT * tdb_sc = NULL ;
char * fname = talloc_asprintf ( mem_ctx , " %s/schannel_store.tdb " , lp_private_dir ( ) ) ;
if ( ! fname ) {
return NULL ;
}
tdb_sc = tdb_open_log ( fname , 0 , TDB_DEFAULT , O_RDWR | O_CREAT , 0600 ) ;
if ( ! tdb_sc ) {
DEBUG ( 0 , ( " open_schannel_session_store: Failed to open %s \n " , fname ) ) ;
2006-02-20 20:59:58 +03:00
TALLOC_FREE ( fname ) ;
2005-10-07 05:46:19 +04:00
return NULL ;
}
vers = tdb_fetch_bystring ( tdb_sc , " SCHANNEL_STORE_VERSION " ) ;
if ( vers . dptr = = NULL ) {
/* First opener, no version. */
SIVAL ( & ver , 0 , 1 ) ;
2007-03-29 13:35:51 +04:00
vers . dptr = ( uint8 * ) & ver ;
2005-10-07 05:46:19 +04:00
vers . dsize = 4 ;
tdb_store_bystring ( tdb_sc , " SCHANNEL_STORE_VERSION " , vers , TDB_REPLACE ) ;
vers . dptr = NULL ;
} else if ( vers . dsize = = 4 ) {
ver = IVAL ( vers . dptr , 0 ) ;
if ( ver ! = 1 ) {
tdb_close ( tdb_sc ) ;
tdb_sc = NULL ;
DEBUG ( 0 , ( " open_schannel_session_store: wrong version number %d in %s \n " ,
( int ) ver , fname ) ) ;
}
} else {
tdb_close ( tdb_sc ) ;
tdb_sc = NULL ;
DEBUG ( 0 , ( " open_schannel_session_store: wrong version number size %d in %s \n " ,
( int ) vers . dsize , fname ) ) ;
}
SAFE_FREE ( vers . dptr ) ;
2006-02-20 20:59:58 +03:00
TALLOC_FREE ( fname ) ;
2005-10-07 05:46:19 +04:00
return tdb_sc ;
}
/******************************************************************************
Store the schannel state after an AUTH2 call .
Note we must be root here .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
bool secrets_store_schannel_session_info ( TALLOC_CTX * mem_ctx ,
2006-02-18 00:32:31 +03:00
const char * remote_machine ,
const struct dcinfo * pdc )
2005-10-07 05:46:19 +04:00
{
TDB_CONTEXT * tdb_sc = NULL ;
TDB_DATA value ;
2007-10-19 04:40:25 +04:00
bool ret ;
2008-03-09 13:26:50 +03:00
char * keystr = talloc_asprintf_strupper_m ( mem_ctx , " %s/%s " ,
SECRETS_SCHANNEL_STATE ,
remote_machine ) ;
2005-10-07 05:46:19 +04:00
if ( ! keystr ) {
return False ;
}
/* Work out how large the record is. */
value . dsize = tdb_pack ( NULL , 0 , " dBBBBBfff " ,
pdc - > sequence ,
8 , pdc - > seed_chal . data ,
8 , pdc - > clnt_chal . data ,
8 , pdc - > srv_chal . data ,
2006-02-17 04:26:21 +03:00
16 , pdc - > sess_key ,
2005-10-07 05:46:19 +04:00
16 , pdc - > mach_pw ,
pdc - > mach_acct ,
pdc - > remote_machine ,
pdc - > domain ) ;
2007-03-29 13:35:51 +04:00
value . dptr = TALLOC_ARRAY ( mem_ctx , uint8 , value . dsize ) ;
2005-10-07 05:46:19 +04:00
if ( ! value . dptr ) {
2006-02-20 20:59:58 +03:00
TALLOC_FREE ( keystr ) ;
2005-10-07 05:46:19 +04:00
return False ;
}
value . dsize = tdb_pack ( value . dptr , value . dsize , " dBBBBBfff " ,
pdc - > sequence ,
8 , pdc - > seed_chal . data ,
8 , pdc - > clnt_chal . data ,
8 , pdc - > srv_chal . data ,
2006-02-17 04:26:21 +03:00
16 , pdc - > sess_key ,
2005-10-07 05:46:19 +04:00
16 , pdc - > mach_pw ,
pdc - > mach_acct ,
pdc - > remote_machine ,
pdc - > domain ) ;
tdb_sc = open_schannel_session_store ( mem_ctx ) ;
if ( ! tdb_sc ) {
2006-02-20 20:59:58 +03:00
TALLOC_FREE ( keystr ) ;
TALLOC_FREE ( value . dptr ) ;
2005-10-07 05:46:19 +04:00
return False ;
}
ret = ( tdb_store_bystring ( tdb_sc , keystr , value , TDB_REPLACE ) = = 0 ? True : False ) ;
DEBUG ( 3 , ( " secrets_store_schannel_session_info: stored schannel info with key %s \n " ,
keystr ) ) ;
tdb_close ( tdb_sc ) ;
2006-02-20 20:59:58 +03:00
TALLOC_FREE ( keystr ) ;
TALLOC_FREE ( value . dptr ) ;
2005-10-07 05:46:19 +04:00
return ret ;
}
/******************************************************************************
Restore the schannel state on a client reconnect .
Note we must be root here .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
bool secrets_restore_schannel_session_info ( TALLOC_CTX * mem_ctx ,
2005-10-07 05:46:19 +04:00
const char * remote_machine ,
2006-02-16 02:15:55 +03:00
struct dcinfo * * ppdc )
2005-10-07 05:46:19 +04:00
{
TDB_CONTEXT * tdb_sc = NULL ;
TDB_DATA value ;
unsigned char * pseed_chal = NULL ;
unsigned char * pclnt_chal = NULL ;
unsigned char * psrv_chal = NULL ;
unsigned char * psess_key = NULL ;
unsigned char * pmach_pw = NULL ;
uint32 l1 , l2 , l3 , l4 , l5 ;
int ret ;
2006-02-16 02:15:55 +03:00
struct dcinfo * pdc = NULL ;
2008-03-09 13:26:50 +03:00
char * keystr = talloc_asprintf_strupper_m ( mem_ctx , " %s/%s " ,
SECRETS_SCHANNEL_STATE ,
remote_machine ) ;
2005-10-07 05:46:19 +04:00
2006-02-16 02:15:55 +03:00
* ppdc = NULL ;
2005-10-07 05:46:19 +04:00
if ( ! keystr ) {
return False ;
}
tdb_sc = open_schannel_session_store ( mem_ctx ) ;
if ( ! tdb_sc ) {
2006-02-20 20:59:58 +03:00
TALLOC_FREE ( keystr ) ;
2005-10-07 05:46:19 +04:00
return False ;
}
value = tdb_fetch_bystring ( tdb_sc , keystr ) ;
if ( ! value . dptr ) {
DEBUG ( 0 , ( " secrets_restore_schannel_session_info: Failed to find entry with key %s \n " ,
keystr ) ) ;
tdb_close ( tdb_sc ) ;
return False ;
}
2006-02-16 02:15:55 +03:00
pdc = TALLOC_ZERO_P ( mem_ctx , struct dcinfo ) ;
2005-10-07 05:46:19 +04:00
/* Retrieve the record. */
ret = tdb_unpack ( value . dptr , value . dsize , " dBBBBBfff " ,
& pdc - > sequence ,
& l1 , & pseed_chal ,
& l2 , & pclnt_chal ,
& l3 , & psrv_chal ,
& l4 , & psess_key ,
& l5 , & pmach_pw ,
& pdc - > mach_acct ,
& pdc - > remote_machine ,
& pdc - > domain ) ;
2006-02-17 04:26:21 +03:00
if ( ret = = - 1 | | l1 ! = 8 | | l2 ! = 8 | | l3 ! = 8 | | l4 ! = 16 | | l5 ! = 16 ) {
2006-02-17 18:51:25 +03:00
/* Bad record - delete it. */
tdb_delete_bystring ( tdb_sc , keystr ) ;
2006-06-13 22:01:58 +04:00
tdb_close ( tdb_sc ) ;
2006-02-20 20:59:58 +03:00
TALLOC_FREE ( keystr ) ;
TALLOC_FREE ( pdc ) ;
2005-10-07 05:46:19 +04:00
SAFE_FREE ( pseed_chal ) ;
SAFE_FREE ( pclnt_chal ) ;
SAFE_FREE ( psrv_chal ) ;
SAFE_FREE ( psess_key ) ;
SAFE_FREE ( pmach_pw ) ;
SAFE_FREE ( value . dptr ) ;
return False ;
}
2006-06-13 22:01:58 +04:00
tdb_close ( tdb_sc ) ;
2005-10-07 05:46:19 +04:00
memcpy ( pdc - > seed_chal . data , pseed_chal , 8 ) ;
memcpy ( pdc - > clnt_chal . data , pclnt_chal , 8 ) ;
memcpy ( pdc - > srv_chal . data , psrv_chal , 8 ) ;
2006-02-17 04:26:21 +03:00
memcpy ( pdc - > sess_key , psess_key , 16 ) ;
2005-10-07 05:46:19 +04:00
memcpy ( pdc - > mach_pw , pmach_pw , 16 ) ;
/* We know these are true so didn't bother to store them. */
pdc - > challenge_sent = True ;
pdc - > authenticated = True ;
2006-02-16 02:15:55 +03:00
DEBUG ( 3 , ( " secrets_restore_schannel_session_info: restored schannel info key %s \n " ,
2005-10-07 05:46:19 +04:00
keystr ) ) ;
SAFE_FREE ( pseed_chal ) ;
SAFE_FREE ( pclnt_chal ) ;
SAFE_FREE ( psrv_chal ) ;
SAFE_FREE ( psess_key ) ;
SAFE_FREE ( pmach_pw ) ;
2006-02-20 20:59:58 +03:00
TALLOC_FREE ( keystr ) ;
2005-10-07 05:46:19 +04:00
SAFE_FREE ( value . dptr ) ;
2006-02-16 02:15:55 +03:00
* ppdc = pdc ;
2005-10-07 05:46:19 +04:00
return True ;
}
2006-12-12 17:52:13 +03:00
2007-10-19 04:40:25 +04:00
bool secrets_store_generic ( const char * owner , const char * key , const char * secret )
2006-12-12 17:52:13 +03:00
{
char * tdbkey = NULL ;
2007-10-19 04:40:25 +04:00
bool ret ;
2007-09-07 13:14:44 +04:00
2006-12-12 17:52:13 +03:00
if ( asprintf ( & tdbkey , " SECRETS/GENERIC/%s/%s " , owner , key ) < 0 ) {
DEBUG ( 0 , ( " asprintf failed! \n " ) ) ;
return False ;
}
2007-09-07 13:14:44 +04:00
2006-12-12 17:52:13 +03:00
ret = secrets_store ( tdbkey , secret , strlen ( secret ) + 1 ) ;
2007-09-07 13:14:44 +04:00
2006-12-12 17:52:13 +03:00
SAFE_FREE ( tdbkey ) ;
return ret ;
}
/*******************************************************************
Find the ldap password .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
char * secrets_fetch_generic ( const char * owner , const char * key )
{
char * secret = NULL ;
char * tdbkey = NULL ;
if ( ( ! owner ) | | ( ! key ) ) {
DEBUG ( 1 , ( " Invalid Paramters " ) ) ;
return NULL ;
}
if ( asprintf ( & tdbkey , " SECRETS/GENERIC/%s/%s " , owner , key ) < 0 ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
return NULL ;
}
2007-09-07 13:14:44 +04:00
2006-12-12 17:52:13 +03:00
secret = ( char * ) secrets_fetch ( tdbkey , NULL ) ;
SAFE_FREE ( tdbkey ) ;
return secret ;
}