2000-11-14 02:03:34 +03:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2000-11-14 02:03:34 +03:00
Password and authentication handling
2002-03-12 05:26:33 +03:00
Copyright ( C ) Jeremy Allison 1996 - 2002
Copyright ( C ) Andrew Tridgell 2002
2000-11-14 02:03:34 +03:00
Copyright ( C ) Gerald ( Jerry ) Carter 2000
2002-07-15 14:35:28 +04:00
Copyright ( C ) Stefan ( metze ) Metzmacher 2002
2000-11-14 02:03:34 +03:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2002-07-15 14:35:28 +04:00
/* NOTE! the global_sam_sid is the SID of our local SAM. This is only
equal to the domain SID when we are a DC , otherwise its our
workstation SID */
static DOM_SID * global_sam_sid = NULL ;
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_PASSDB
2002-03-10 04:44:21 +03:00
2000-11-14 02:03:34 +03:00
/****************************************************************************
2002-03-10 04:44:21 +03:00
Read a SID from a file . This is for compatibility with the old MACHINE . SID
style of SID storage
2000-11-14 02:03:34 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-10 04:44:21 +03:00
static BOOL read_sid_from_file ( const char * fname , DOM_SID * sid )
2000-11-14 02:03:34 +03:00
{
2002-03-10 04:44:21 +03:00
char * * lines ;
int numlines ;
BOOL ret ;
2000-11-14 02:03:34 +03:00
2002-03-10 04:44:21 +03:00
lines = file_lines_load ( fname , & numlines ) ;
if ( ! lines | | numlines < 1 ) {
if ( lines ) file_lines_free ( lines ) ;
return False ;
}
ret = string_to_sid ( sid , lines [ 0 ] ) ;
file_lines_free ( lines ) ;
return ret ;
}
2000-11-14 02:03:34 +03:00
2002-03-10 04:44:21 +03:00
/*
generate a random sid - used to build our own sid if we don ' t have one
*/
static void generate_random_sid ( DOM_SID * sid )
{
int i ;
uchar raw_sid_data [ 12 ] ;
memset ( ( char * ) sid , ' \0 ' , sizeof ( * sid ) ) ;
sid - > sid_rev_num = 1 ;
sid - > id_auth [ 5 ] = 5 ;
sid - > num_auths = 0 ;
sid - > sub_auths [ sid - > num_auths + + ] = 21 ;
2004-07-14 08:36:01 +04:00
generate_random_buffer ( raw_sid_data , 12 ) ;
2002-03-10 04:44:21 +03:00
for ( i = 0 ; i < 3 ; i + + )
sid - > sub_auths [ sid - > num_auths + + ] = IVAL ( raw_sid_data , i * 4 ) ;
2000-11-14 02:03:34 +03:00
}
/****************************************************************************
2002-03-10 04:44:21 +03:00
Generate the global machine sid .
2000-11-14 02:03:34 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-03-12 05:26:33 +03:00
2004-02-26 01:01:02 +03:00
static DOM_SID * pdb_generate_sam_sid ( void )
2000-11-14 02:03:34 +03:00
{
2003-04-21 18:09:03 +04:00
DOM_SID domain_sid ;
2002-03-10 04:44:21 +03:00
char * fname = NULL ;
2002-03-12 05:26:33 +03:00
BOOL is_dc = False ;
2004-02-26 01:01:02 +03:00
DOM_SID * sam_sid ;
2004-12-07 21:25:53 +03:00
if ( ! ( sam_sid = SMB_MALLOC_P ( DOM_SID ) ) )
2004-02-26 01:01:02 +03:00
return NULL ;
2002-07-15 14:35:28 +04:00
2000-11-14 02:03:34 +03:00
generate_wellknown_sids ( ) ;
2002-03-10 04:44:21 +03:00
switch ( lp_server_role ( ) ) {
case ROLE_DOMAIN_PDC :
case ROLE_DOMAIN_BDC :
2002-03-12 05:26:33 +03:00
is_dc = True ;
2002-03-10 04:44:21 +03:00
break ;
default :
2002-03-12 05:26:33 +03:00
is_dc = False ;
2002-03-10 04:44:21 +03:00
break ;
2000-11-14 02:03:34 +03:00
}
2003-04-21 18:09:03 +04:00
if ( is_dc ) {
if ( secrets_fetch_domain_sid ( lp_workgroup ( ) , & domain_sid ) ) {
2004-02-26 01:01:02 +03:00
sid_copy ( sam_sid , & domain_sid ) ;
return sam_sid ;
2003-04-21 18:09:03 +04:00
}
}
2004-02-26 01:01:02 +03:00
if ( secrets_fetch_domain_sid ( global_myname ( ) , sam_sid ) ) {
2002-03-12 05:26:33 +03:00
/* We got our sid. If not a pdc/bdc, we're done. */
if ( ! is_dc )
2004-02-26 01:01:02 +03:00
return sam_sid ;
2002-03-12 05:26:33 +03:00
2002-09-25 19:19:00 +04:00
if ( ! secrets_fetch_domain_sid ( lp_workgroup ( ) , & domain_sid ) ) {
2002-03-12 05:26:33 +03:00
/* No domain sid and we're a pdc/bdc. Store it */
2004-02-26 01:01:02 +03:00
if ( ! secrets_store_domain_sid ( lp_workgroup ( ) , sam_sid ) ) {
2002-03-12 05:26:33 +03:00
DEBUG ( 0 , ( " pdb_generate_sam_sid: Can't store domain SID as a pdc/bdc. \n " ) ) ;
2004-02-26 01:01:02 +03:00
SAFE_FREE ( sam_sid ) ;
return NULL ;
2002-03-12 05:26:33 +03:00
}
2004-02-26 01:01:02 +03:00
return sam_sid ;
2002-03-12 05:26:33 +03:00
}
2004-02-26 01:01:02 +03:00
if ( ! sid_equal ( & domain_sid , sam_sid ) ) {
2002-03-12 05:26:33 +03:00
2003-04-21 18:09:03 +04:00
/* Domain name sid doesn't match global sam sid. Re-store domain sid as 'local' sid. */
2002-03-12 05:26:33 +03:00
DEBUG ( 0 , ( " pdb_generate_sam_sid: Mismatched SIDs as a pdc/bdc. \n " ) ) ;
2003-04-21 18:09:03 +04:00
if ( ! secrets_store_domain_sid ( global_myname ( ) , & domain_sid ) ) {
DEBUG ( 0 , ( " pdb_generate_sam_sid: Can't re-store domain SID for local sid as PDC/BDC. \n " ) ) ;
2004-02-26 01:01:02 +03:00
SAFE_FREE ( sam_sid ) ;
return NULL ;
2002-03-12 05:26:33 +03:00
}
2004-02-26 01:01:02 +03:00
return sam_sid ;
2002-03-12 05:26:33 +03:00
}
2004-02-26 01:01:02 +03:00
return sam_sid ;
2002-03-12 05:26:33 +03:00
2002-03-10 04:44:21 +03:00
}
2000-11-14 02:03:34 +03:00
2002-03-10 04:44:21 +03:00
/* check for an old MACHINE.SID file for backwards compatibility */
asprintf ( & fname , " %s/MACHINE.SID " , lp_private_dir ( ) ) ;
2002-03-12 05:26:33 +03:00
2004-02-26 01:01:02 +03:00
if ( read_sid_from_file ( fname , sam_sid ) ) {
2002-03-10 04:44:21 +03:00
/* remember it for future reference and unlink the old MACHINE.SID */
2004-02-26 01:01:02 +03:00
if ( ! secrets_store_domain_sid ( global_myname ( ) , sam_sid ) ) {
2002-03-12 05:26:33 +03:00
DEBUG ( 0 , ( " pdb_generate_sam_sid: Failed to store SID from file. \n " ) ) ;
SAFE_FREE ( fname ) ;
2004-02-26 01:01:02 +03:00
SAFE_FREE ( sam_sid ) ;
return NULL ;
2002-03-12 05:26:33 +03:00
}
unlink ( fname ) ;
if ( is_dc ) {
2004-02-26 01:01:02 +03:00
if ( ! secrets_store_domain_sid ( lp_workgroup ( ) , sam_sid ) ) {
2002-03-12 05:26:33 +03:00
DEBUG ( 0 , ( " pdb_generate_sam_sid: Failed to store domain SID from file. \n " ) ) ;
SAFE_FREE ( fname ) ;
2004-02-26 01:01:02 +03:00
SAFE_FREE ( sam_sid ) ;
return NULL ;
2002-03-12 05:26:33 +03:00
}
2000-11-14 02:03:34 +03:00
}
2002-04-02 11:45:19 +04:00
2002-07-15 14:35:28 +04:00
/* Stored the old sid from MACHINE.SID successfully.*/
2002-04-02 11:45:19 +04:00
SAFE_FREE ( fname ) ;
2004-02-26 01:01:02 +03:00
return sam_sid ;
2000-11-14 02:03:34 +03:00
}
2002-03-12 05:26:33 +03:00
SAFE_FREE ( fname ) ;
2002-03-10 04:44:21 +03:00
/* we don't have the SID in secrets.tdb, we will need to
generate one and save it */
2004-02-26 01:01:02 +03:00
generate_random_sid ( sam_sid ) ;
2000-11-14 02:03:34 +03:00
2004-02-26 01:01:02 +03:00
if ( ! secrets_store_domain_sid ( global_myname ( ) , sam_sid ) ) {
2002-03-12 05:26:33 +03:00
DEBUG ( 0 , ( " pdb_generate_sam_sid: Failed to store generated machine SID. \n " ) ) ;
2004-02-26 01:01:02 +03:00
SAFE_FREE ( sam_sid ) ;
return NULL ;
2002-03-12 05:26:33 +03:00
}
if ( is_dc ) {
2004-02-26 01:01:02 +03:00
if ( ! secrets_store_domain_sid ( lp_workgroup ( ) , sam_sid ) ) {
2002-03-12 05:26:33 +03:00
DEBUG ( 0 , ( " pdb_generate_sam_sid: Failed to store generated domain SID. \n " ) ) ;
2004-02-26 01:01:02 +03:00
SAFE_FREE ( sam_sid ) ;
return NULL ;
2002-03-12 05:26:33 +03:00
}
}
2004-02-26 01:01:02 +03:00
return sam_sid ;
2000-11-14 02:03:34 +03:00
}
2002-07-15 14:35:28 +04:00
/* return our global_sam_sid */
DOM_SID * get_global_sam_sid ( void )
{
if ( global_sam_sid ! = NULL )
return global_sam_sid ;
/* memory for global_sam_sid is allocated in
pdb_generate_sam_sid ( ) as needed */
2004-02-26 01:01:02 +03:00
if ( ! ( global_sam_sid = pdb_generate_sam_sid ( ) ) ) {
2003-06-18 12:42:04 +04:00
smb_panic ( " Could not generate a machine SID \n " ) ;
}
2004-02-26 01:01:02 +03:00
2002-07-15 14:35:28 +04:00
return global_sam_sid ;
}
2004-02-08 14:05:34 +03:00
/**
* Force get_global_sam_sid to requery the backends
*/
2004-02-09 17:43:18 +03:00
void reset_global_sam_sid ( void )
2004-02-08 14:05:34 +03:00
{
SAFE_FREE ( global_sam_sid ) ;
}