utils/profiles.c

説明を見る。
00001 /* 
00002    Samba Unix/Linux SMB client utility profiles.c 
00003    
00004    Copyright (C) Richard Sharpe, <rsharpe@richardsharpe.com>   2002 
00005    Copyright (C) Jelmer Vernooij (conversion to popt)          2003 
00006    Copyright (C) Gerald (Jerry) Carter                         2005 
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012    
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017    
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
00021 */
00022                                   
00023 #include "includes.h"
00024 #include "regfio.h"
00025 
00026 /* GLOBAL VARIABLES */
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         /* swap out the SIDs in the security descriptor */
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         /* copy values into the REGVAL_CTR */
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         /* copy subkeys into the REGSUBKEY_CTR */
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         /* write each one of the subkeys out */
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         /* values is a talloc()'d child of subkeys here so just throw it all away */
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         /* setup logging options */
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         /* Now, process the arguments */
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         /* actually do the update now */
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         /* cleanup */
00279         
00280         regfio_close( infile );
00281         regfio_close( outfile );
00282 
00283         poptFreeContext(pc);
00284 
00285         return( 0 );
00286 }

Sambaに対してSat Aug 29 21:23:30 2009に生成されました。  doxygen 1.4.7