2002-11-01 08:06:19 +03:00
/*
Samba Unix / Linux SMB client utility profiles . c
2005-08-26 07:40:24 +04:00
Copyright ( C ) Richard Sharpe , < rsharpe @ richardsharpe . com > 2002
Copyright ( C ) Jelmer Vernooij ( conversion to popt ) 2003
Copyright ( C ) Gerald ( Jerry ) Carter 2005
2002-11-01 08:06:19 +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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2002-11-01 08:06:19 +03: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 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-08-26 07:40:24 +04:00
*/
2002-10-31 20:27:47 +03:00
# include "includes.h"
2005-08-26 07:40:24 +04:00
# include "regfio.h"
/* GLOBAL VARIABLES */
2002-11-01 11:53:28 +03:00
DOM_SID old_sid , new_sid ;
2005-06-25 00:25:18 +04:00
int change = 0 , new_val = 0 ;
2007-10-19 22:38:36 +04:00
int opt_verbose = False ;
2002-11-01 11:53:28 +03:00
2007-02-26 16:07:34 +03:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void verbose_output ( const char * format , . . . ) PRINTF_ATTRIBUTE ( 1 , 2 ) ;
static void verbose_output ( const char * format , . . . )
{
va_list args ;
char * var = NULL ;
if ( ! opt_verbose ) {
return ;
}
va_start ( args , format ) ;
if ( ( vasprintf ( & var , format , args ) ) = = - 1 ) {
va_end ( args ) ;
return ;
}
fprintf ( stdout , var ) ;
va_end ( args ) ;
SAFE_FREE ( var ) ;
}
2002-11-01 08:06:19 +03:00
2005-08-26 07:40:24 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-01 08:06:19 +03:00
2007-10-19 04:40:25 +04:00
static bool swap_sid_in_acl ( SEC_DESC * sd , DOM_SID * s1 , DOM_SID * s2 )
2005-08-26 07:40:24 +04:00
{
2007-02-26 16:07:34 +03:00
SEC_ACL * acl ;
2005-08-26 07:40:24 +04:00
int i ;
2007-10-19 04:40:25 +04:00
bool update = False ;
2002-11-01 08:06:19 +03:00
2007-02-26 16:07:34 +03:00
verbose_output ( " Owner SID: %s \n " , sid_string_static ( sd - > owner_sid ) ) ;
2005-08-26 20:06:17 +04:00
if ( sid_equal ( sd - > owner_sid , s1 ) ) {
2005-08-26 07:40:24 +04:00
sid_copy ( sd - > owner_sid , s2 ) ;
2005-08-26 20:06:17 +04:00
update = True ;
2007-02-26 16:07:34 +03:00
verbose_output ( " New Owner SID: %s \n " ,
sid_string_static ( sd - > owner_sid ) ) ;
2005-08-26 20:06:17 +04:00
}
2002-11-01 08:06:19 +03:00
2007-02-26 16:07:34 +03:00
verbose_output ( " Group SID: %s \n " , sid_string_static ( sd - > group_sid ) ) ;
2006-09-21 02:23:12 +04:00
if ( sid_equal ( sd - > group_sid , s1 ) ) {
sid_copy ( sd - > group_sid , s2 ) ;
2005-08-26 20:06:17 +04:00
update = True ;
2007-02-26 16:07:34 +03:00
verbose_output ( " New Group SID: %s \n " ,
sid_string_static ( sd - > group_sid ) ) ;
2005-08-26 20:06:17 +04:00
}
2002-11-01 08:06:19 +03:00
2007-02-26 16:07:34 +03:00
acl = sd - > dacl ;
verbose_output ( " DACL: %d entries: \n " , acl - > num_aces ) ;
2005-08-26 07:40:24 +04:00
for ( i = 0 ; i < acl - > num_aces ; i + + ) {
2007-02-26 16:07:34 +03:00
verbose_output ( " Trustee SID: %s \n " ,
sid_string_static ( & acl - > aces [ i ] . trustee ) ) ;
2006-09-21 02:23:12 +04:00
if ( sid_equal ( & acl - > aces [ i ] . trustee , s1 ) ) {
sid_copy ( & acl - > aces [ i ] . trustee , s2 ) ;
2005-08-26 20:06:17 +04:00
update = True ;
2007-02-26 16:07:34 +03:00
verbose_output ( " New Trustee SID: %s \n " ,
sid_string_static ( & acl - > aces [ i ] . trustee ) ) ;
2005-08-26 20:06:17 +04:00
}
2005-08-26 07:40:24 +04:00
}
2005-08-26 20:06:17 +04:00
2007-02-26 16:07:34 +03:00
#if 0
acl = sd - > sacl ;
verbose_output ( " SACL: %d entries: \n " , acl - > num_aces ) ;
for ( i = 0 ; i < acl - > num_aces ; i + + ) {
verbose_output ( " Trustee SID: %s \n " ,
sid_string_static ( & acl - > aces [ i ] . trustee ) ) ;
if ( sid_equal ( & acl - > aces [ i ] . trustee , s1 ) ) {
sid_copy ( & acl - > aces [ i ] . trustee , s2 ) ;
update = True ;
verbose_output ( " New Trustee SID: %s \n " ,
sid_string_static ( & acl - > aces [ i ] . trustee ) ) ;
}
}
# endif
2005-08-26 20:06:17 +04:00
return update ;
2002-11-01 08:06:19 +03:00
}
2005-08-26 07:40:24 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static bool copy_registry_tree ( REGF_FILE * infile , REGF_NK_REC * nk ,
2005-08-26 07:40:24 +04:00
REGF_NK_REC * parent , REGF_FILE * outfile ,
const char * parentpath )
2002-11-01 10:43:54 +03:00
{
2005-08-26 07:40:24 +04:00
REGF_NK_REC * key , * subkey ;
SEC_DESC * new_sd ;
2005-08-29 18:55:40 +04:00
REGVAL_CTR * values ;
REGSUBKEY_CTR * subkeys ;
2005-08-26 07:40:24 +04:00
int i ;
pstring path ;
/* swap out the SIDs in the security descriptor */
if ( ! ( new_sd = dup_sec_desc ( outfile - > mem_ctx , nk - > sec_desc - > sec_desc ) ) ) {
fprintf ( stderr , " Failed to copy security descriptor! \n " ) ;
return False ;
}
2002-11-01 10:43:54 +03:00
2007-02-26 16:07:34 +03:00
verbose_output ( " ACL for %s%s%s \n " , parentpath , parent ? " \\ " : " " , nk - > keyname ) ;
swap_sid_in_acl ( new_sd , & old_sid , & new_sid ) ;
2003-07-02 05:09:17 +04:00
2005-08-29 18:55:40 +04:00
if ( ! ( subkeys = TALLOC_ZERO_P ( NULL , REGSUBKEY_CTR ) ) ) {
DEBUG ( 0 , ( " copy_registry_tree: talloc() failure! \n " ) ) ;
return False ;
}
if ( ! ( values = TALLOC_ZERO_P ( subkeys , REGVAL_CTR ) ) ) {
2007-10-15 07:24:44 +04:00
TALLOC_FREE ( subkeys ) ;
2005-08-29 18:55:40 +04:00
DEBUG ( 0 , ( " copy_registry_tree: talloc() failure! \n " ) ) ;
return False ;
}
2002-11-01 08:06:19 +03:00
2005-08-26 07:40:24 +04:00
/* copy values into the REGVAL_CTR */
2003-07-02 05:09:17 +04:00
2005-08-26 07:40:24 +04:00
for ( i = 0 ; i < nk - > num_values ; i + + ) {
2005-08-29 18:55:40 +04:00
regval_ctr_addvalue ( values , nk - > values [ i ] . valuename , nk - > values [ i ] . type ,
2005-10-18 07:24:00 +04:00
( const char * ) nk - > values [ i ] . data , ( nk - > values [ i ] . data_size & ~ VK_DATA_IN_OFFSET ) ) ;
2005-08-26 07:40:24 +04:00
}
2002-10-31 20:27:47 +03:00
2005-08-26 07:40:24 +04:00
/* copy subkeys into the REGSUBKEY_CTR */
2002-10-31 20:27:47 +03:00
2005-08-26 07:40:24 +04:00
while ( ( subkey = regfio_fetch_subkey ( infile , nk ) ) ) {
2005-08-29 18:55:40 +04:00
regsubkey_ctr_addkey ( subkeys , subkey - > keyname ) ;
2005-08-26 07:40:24 +04:00
}
2002-10-31 20:27:47 +03:00
2005-08-29 18:55:40 +04:00
key = regfio_write_key ( outfile , nk - > keyname , values , subkeys , new_sd , parent ) ;
2002-10-31 20:27:47 +03:00
2005-08-26 07:40:24 +04:00
/* write each one of the subkeys out */
2002-11-01 11:53:28 +03:00
2005-08-26 07:40:24 +04:00
pstr_sprintf ( path , " %s%s%s " , parentpath , parent ? " \\ " : " " , nk - > keyname ) ;
nk - > subkey_index = 0 ;
while ( ( subkey = regfio_fetch_subkey ( infile , nk ) ) ) {
2007-10-15 07:24:44 +04:00
if ( ! copy_registry_tree ( infile , subkey , key , outfile , path ) ) {
TALLOC_FREE ( subkeys ) ;
2005-08-26 07:40:24 +04:00
return False ;
2007-10-15 07:24:44 +04:00
}
2005-08-26 07:40:24 +04:00
}
2002-11-01 11:53:28 +03:00
2005-08-29 18:55:40 +04:00
/* values is a talloc()'d child of subkeys here so just throw it all away */
TALLOC_FREE ( subkeys ) ;
2002-11-01 11:53:28 +03:00
2007-02-26 16:07:34 +03:00
verbose_output ( " [%s] \n " , path ) ;
2002-11-01 11:53:28 +03:00
2005-08-26 07:40:24 +04:00
return True ;
2002-11-01 11:53:28 +03:00
}
2005-08-26 07:40:24 +04:00
/*********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int main ( int argc , char * argv [ ] )
2002-10-31 20:27:47 +03:00
{
2005-08-26 07:40:24 +04:00
int opt ;
REGF_FILE * infile , * outfile ;
REGF_NK_REC * nk ;
pstring orig_filename , new_filename ;
struct poptOption long_options [ ] = {
POPT_AUTOHELP
{ " change-sid " , ' c ' , POPT_ARG_STRING , NULL , ' c ' , " Provides SID to change " } ,
{ " new-sid " , ' n ' , POPT_ARG_STRING , NULL , ' n ' , " Provides SID to change to " } ,
2007-02-26 16:07:34 +03:00
{ " verbose " , ' v ' , POPT_ARG_NONE , & opt_verbose , ' v ' , " Verbose output " } ,
2005-08-26 20:06:17 +04:00
POPT_COMMON_SAMBA
POPT_COMMON_VERSION
POPT_TABLEEND
2005-08-26 07:40:24 +04:00
} ;
2005-08-26 20:06:17 +04:00
poptContext pc ;
2005-08-26 07:40:24 +04:00
2006-02-13 07:58:13 +03:00
load_case_tables ( ) ;
2005-08-26 20:06:17 +04:00
/* setup logging options */
2005-08-26 07:40:24 +04:00
2005-08-26 20:06:17 +04:00
setup_logging ( " profiles " , True ) ;
dbf = x_stderr ;
x_setbuf ( x_stderr , NULL ) ;
2005-08-26 07:40:24 +04:00
pc = poptGetContext ( " profiles " , argc , ( const char * * ) argv , long_options ,
POPT_CONTEXT_KEEP_FIRST ) ;
poptSetOtherOptionHelp ( pc , " <profilefile> " ) ;
/* Now, process the arguments */
while ( ( opt = poptGetNextOpt ( pc ) ) ! = - 1 ) {
switch ( opt ) {
case ' c ' :
change = 1 ;
if ( ! string_to_sid ( & old_sid , poptGetOptArg ( pc ) ) ) {
fprintf ( stderr , " Argument to -c should be a SID in form of S-1-5-... \n " ) ;
poptPrintUsage ( pc , stderr , 0 ) ;
exit ( 254 ) ;
}
break ;
case ' n ' :
new_val = 1 ;
if ( ! string_to_sid ( & new_sid , poptGetOptArg ( pc ) ) ) {
fprintf ( stderr , " Argument to -n should be a SID in form of S-1-5-... \n " ) ;
poptPrintUsage ( pc , stderr , 0 ) ;
exit ( 253 ) ;
}
break ;
2003-04-14 07:59:04 +04:00
}
2005-08-26 07:40:24 +04:00
}
2003-04-14 07:59:04 +04:00
2005-08-26 20:06:17 +04:00
poptGetArg ( pc ) ;
2003-04-14 07:59:04 +04:00
2005-08-26 07:40:24 +04:00
if ( ! poptPeekArg ( pc ) ) {
poptPrintUsage ( pc , stderr , 0 ) ;
exit ( 1 ) ;
2003-04-14 07:59:04 +04:00
}
2005-08-26 07:40:24 +04:00
2005-08-30 10:41:32 +04:00
if ( ( ! change & & new_val ) | | ( change & & ! new_val ) ) {
2005-08-26 07:40:24 +04:00
fprintf ( stderr , " You must specify both -c and -n if one or the other is set! \n " ) ;
poptPrintUsage ( pc , stderr , 0 ) ;
exit ( 252 ) ;
}
pstrcpy ( orig_filename , poptPeekArg ( pc ) ) ;
pstr_sprintf ( new_filename , " %s.new " , orig_filename ) ;
if ( ! ( infile = regfio_open ( orig_filename , O_RDONLY , 0 ) ) ) {
fprintf ( stderr , " Failed to open %s! \n " , orig_filename ) ;
fprintf ( stderr , " Error was (%s) \n " , strerror ( errno ) ) ;
exit ( 1 ) ;
}
if ( ! ( outfile = regfio_open ( new_filename , ( O_RDWR | O_CREAT | O_TRUNC ) , ( S_IREAD | S_IWRITE ) ) ) ) {
fprintf ( stderr , " Failed to open new file %s! \n " , new_filename ) ;
fprintf ( stderr , " Error was (%s) \n " , strerror ( errno ) ) ;
exit ( 1 ) ;
}
/* actually do the update now */
2006-06-20 13:16:53 +04:00
if ( ( nk = regfio_rootkey ( infile ) ) = = NULL ) {
fprintf ( stderr , " Could not get rootkey \n " ) ;
exit ( 3 ) ;
}
2005-08-26 07:40:24 +04:00
if ( ! copy_registry_tree ( infile , nk , NULL , outfile , " " ) ) {
fprintf ( stderr , " Failed to write updated registry file! \n " ) ;
exit ( 2 ) ;
}
/* cleanup */
regfio_close ( infile ) ;
regfio_close ( outfile ) ;
poptFreeContext ( pc ) ;
2005-08-30 10:41:32 +04:00
return ( 0 ) ;
2002-11-01 11:53:28 +03:00
}