00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "includes.h"
00024 #include "regfio.h"
00025
00026
00027
00028 DOM_SID old_sid, new_sid;
00029 int change = 0, new_val = 0;
00030 BOOL opt_verbose = False;
00031
00032
00033
00034
00035 static void verbose_output(const char *format, ...) PRINTF_ATTRIBUTE(1,2);
00036 static void verbose_output(const char *format, ...)
00037 {
00038 va_list args;
00039 char *var = NULL;
00040
00041 if (!opt_verbose) {
00042 return;
00043 }
00044
00045 va_start(args, format);
00046 if ((vasprintf(&var, format, args)) == -1) {
00047 va_end(args);
00048 return;
00049 }
00050
00051 fprintf(stdout, var);
00052 va_end(args);
00053 SAFE_FREE(var);
00054 }
00055
00056
00057
00058
00059 static BOOL swap_sid_in_acl( SEC_DESC *sd, DOM_SID *s1, DOM_SID *s2 )
00060 {
00061 SEC_ACL *acl;
00062 int i;
00063 BOOL update = False;
00064
00065 verbose_output(" Owner SID: %s\n", sid_string_static(sd->owner_sid));
00066 if ( sid_equal( sd->owner_sid, s1 ) ) {
00067 sid_copy( sd->owner_sid, s2 );
00068 update = True;
00069 verbose_output(" New Owner SID: %s\n",
00070 sid_string_static(sd->owner_sid));
00071
00072 }
00073
00074 verbose_output(" Group SID: %s\n", sid_string_static(sd->group_sid));
00075 if ( sid_equal( sd->group_sid, s1 ) ) {
00076 sid_copy( sd->group_sid, s2 );
00077 update = True;
00078 verbose_output(" New Group SID: %s\n",
00079 sid_string_static(sd->group_sid));
00080 }
00081
00082 acl = sd->dacl;
00083 verbose_output(" DACL: %d entries:\n", acl->num_aces);
00084 for ( i=0; i<acl->num_aces; i++ ) {
00085 verbose_output(" Trustee SID: %s\n",
00086 sid_string_static(&acl->aces[i].trustee));
00087 if ( sid_equal( &acl->aces[i].trustee, s1 ) ) {
00088 sid_copy( &acl->aces[i].trustee, s2 );
00089 update = True;
00090 verbose_output(" New Trustee SID: %s\n",
00091 sid_string_static(&acl->aces[i].trustee));
00092 }
00093 }
00094
00095 #if 0
00096 acl = sd->sacl;
00097 verbose_output(" SACL: %d entries: \n", acl->num_aces);
00098 for ( i=0; i<acl->num_aces; i++ ) {
00099 verbose_output(" Trustee SID: %s\n",
00100 sid_string_static(&acl->aces[i].trustee));
00101 if ( sid_equal( &acl->aces[i].trustee, s1 ) ) {
00102 sid_copy( &acl->aces[i].trustee, s2 );
00103 update = True;
00104 verbose_output(" New Trustee SID: %s\n",
00105 sid_string_static(&acl->aces[i].trustee));
00106 }
00107 }
00108 #endif
00109 return update;
00110 }
00111
00112
00113
00114
00115 static BOOL copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
00116 REGF_NK_REC *parent, REGF_FILE *outfile,
00117 const char *parentpath )
00118 {
00119 REGF_NK_REC *key, *subkey;
00120 SEC_DESC *new_sd;
00121 REGVAL_CTR *values;
00122 REGSUBKEY_CTR *subkeys;
00123 int i;
00124 pstring path;
00125
00126
00127
00128 if ( !(new_sd = dup_sec_desc( outfile->mem_ctx, nk->sec_desc->sec_desc )) ) {
00129 fprintf( stderr, "Failed to copy security descriptor!\n" );
00130 return False;
00131 }
00132
00133 verbose_output("ACL for %s%s%s\n", parentpath, parent ? "\\" : "", nk->keyname);
00134 swap_sid_in_acl( new_sd, &old_sid, &new_sid );
00135
00136 if ( !(subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) ) {
00137 DEBUG(0,("copy_registry_tree: talloc() failure!\n"));
00138 return False;
00139 }
00140
00141 if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) {
00142 DEBUG(0,("copy_registry_tree: talloc() failure!\n"));
00143 return False;
00144 }
00145
00146
00147
00148 for ( i=0; i<nk->num_values; i++ ) {
00149 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
00150 (const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
00151 }
00152
00153
00154
00155 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
00156 regsubkey_ctr_addkey( subkeys, subkey->keyname );
00157 }
00158
00159 key = regfio_write_key( outfile, nk->keyname, values, subkeys, new_sd, parent );
00160
00161
00162
00163 pstr_sprintf( path, "%s%s%s", parentpath, parent ? "\\" : "", nk->keyname );
00164
00165 nk->subkey_index = 0;
00166 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
00167 if ( !copy_registry_tree( infile, subkey, key, outfile, path ) )
00168 return False;
00169 }
00170
00171
00172
00173 TALLOC_FREE( subkeys );
00174
00175 verbose_output("[%s]\n", path);
00176
00177 return True;
00178 }
00179
00180
00181
00182
00183 int main( int argc, char *argv[] )
00184 {
00185 int opt;
00186 REGF_FILE *infile, *outfile;
00187 REGF_NK_REC *nk;
00188 pstring orig_filename, new_filename;
00189 struct poptOption long_options[] = {
00190 POPT_AUTOHELP
00191 { "change-sid", 'c', POPT_ARG_STRING, NULL, 'c', "Provides SID to change" },
00192 { "new-sid", 'n', POPT_ARG_STRING, NULL, 'n', "Provides SID to change to" },
00193 { "verbose", 'v', POPT_ARG_NONE, &opt_verbose, 'v', "Verbose output" },
00194 POPT_COMMON_SAMBA
00195 POPT_COMMON_VERSION
00196 POPT_TABLEEND
00197 };
00198 poptContext pc;
00199
00200 load_case_tables();
00201
00202
00203
00204 setup_logging( "profiles", True );
00205 dbf = x_stderr;
00206 x_setbuf( x_stderr, NULL );
00207
00208 pc = poptGetContext("profiles", argc, (const char **)argv, long_options,
00209 POPT_CONTEXT_KEEP_FIRST);
00210
00211 poptSetOtherOptionHelp(pc, "<profilefile>");
00212
00213
00214
00215 while ((opt = poptGetNextOpt(pc)) != -1) {
00216 switch (opt) {
00217 case 'c':
00218 change = 1;
00219 if (!string_to_sid(&old_sid, poptGetOptArg(pc))) {
00220 fprintf(stderr, "Argument to -c should be a SID in form of S-1-5-...\n");
00221 poptPrintUsage(pc, stderr, 0);
00222 exit(254);
00223 }
00224 break;
00225
00226 case 'n':
00227 new_val = 1;
00228 if (!string_to_sid(&new_sid, poptGetOptArg(pc))) {
00229 fprintf(stderr, "Argument to -n should be a SID in form of S-1-5-...\n");
00230 poptPrintUsage(pc, stderr, 0);
00231 exit(253);
00232 }
00233 break;
00234
00235 }
00236 }
00237
00238 poptGetArg(pc);
00239
00240 if (!poptPeekArg(pc)) {
00241 poptPrintUsage(pc, stderr, 0);
00242 exit(1);
00243 }
00244
00245 if ((!change && new_val) || (change && !new_val)) {
00246 fprintf(stderr, "You must specify both -c and -n if one or the other is set!\n");
00247 poptPrintUsage(pc, stderr, 0);
00248 exit(252);
00249 }
00250
00251 pstrcpy( orig_filename, poptPeekArg(pc) );
00252 pstr_sprintf( new_filename, "%s.new", orig_filename );
00253
00254 if ( !(infile = regfio_open( orig_filename, O_RDONLY, 0 )) ) {
00255 fprintf( stderr, "Failed to open %s!\n", orig_filename );
00256 fprintf( stderr, "Error was (%s)\n", strerror(errno) );
00257 exit (1);
00258 }
00259
00260 if ( !(outfile = regfio_open( new_filename, (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
00261 fprintf( stderr, "Failed to open new file %s!\n", new_filename );
00262 fprintf( stderr, "Error was (%s)\n", strerror(errno) );
00263 exit (1);
00264 }
00265
00266
00267
00268 if ((nk = regfio_rootkey( infile )) == NULL) {
00269 fprintf(stderr, "Could not get rootkey\n");
00270 exit(3);
00271 }
00272
00273 if ( !copy_registry_tree( infile, nk, NULL, outfile, "" ) ) {
00274 fprintf(stderr, "Failed to write updated registry file!\n");
00275 exit(2);
00276 }
00277
00278
00279
00280 regfio_close( infile );
00281 regfio_close( outfile );
00282
00283 poptFreeContext(pc);
00284
00285 return( 0 );
00286 }