~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/utils/profiles.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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);
 
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 )
 
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,
 
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[] )
 
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
}