2010-05-20 14:02:55 +04:00
/*
Samba Unix / Linux SMB client utility profiles . c
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 .
2010-05-20 14:02:55 +04:00
2002-11-01 08:06:19 +03: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 .
2010-05-20 14:02:55 +04:00
2002-11-01 08:06:19 +03:00
You should have received a copy of the GNU General Public License
2010-05-20 14:02:55 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-08-26 07:40:24 +04:00
*/
2010-05-20 14:02:55 +04:00
2002-10-31 20:27:47 +03:00
# include "includes.h"
2011-02-26 01:20:06 +03:00
# include "system/filesys.h"
2010-08-05 12:49:53 +04:00
# include "popt_common.h"
2010-05-25 03:00:37 +04:00
# include "registry/reg_objects.h"
2010-09-21 11:08:33 +04:00
# include "registry/regfio.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2005-08-26 07:40:24 +04:00
/* GLOBAL VARIABLES */
2010-05-21 05:25:01 +04:00
struct 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 ;
}
2009-01-01 05:06:57 +03:00
fprintf ( stdout , " %s " , var ) ;
2007-02-26 16:07:34 +03:00
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
2010-05-21 05:25:01 +04:00
static bool swap_sid_in_acl ( struct security_descriptor * sd , struct dom_sid * s1 , struct dom_sid * s2 )
2005-08-26 07:40:24 +04:00
{
2010-05-18 05:30:40 +04:00
struct security_acl * theacl ;
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-12-15 23:53:26 +03:00
verbose_output ( " Owner SID: %s \n " , sid_string_tos ( sd - > owner_sid ) ) ;
2010-08-26 17:48:50 +04:00
if ( dom_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 ;
2010-05-20 14:02:55 +04:00
verbose_output ( " New Owner SID: %s \n " ,
2007-12-15 23:53:26 +03:00
sid_string_tos ( sd - > owner_sid ) ) ;
2007-02-26 16:07:34 +03:00
2005-08-26 20:06:17 +04:00
}
2002-11-01 08:06:19 +03:00
2007-12-15 23:53:26 +03:00
verbose_output ( " Group SID: %s \n " , sid_string_tos ( sd - > group_sid ) ) ;
2010-08-26 17:48:50 +04:00
if ( dom_sid_equal ( sd - > group_sid , s1 ) ) {
2006-09-21 02:23:12 +04:00
sid_copy ( sd - > group_sid , s2 ) ;
2005-08-26 20:06:17 +04:00
update = True ;
2010-05-20 14:02:55 +04:00
verbose_output ( " New Group SID: %s \n " ,
2007-12-15 23:53:26 +03:00
sid_string_tos ( sd - > group_sid ) ) ;
2005-08-26 20:06:17 +04:00
}
2002-11-01 08:06:19 +03:00
2009-02-24 02:44:34 +03:00
theacl = sd - > dacl ;
verbose_output ( " DACL: %d entries: \n " , theacl - > num_aces ) ;
for ( i = 0 ; i < theacl - > num_aces ; i + + ) {
2010-05-20 14:02:55 +04:00
verbose_output ( " Trustee SID: %s \n " ,
2009-02-24 02:44:34 +03:00
sid_string_tos ( & theacl - > aces [ i ] . trustee ) ) ;
2010-08-26 17:48:50 +04:00
if ( dom_sid_equal ( & theacl - > aces [ i ] . trustee , s1 ) ) {
2009-02-24 02:44:34 +03:00
sid_copy ( & theacl - > aces [ i ] . trustee , s2 ) ;
2005-08-26 20:06:17 +04:00
update = True ;
2010-05-20 14:02:55 +04:00
verbose_output ( " New Trustee SID: %s \n " ,
2009-02-24 02:44:34 +03:00
sid_string_tos ( & theacl - > 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
2009-02-24 02:44:34 +03:00
theacl = sd - > sacl ;
verbose_output ( " SACL: %d entries: \n " , theacl - > num_aces ) ;
for ( i = 0 ; i < theacl - > num_aces ; i + + ) {
2010-05-20 14:02:55 +04:00
verbose_output ( " Trustee SID: %s \n " ,
2009-02-24 02:44:34 +03:00
sid_string_tos ( & theacl - > aces [ i ] . trustee ) ) ;
2010-08-26 17:48:50 +04:00
if ( dom_sid_equal ( & theacl - > aces [ i ] . trustee , s1 ) ) {
2009-02-24 02:44:34 +03:00
sid_copy ( & theacl - > aces [ i ] . trustee , s2 ) ;
2007-02-26 16:07:34 +03:00
update = True ;
2010-05-20 14:02:55 +04:00
verbose_output ( " New Trustee SID: %s \n " ,
2009-02-24 02:44:34 +03:00
sid_string_tos ( & theacl - > aces [ i ] . trustee ) ) ;
2007-02-26 16:07:34 +03:00
}
}
# 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 ;
2010-05-18 12:29:34 +04:00
struct security_descriptor * new_sd ;
2009-03-23 20:14:17 +03:00
struct regval_ctr * values ;
2009-02-24 17:19:18 +03:00
struct regsubkey_ctr * subkeys ;
2005-08-26 07:40:24 +04:00
int i ;
2007-12-04 05:48:41 +03:00
char * path ;
2009-02-25 02:32:21 +03:00
WERROR werr ;
2005-08-26 07:40:24 +04:00
/* swap out the SIDs in the security descriptor */
2014-05-26 17:41:41 +04:00
if ( nk - > sec_desc - > sec_desc = = NULL ) {
new_sd = NULL ;
} else {
new_sd = security_descriptor_copy ( outfile - > mem_ctx ,
nk - > sec_desc - > sec_desc ) ;
}
if ( new_sd = = NULL ) {
fprintf ( stderr , " Failed to copy security descriptor! \n " ) ;
2005-08-26 07:40:24 +04:00
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
2009-02-25 02:32:21 +03:00
werr = regsubkey_ctr_init ( NULL , & subkeys ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
2005-08-29 18:55:40 +04:00
DEBUG ( 0 , ( " copy_registry_tree: talloc() failure! \n " ) ) ;
return False ;
}
2010-05-24 17:08:58 +04:00
werr = regval_ctr_init ( subkeys , & values ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
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
2009-03-23 20:14:17 +03:00
/* copy values into the struct 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 ,
2010-05-25 00:19:17 +04:00
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
2009-02-24 17:19:18 +03:00
/* copy subkeys into the struct 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
2007-12-04 05:48:41 +03:00
path = talloc_asprintf ( subkeys , " %s%s%s " ,
parentpath , parent ? " \\ " : " " , nk - > keyname ) ;
if ( ! path ) {
TALLOC_FREE ( subkeys ) ;
return false ;
}
2005-08-26 07:40:24 +04:00
nk - > subkey_index = 0 ;
2007-12-04 05:48:41 +03:00
while ( ( subkey = regfio_fetch_subkey ( infile , nk ) ) ) {
if ( ! copy_registry_tree ( infile , subkey , key , outfile , path ) ) {
TALLOC_FREE ( subkeys ) ;
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
/*********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-02-26 23:16:26 +04:00
int main ( int argc , const char * argv [ ] )
2002-10-31 20:27:47 +03:00
{
2007-12-04 05:48:41 +03:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2005-08-26 07:40:24 +04:00
int opt ;
REGF_FILE * infile , * outfile ;
REGF_NK_REC * nk ;
2007-12-04 05:48:41 +03:00
char * orig_filename , * new_filename ;
2005-08-26 07:40:24 +04:00
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
2010-10-29 07:19:32 +04:00
setup_logging ( " profiles " , DEBUG_STDERR ) ;
2005-08-26 07:40:24 +04:00
2014-02-26 23:16:26 +04:00
pc = poptGetContext ( " profiles " , argc , argv , long_options ,
2005-08-26 07:40:24 +04:00
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
2007-12-04 05:48:41 +03: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 ) ;
}
2007-12-04 05:48:41 +03:00
orig_filename = talloc_strdup ( frame , poptPeekArg ( pc ) ) ;
if ( ! orig_filename ) {
exit ( ENOMEM ) ;
}
new_filename = talloc_asprintf ( frame ,
" %s.new " ,
orig_filename ) ;
if ( ! new_filename ) {
exit ( ENOMEM ) ;
}
if ( ! ( infile = regfio_open ( orig_filename , O_RDONLY , 0 ) ) ) {
2005-08-26 07:40:24 +04:00
fprintf ( stderr , " Failed to open %s! \n " , orig_filename ) ;
fprintf ( stderr , " Error was (%s) \n " , strerror ( errno ) ) ;
exit ( 1 ) ;
}
2007-12-04 05:48:41 +03:00
2010-09-25 21:56:58 +04:00
if ( ! ( outfile = regfio_open ( new_filename , ( O_RDWR | O_CREAT | O_TRUNC ) ,
( S_IRUSR | S_IWUSR ) ) ) ) {
2005-08-26 07:40:24 +04:00
fprintf ( stderr , " Failed to open new file %s! \n " , new_filename ) ;
fprintf ( stderr , " Error was (%s) \n " , strerror ( errno ) ) ;
exit ( 1 ) ;
}
2007-12-04 05:48:41 +03:00
2005-08-26 07:40:24 +04:00
/* actually do the update now */
2007-12-04 05:48:41 +03:00
2006-06-20 13:16:53 +04:00
if ( ( nk = regfio_rootkey ( infile ) ) = = NULL ) {
fprintf ( stderr , " Could not get rootkey \n " ) ;
exit ( 3 ) ;
}
2007-12-04 05:48:41 +03:00
if ( ! copy_registry_tree ( infile , nk , NULL , outfile , " " ) ) {
2005-08-26 07:40:24 +04:00
fprintf ( stderr , " Failed to write updated registry file! \n " ) ;
exit ( 2 ) ;
}
2007-12-04 05:48:41 +03:00
2005-08-26 07:40:24 +04:00
/* cleanup */
2007-12-04 05:48:41 +03:00
regfio_close ( infile ) ;
regfio_close ( outfile ) ;
2005-08-26 07:40:24 +04:00
poptFreeContext ( pc ) ;
2007-12-04 05:48:41 +03:00
TALLOC_FREE ( frame ) ;
return 0 ;
2002-11-01 11:53:28 +03:00
}