root/source3/utils/profiles.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. verbose_output
  2. swap_sid_in_acl
  3. copy_registry_tree
  4. main

   1 /* 
   2    Samba Unix/Linux SMB client utility profiles.c 
   3    
   4    Copyright (C) Richard Sharpe, <rsharpe@richardsharpe.com>   2002 
   5    Copyright (C) Jelmer Vernooij (conversion to popt)          2003 
   6    Copyright (C) Gerald (Jerry) Carter                         2005 
   7 
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12    
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17    
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  
  20 */
  21                                   
  22 #include "includes.h"
  23 #include "regfio.h"
  24 
  25 /* GLOBAL VARIABLES */
  26 
  27 DOM_SID old_sid, new_sid;
  28 int change = 0, new_val = 0;
  29 int opt_verbose = False;
  30 
  31 /********************************************************************
  32 ********************************************************************/
  33 
  34 static void verbose_output(const char *format, ...) PRINTF_ATTRIBUTE(1,2);
     /* [<][>][^][v][top][bottom][index][help] */
  35 static void verbose_output(const char *format, ...)
  36 {
  37         va_list args;
  38         char *var = NULL;
  39 
  40         if (!opt_verbose) {
  41                 return;
  42         }
  43 
  44         va_start(args, format);
  45         if ((vasprintf(&var, format, args)) == -1) {
  46                 va_end(args);
  47                 return;
  48         }
  49 
  50         fprintf(stdout, "%s", var);
  51         va_end(args);
  52         SAFE_FREE(var);
  53 }
  54 
  55 /********************************************************************
  56 ********************************************************************/
  57 
  58 static bool swap_sid_in_acl( SEC_DESC *sd, DOM_SID *s1, DOM_SID *s2 )
     /* [<][>][^][v][top][bottom][index][help] */
  59 {
  60         SEC_ACL *theacl;
  61         int i;
  62         bool update = False;
  63 
  64         verbose_output("  Owner SID: %s\n", sid_string_tos(sd->owner_sid));
  65         if ( sid_equal( sd->owner_sid, s1 ) ) {
  66                 sid_copy( sd->owner_sid, s2 );
  67                 update = True;
  68                 verbose_output("  New Owner SID: %s\n", 
  69                         sid_string_tos(sd->owner_sid));
  70 
  71         }
  72 
  73         verbose_output("  Group SID: %s\n", sid_string_tos(sd->group_sid));
  74         if ( sid_equal( sd->group_sid, s1 ) ) {
  75                 sid_copy( sd->group_sid, s2 );
  76                 update = True;
  77                 verbose_output("  New Group SID: %s\n", 
  78                         sid_string_tos(sd->group_sid));
  79         }
  80 
  81         theacl = sd->dacl;
  82         verbose_output("  DACL: %d entries:\n", theacl->num_aces);
  83         for ( i=0; i<theacl->num_aces; i++ ) {
  84                 verbose_output("    Trustee SID: %s\n", 
  85                         sid_string_tos(&theacl->aces[i].trustee));
  86                 if ( sid_equal( &theacl->aces[i].trustee, s1 ) ) {
  87                         sid_copy( &theacl->aces[i].trustee, s2 );
  88                         update = True;
  89                         verbose_output("    New Trustee SID: %s\n", 
  90                                 sid_string_tos(&theacl->aces[i].trustee));
  91                 }
  92         }
  93 
  94 #if 0
  95         theacl = sd->sacl;
  96         verbose_output("  SACL: %d entries: \n", theacl->num_aces);
  97         for ( i=0; i<theacl->num_aces; i++ ) {
  98                 verbose_output("    Trustee SID: %s\n", 
  99                         sid_string_tos(&theacl->aces[i].trustee));
 100                 if ( sid_equal( &theacl->aces[i].trustee, s1 ) ) {
 101                         sid_copy( &theacl->aces[i].trustee, s2 );
 102                         update = True;
 103                         verbose_output("    New Trustee SID: %s\n", 
 104                                 sid_string_tos(&theacl->aces[i].trustee));
 105                 }
 106         }
 107 #endif
 108         return update;
 109 }
 110 
 111 /********************************************************************
 112 ********************************************************************/
 113 
 114 static bool copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
     /* [<][>][^][v][top][bottom][index][help] */
 115                                 REGF_NK_REC *parent, REGF_FILE *outfile,
 116                                 const char *parentpath  )
 117 {
 118         REGF_NK_REC *key, *subkey;
 119         SEC_DESC *new_sd;
 120         REGVAL_CTR *values;
 121         struct regsubkey_ctr *subkeys;
 122         int i;
 123         char *path;
 124         WERROR werr;
 125 
 126         /* swap out the SIDs in the security descriptor */
 127 
 128         if ( !(new_sd = dup_sec_desc( outfile->mem_ctx, nk->sec_desc->sec_desc )) ) {
 129                 fprintf( stderr, "Failed to copy security descriptor!\n" );
 130                 return False;
 131         }
 132 
 133         verbose_output("ACL for %s%s%s\n", parentpath, parent ? "\\" : "", nk->keyname);
 134         swap_sid_in_acl( new_sd, &old_sid, &new_sid );
 135 
 136         werr = regsubkey_ctr_init(NULL, &subkeys);
 137         if (!W_ERROR_IS_OK(werr)) {
 138                 DEBUG(0,("copy_registry_tree: talloc() failure!\n"));
 139                 return False;
 140         }
 141 
 142         if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) {
 143                 TALLOC_FREE( subkeys );
 144                 DEBUG(0,("copy_registry_tree: talloc() failure!\n"));
 145                 return False;
 146         }
 147 
 148         /* copy values into the REGVAL_CTR */
 149 
 150         for ( i=0; i<nk->num_values; i++ ) {
 151                 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
 152                         (const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
 153         }
 154 
 155         /* copy subkeys into the struct regsubkey_ctr */
 156 
 157         while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
 158                 regsubkey_ctr_addkey( subkeys, subkey->keyname );
 159         }
 160 
 161         key = regfio_write_key( outfile, nk->keyname, values, subkeys, new_sd, parent );
 162 
 163         /* write each one of the subkeys out */
 164 
 165         path = talloc_asprintf(subkeys, "%s%s%s",
 166                         parentpath, parent ? "\\" : "",nk->keyname);
 167         if (!path) {
 168                 TALLOC_FREE( subkeys );
 169                 return false;
 170         }
 171 
 172         nk->subkey_index = 0;
 173         while ((subkey = regfio_fetch_subkey(infile, nk))) {
 174                 if (!copy_registry_tree( infile, subkey, key, outfile, path)) {
 175                         TALLOC_FREE(subkeys);
 176                         return false;
 177                 }
 178         }
 179 
 180         /* values is a talloc()'d child of subkeys here so just throw it all away */
 181 
 182         TALLOC_FREE( subkeys );
 183 
 184         verbose_output("[%s]\n", path);
 185 
 186         return True;
 187 }
 188 
 189 /*********************************************************************
 190 *********************************************************************/
 191 
 192 int main( int argc, char *argv[] )
     /* [<][>][^][v][top][bottom][index][help] */
 193 {
 194         TALLOC_CTX *frame = talloc_stackframe();
 195         int opt;
 196         REGF_FILE *infile, *outfile;
 197         REGF_NK_REC *nk;
 198         char *orig_filename, *new_filename;
 199         struct poptOption long_options[] = {
 200                 POPT_AUTOHELP
 201                 { "change-sid", 'c', POPT_ARG_STRING, NULL, 'c', "Provides SID to change" },
 202                 { "new-sid", 'n', POPT_ARG_STRING, NULL, 'n', "Provides SID to change to" },
 203                 { "verbose", 'v', POPT_ARG_NONE, &opt_verbose, 'v', "Verbose output" },
 204                 POPT_COMMON_SAMBA
 205                 POPT_COMMON_VERSION
 206                 POPT_TABLEEND
 207         };
 208         poptContext pc;
 209 
 210         load_case_tables();
 211 
 212         /* setup logging options */
 213 
 214         setup_logging( "profiles", True );
 215         dbf = x_stderr;
 216         x_setbuf( x_stderr, NULL );
 217 
 218         pc = poptGetContext("profiles", argc, (const char **)argv, long_options,
 219                 POPT_CONTEXT_KEEP_FIRST);
 220 
 221         poptSetOtherOptionHelp(pc, "<profilefile>");
 222 
 223         /* Now, process the arguments */
 224 
 225         while ((opt = poptGetNextOpt(pc)) != -1) {
 226                 switch (opt) {
 227                 case 'c':
 228                         change = 1;
 229                         if (!string_to_sid(&old_sid, poptGetOptArg(pc))) {
 230                                 fprintf(stderr, "Argument to -c should be a SID in form of S-1-5-...\n");
 231                                 poptPrintUsage(pc, stderr, 0);
 232                                 exit(254);
 233                         }
 234                         break;
 235 
 236                 case 'n':
 237                         new_val = 1;
 238                         if (!string_to_sid(&new_sid, poptGetOptArg(pc))) {
 239                                 fprintf(stderr, "Argument to -n should be a SID in form of S-1-5-...\n");
 240                                 poptPrintUsage(pc, stderr, 0);
 241                                 exit(253);
 242                         }
 243                         break;
 244 
 245                 }
 246         }
 247 
 248         poptGetArg(pc);
 249 
 250         if (!poptPeekArg(pc)) {
 251                 poptPrintUsage(pc, stderr, 0);
 252                 exit(1);
 253         }
 254 
 255         if ((!change && new_val) || (change && !new_val)) {
 256                 fprintf(stderr, "You must specify both -c and -n if one or the other is set!\n");
 257                 poptPrintUsage(pc, stderr, 0);
 258                 exit(252);
 259         }
 260 
 261         orig_filename = talloc_strdup(frame, poptPeekArg(pc));
 262         if (!orig_filename) {
 263                 exit(ENOMEM);
 264         }
 265         new_filename = talloc_asprintf(frame,
 266                                         "%s.new",
 267                                         orig_filename);
 268         if (!new_filename) {
 269                 exit(ENOMEM);
 270         }
 271 
 272         if (!(infile = regfio_open( orig_filename, O_RDONLY, 0))) {
 273                 fprintf( stderr, "Failed to open %s!\n", orig_filename );
 274                 fprintf( stderr, "Error was (%s)\n", strerror(errno) );
 275                 exit (1);
 276         }
 277 
 278         if ( !(outfile = regfio_open( new_filename, (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
 279                 fprintf( stderr, "Failed to open new file %s!\n", new_filename );
 280                 fprintf( stderr, "Error was (%s)\n", strerror(errno) );
 281                 exit (1);
 282         }
 283 
 284         /* actually do the update now */
 285 
 286         if ((nk = regfio_rootkey( infile )) == NULL) {
 287                 fprintf(stderr, "Could not get rootkey\n");
 288                 exit(3);
 289         }
 290 
 291         if (!copy_registry_tree( infile, nk, NULL, outfile, "")) {
 292                 fprintf(stderr, "Failed to write updated registry file!\n");
 293                 exit(2);
 294         }
 295 
 296         /* cleanup */
 297 
 298         regfio_close(infile);
 299         regfio_close(outfile);
 300 
 301         poptFreeContext(pc);
 302 
 303         TALLOC_FREE(frame);
 304         return 0;
 305 }

/* [<][>][^][v][top][bottom][index][help] */