2000-05-08 22:14:25 +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
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
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
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"
static TDB_CONTEXT * tdb ;
/* open up the secrets database */
BOOL secrets_init ( void )
{
pstring fname ;
2001-11-17 06:19:17 +03:00
if ( tdb )
return True ;
2000-05-08 22:14:25 +04:00
2000-11-21 08:55:16 +03:00
pstrcpy ( fname , lp_private_dir ( ) ) ;
2000-05-08 22:14:25 +04:00
pstrcat ( fname , " /secrets.tdb " ) ;
2001-09-07 02:08:19 +04:00
tdb = tdb_open_log ( fname , 0 , TDB_DEFAULT , O_RDWR | O_CREAT , 0600 ) ;
2000-05-08 22:14:25 +04:00
if ( ! tdb ) {
DEBUG ( 0 , ( " Failed to open %s \n " , fname ) ) ;
return False ;
}
return True ;
}
/* 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
*/
void * secrets_fetch ( char * key , size_t * size )
{
TDB_DATA kbuf , dbuf ;
2001-12-05 12:45:00 +03:00
secrets_init ( ) ;
2001-11-17 06:19:17 +03:00
if ( ! tdb )
2001-11-24 17:16:41 +03:00
return NULL ;
2000-05-08 22:14:25 +04:00
kbuf . dptr = key ;
kbuf . dsize = strlen ( key ) ;
dbuf = tdb_fetch ( tdb , kbuf ) ;
2001-11-17 06:19:17 +03:00
if ( size )
* size = dbuf . dsize ;
2000-05-08 22:14:25 +04:00
return dbuf . dptr ;
}
/* store a secrets entry
*/
BOOL secrets_store ( char * key , void * data , size_t size )
{
TDB_DATA kbuf , dbuf ;
2001-12-05 12:45:00 +03:00
secrets_init ( ) ;
2001-11-17 06:19:17 +03:00
if ( ! tdb )
return False ;
2000-05-08 22:14:25 +04:00
kbuf . dptr = key ;
kbuf . dsize = strlen ( key ) ;
dbuf . dptr = data ;
dbuf . dsize = size ;
return tdb_store ( tdb , kbuf , dbuf , TDB_REPLACE ) = = 0 ;
}
/* delete a secets database entry
*/
BOOL secrets_delete ( char * key )
{
TDB_DATA kbuf ;
2001-12-05 12:45:00 +03:00
secrets_init ( ) ;
2001-11-17 06:19:17 +03:00
if ( ! tdb )
return False ;
2000-05-08 22:14:25 +04:00
kbuf . dptr = key ;
kbuf . dsize = strlen ( key ) ;
return tdb_delete ( tdb , kbuf ) = = 0 ;
}
2000-05-29 05:23:48 +04:00
BOOL secrets_store_domain_sid ( char * domain , DOM_SID * sid )
{
fstring key ;
2001-04-09 00:22:39 +04:00
slprintf ( key , sizeof ( key ) - 1 , " %s/%s " , SECRETS_DOMAIN_SID , domain ) ;
2000-05-29 05:23:48 +04:00
return secrets_store ( key , sid , sizeof ( DOM_SID ) ) ;
}
BOOL secrets_fetch_domain_sid ( char * domain , DOM_SID * sid )
{
DOM_SID * dyn_sid ;
fstring key ;
2000-07-10 10:41:04 +04:00
size_t size ;
2000-05-29 05:23:48 +04:00
2001-04-09 00:22:39 +04:00
slprintf ( key , sizeof ( key ) - 1 , " %s/%s " , SECRETS_DOMAIN_SID , domain ) ;
2000-05-29 05:23:48 +04:00
dyn_sid = ( DOM_SID * ) secrets_fetch ( key , & size ) ;
if ( dyn_sid = = NULL )
return False ;
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 ;
}
2000-06-03 10:16:11 +04:00
/************************************************************************
form a key for fetching a domain trust password
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-11-28 02:59:42 +03:00
char * trust_keystr ( char * domain )
2000-06-03 10:16:11 +04:00
{
static fstring keystr ;
2001-02-14 08:34:50 +03:00
2001-04-09 00:22:39 +04:00
slprintf ( keystr , sizeof ( keystr ) - 1 , " %s/%s " ,
2001-07-04 11:15:53 +04:00
SECRETS_MACHINE_ACCT_PASS , domain ) ;
2001-02-14 08:34:50 +03:00
2000-06-03 10:16:11 +04:00
return keystr ;
}
/************************************************************************
Routine to get the trust account password for a domain .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL secrets_fetch_trust_account_password ( char * domain , uint8 ret_pwd [ 16 ] ,
time_t * pass_last_set_time )
{
struct machine_acct_pass * pass ;
2001-11-24 17:16:41 +03:00
char * plaintext ;
2000-06-03 10:16:11 +04:00
size_t size ;
2001-11-24 17:16:41 +03:00
plaintext = secrets_fetch_machine_password ( ) ;
if ( plaintext ) {
/* we have an ADS password - use that */
DEBUG ( 4 , ( " Using ADS machine password \n " ) ) ;
E_md4hash ( ( uchar * ) plaintext , ret_pwd ) ;
SAFE_FREE ( plaintext ) ;
return True ;
}
2001-12-05 13:52:13 +03:00
if ( ! ( pass = secrets_fetch ( trust_keystr ( domain ) , & size ) ) ) {
DEBUG ( 5 , ( " secrets_fetch failed! \n " ) ) ;
2000-11-28 02:59:42 +03:00
return False ;
2001-12-05 13:52:13 +03:00
}
if ( size ! = sizeof ( * pass ) ) {
DEBUG ( 0 , ( " secrets were of incorrect size! \n " ) ) ;
return False ;
}
2000-06-03 10:16:11 +04:00
if ( pass_last_set_time ) * pass_last_set_time = pass - > mod_time ;
memcpy ( ret_pwd , pass - > hash , 16 ) ;
2001-09-17 09:04:17 +04:00
SAFE_FREE ( pass ) ;
2000-06-03 10:16:11 +04:00
return True ;
}
/************************************************************************
Routine to set the trust account password for a domain .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL secrets_store_trust_account_password ( char * domain , uint8 new_pwd [ 16 ] )
{
struct machine_acct_pass pass ;
pass . mod_time = time ( NULL ) ;
memcpy ( pass . hash , new_pwd , 16 ) ;
return secrets_store ( trust_keystr ( domain ) , ( void * ) & pass , sizeof ( pass ) ) ;
}
2000-11-28 02:59:42 +03:00
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL secrets_store_machine_password ( char * pass )
{
2002-02-22 06:18:37 +03:00
char * key ;
BOOL ret ;
asprintf ( & key , " %s/%s " , SECRETS_MACHINE_PASSWORD , lp_workgroup ( ) ) ;
strupper ( key ) ;
ret = secrets_store ( key , pass , strlen ( pass ) + 1 ) ;
free ( key ) ;
return ret ;
2001-11-24 17:16:41 +03:00
}
/************************************************************************
Routine to fetch the plaintext machine account password for a realm
the password is assumed to be a null terminated ascii string
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
char * secrets_fetch_machine_password ( void )
{
2002-02-22 06:18:37 +03:00
char * key ;
char * ret ;
asprintf ( & key , " %s/%s " , SECRETS_MACHINE_PASSWORD , lp_workgroup ( ) ) ;
strupper ( key ) ;
ret = ( char * ) secrets_fetch ( key , NULL ) ;
free ( key ) ;
return ret ;
2001-11-24 17:16:41 +03:00
}
2000-11-28 02:59:42 +03:00
/************************************************************************
Routine to delete the trust account password file for a domain .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL trust_password_delete ( char * domain )
{
return secrets_delete ( trust_keystr ( domain ) ) ;
}
2001-06-07 02:04:26 +04:00
/*******************************************************************
Reset the ' done ' variables so after a client process is created
from a fork call these calls will be re - done . This should be
expanded if more variables need reseting .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void reset_globals_after_fork ( void )
{
unsigned char dummy ;
2001-12-05 12:45:00 +03:00
secrets_init ( ) ;
2001-06-07 02:04:26 +04:00
/*
* Increment the global seed value to ensure every smbd starts
* with a new random seed .
*/
if ( tdb ) {
uint32 initial_val = sys_getpid ( ) ;
2002-01-09 05:35:08 +03:00
tdb_change_int32_atomic ( tdb , " INFO/random_seed " , ( int * ) & initial_val , 1 ) ;
2001-06-07 02:04:26 +04:00
set_rand_reseed_data ( ( unsigned char * ) & initial_val , sizeof ( initial_val ) ) ;
}
/*
* Re - seed the random crypto generator , so all smbd ' s
* started from the same parent won ' t generate the same
* sequence .
*/
generate_random_buffer ( & dummy , 1 , True ) ;
}
2001-12-13 21:09:29 +03:00
BOOL secrets_store_ldap_pw ( char * dn , char * pw )
{
fstring key ;
char * p ;
pstrcpy ( key , dn ) ;
for ( p = key ; * p ; p + + )
if ( * p = = ' , ' ) * p = ' / ' ;
return secrets_store ( key , pw , strlen ( pw ) ) ;
}
BOOL fetch_ldap_pw ( char * dn , char * pw , int len )
{
fstring key ;
char * p ;
void * data = NULL ;
size_t size ;
pstrcpy ( key , dn ) ;
for ( p = key ; * p ; p + + )
if ( * p = = ' , ' ) * p = ' / ' ;
data = secrets_fetch ( key , & size ) ;
if ( ! size ) {
DEBUG ( 0 , ( " fetch_ldap_pw: no ldap secret retrieved! \n " ) ) ;
return False ;
}
if ( size > len - 1 )
{
DEBUG ( 0 , ( " fetch_ldap_pw: ldap secret is too long (%d > %d)! \n " , size , len - 1 ) ) ;
return False ;
}
memcpy ( pw , data , size ) ;
pw [ size ] = ' \0 ' ;
return True ;
}