~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/registry/reg_objects.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
 *  Unix SMB/CIFS implementation.
 
3
 *  Virtual Windows Registry Layer
 
4
 *  Copyright (C) Gerald Carter                     2002-2005
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; either version 3 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  This program is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
/* Implementation of registry frontend view functions. */
 
21
 
 
22
#include "includes.h"
 
23
 
 
24
#undef DBGC_CLASS
 
25
#define DBGC_CLASS DBGC_REGISTRY
 
26
 
 
27
struct regsubkey_ctr {
 
28
        uint32_t        num_subkeys;
 
29
        char            **subkeys;
 
30
        struct db_context *subkeys_hash;
 
31
        int seqnum;
 
32
};
 
33
 
 
34
/**********************************************************************
 
35
 
 
36
 Note that the struct regsubkey_ctr and REGVAL_CTR objects *must* be
 
37
 talloc()'d since the methods use the object pointer as the talloc
 
38
 context for internal private data.
 
39
 
 
40
 There is no longer a regval_ctr_intit() and regval_ctr_destroy()
 
41
 pair of functions.  Simply TALLOC_ZERO_P() and TALLOC_FREE() the
 
42
 object.
 
43
 
 
44
 **********************************************************************/
 
45
 
 
46
WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr)
 
47
{
 
48
        if (ctr == NULL) {
 
49
                return WERR_INVALID_PARAM;
 
50
        }
 
51
 
 
52
        *ctr = talloc_zero(mem_ctx, struct regsubkey_ctr);
 
53
        if (*ctr == NULL) {
 
54
                return WERR_NOMEM;
 
55
        }
 
56
 
 
57
        (*ctr)->subkeys_hash = db_open_rbt(*ctr);
 
58
        if ((*ctr)->subkeys_hash == NULL) {
 
59
                talloc_free(*ctr);
 
60
                return WERR_NOMEM;
 
61
        }
 
62
 
 
63
        return WERR_OK;
 
64
}
 
65
 
 
66
WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum)
 
67
{
 
68
        if (ctr == NULL) {
 
69
                return WERR_INVALID_PARAM;
 
70
        }
 
71
 
 
72
        ctr->seqnum = seqnum;
 
73
 
 
74
        return WERR_OK;
 
75
}
 
76
 
 
77
int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr)
 
78
{
 
79
        if (ctr == NULL) {
 
80
                return -1;
 
81
        }
 
82
 
 
83
        return ctr->seqnum;
 
84
}
 
85
 
 
86
static WERROR regsubkey_ctr_hash_keyname(struct regsubkey_ctr *ctr,
 
87
                                         const char *keyname,
 
88
                                         uint32 idx)
 
89
{
 
90
        WERROR werr;
 
91
 
 
92
        werr = ntstatus_to_werror(dbwrap_store_bystring(ctr->subkeys_hash,
 
93
                                                keyname,
 
94
                                                make_tdb_data((uint8 *)&idx,
 
95
                                                              sizeof(idx)),
 
96
                                                TDB_REPLACE));
 
97
        if (!W_ERROR_IS_OK(werr)) {
 
98
                DEBUG(1, ("error hashing new key '%s' in container: %s\n",
 
99
                          keyname, win_errstr(werr)));
 
100
        }
 
101
 
 
102
        return werr;
 
103
}
 
104
 
 
105
static WERROR regsubkey_ctr_unhash_keyname(struct regsubkey_ctr *ctr,
 
106
                                           const char *keyname)
 
107
{
 
108
        WERROR werr;
 
109
 
 
110
        werr = ntstatus_to_werror(dbwrap_delete_bystring(ctr->subkeys_hash,
 
111
                                  keyname));
 
112
        if (!W_ERROR_IS_OK(werr)) {
 
113
                DEBUG(1, ("error unhashing key '%s' in container: %s\n",
 
114
                          keyname, win_errstr(werr)));
 
115
        }
 
116
 
 
117
        return werr;
 
118
}
 
119
 
 
120
static WERROR regsubkey_ctr_index_for_keyname(struct regsubkey_ctr *ctr,
 
121
                                              const char *keyname,
 
122
                                              uint32 *idx)
 
123
{
 
124
        TDB_DATA data;
 
125
 
 
126
        if ((ctr == NULL) || (keyname == NULL)) {
 
127
                return WERR_INVALID_PARAM;
 
128
        }
 
129
 
 
130
        data = dbwrap_fetch_bystring(ctr->subkeys_hash, ctr, keyname);
 
131
        if (data.dptr == NULL) {
 
132
                return WERR_NOT_FOUND;
 
133
        }
 
134
 
 
135
        if (data.dsize != sizeof(*idx)) {
 
136
                talloc_free(data.dptr);
 
137
                return WERR_INVALID_DATATYPE;
 
138
        }
 
139
 
 
140
        if (idx != NULL) {
 
141
                *idx = *(uint32 *)data.dptr;
 
142
        }
 
143
 
 
144
        talloc_free(data.dptr);
 
145
        return WERR_OK;
 
146
}
 
147
 
 
148
/***********************************************************************
 
149
 Add a new key to the array
 
150
 **********************************************************************/
 
151
 
 
152
WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname )
 
153
{
 
154
        char **newkeys;
 
155
        WERROR werr;
 
156
 
 
157
        if ( !keyname ) {
 
158
                return WERR_OK;
 
159
        }
 
160
 
 
161
        /* make sure the keyname is not already there */
 
162
 
 
163
        if ( regsubkey_ctr_key_exists( ctr, keyname ) ) {
 
164
                return WERR_OK;
 
165
        }
 
166
 
 
167
        if (!(newkeys = TALLOC_REALLOC_ARRAY(ctr, ctr->subkeys, char *,
 
168
                                             ctr->num_subkeys+1))) {
 
169
                return WERR_NOMEM;
 
170
        }
 
171
 
 
172
        ctr->subkeys = newkeys;
 
173
 
 
174
        if (!(ctr->subkeys[ctr->num_subkeys] = talloc_strdup(ctr->subkeys,
 
175
                                                             keyname ))) {
 
176
                /*
 
177
                 * Don't shrink the new array again, this wastes a pointer
 
178
                 */
 
179
                return WERR_NOMEM;
 
180
        }
 
181
 
 
182
        werr = regsubkey_ctr_hash_keyname(ctr, keyname, ctr->num_subkeys);
 
183
        W_ERROR_NOT_OK_RETURN(werr);
 
184
 
 
185
        ctr->num_subkeys++;
 
186
 
 
187
        return WERR_OK;
 
188
}
 
189
 
 
190
 /***********************************************************************
 
191
 Delete a key from the array
 
192
 **********************************************************************/
 
193
 
 
194
WERROR regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname )
 
195
{
 
196
        WERROR werr;
 
197
        uint32 idx, j;
 
198
 
 
199
        if (keyname == NULL) {
 
200
                return WERR_INVALID_PARAM;
 
201
        }
 
202
 
 
203
        /* make sure the keyname is actually already there */
 
204
 
 
205
        werr = regsubkey_ctr_index_for_keyname(ctr, keyname, &idx);
 
206
        W_ERROR_NOT_OK_RETURN(werr);
 
207
 
 
208
        werr = regsubkey_ctr_unhash_keyname(ctr, keyname);
 
209
        W_ERROR_NOT_OK_RETURN(werr);
 
210
 
 
211
        /* update if we have any keys left */
 
212
        ctr->num_subkeys--;
 
213
        if (idx < ctr->num_subkeys) {
 
214
                memmove(&ctr->subkeys[idx], &ctr->subkeys[idx+1],
 
215
                        sizeof(char *) * (ctr->num_subkeys - idx));
 
216
 
 
217
                /* we have to re-hash rest of the array...  :-( */
 
218
                for (j = idx; j < ctr->num_subkeys; j++) {
 
219
                        werr = regsubkey_ctr_hash_keyname(ctr, ctr->subkeys[j], j);
 
220
                        W_ERROR_NOT_OK_RETURN(werr);
 
221
                }
 
222
        }
 
223
 
 
224
        return WERR_OK;
 
225
}
 
226
 
 
227
/***********************************************************************
 
228
 Check for the existance of a key
 
229
 **********************************************************************/
 
230
 
 
231
bool regsubkey_ctr_key_exists( struct regsubkey_ctr *ctr, const char *keyname )
 
232
{
 
233
        WERROR werr;
 
234
 
 
235
        if (!ctr->subkeys) {
 
236
                return False;
 
237
        }
 
238
 
 
239
        werr = regsubkey_ctr_index_for_keyname(ctr, keyname, NULL);
 
240
        if (!W_ERROR_IS_OK(werr)) {
 
241
                return false;
 
242
        }
 
243
 
 
244
        return true;
 
245
}
 
246
 
 
247
/***********************************************************************
 
248
 How many keys does the container hold ?
 
249
 **********************************************************************/
 
250
 
 
251
int regsubkey_ctr_numkeys( struct regsubkey_ctr *ctr )
 
252
{
 
253
        return ctr->num_subkeys;
 
254
}
 
255
 
 
256
/***********************************************************************
 
257
 Retreive a specific key string
 
258
 **********************************************************************/
 
259
 
 
260
char* regsubkey_ctr_specific_key( struct regsubkey_ctr *ctr, uint32_t key_index )
 
261
{
 
262
        if ( ! (key_index < ctr->num_subkeys) )
 
263
                return NULL;
 
264
 
 
265
        return ctr->subkeys[key_index];
 
266
}
 
267
 
 
268
/*
 
269
 * Utility functions for REGVAL_CTR
 
270
 */
 
271
 
 
272
/***********************************************************************
 
273
 How many keys does the container hold ?
 
274
 **********************************************************************/
 
275
 
 
276
int regval_ctr_numvals( REGVAL_CTR *ctr )
 
277
{
 
278
        return ctr->num_values;
 
279
}
 
280
 
 
281
/***********************************************************************
 
282
 allocate memory for and duplicate a REGISTRY_VALUE.
 
283
 This is malloc'd memory so the caller should free it when done
 
284
 **********************************************************************/
 
285
 
 
286
REGISTRY_VALUE* dup_registry_value( REGISTRY_VALUE *val )
 
287
{
 
288
        REGISTRY_VALUE  *copy = NULL;
 
289
 
 
290
        if ( !val )
 
291
                return NULL;
 
292
 
 
293
        if ( !(copy = SMB_MALLOC_P( REGISTRY_VALUE)) ) {
 
294
                DEBUG(0,("dup_registry_value: malloc() failed!\n"));
 
295
                return NULL;
 
296
        }
 
297
 
 
298
        /* copy all the non-pointer initial data */
 
299
 
 
300
        memcpy( copy, val, sizeof(REGISTRY_VALUE) );
 
301
 
 
302
        copy->size = 0;
 
303
        copy->data_p = NULL;
 
304
 
 
305
        if ( val->data_p && val->size )
 
306
        {
 
307
                if ( !(copy->data_p = (uint8 *)memdup( val->data_p,
 
308
                                                       val->size )) ) {
 
309
                        DEBUG(0,("dup_registry_value: memdup() failed for [%d] "
 
310
                                 "bytes!\n", val->size));
 
311
                        SAFE_FREE( copy );
 
312
                        return NULL;
 
313
                }
 
314
                copy->size = val->size;
 
315
        }
 
316
 
 
317
        return copy;
 
318
}
 
319
 
 
320
/**********************************************************************
 
321
 free the memory allocated to a REGISTRY_VALUE
 
322
 *********************************************************************/
 
323
 
 
324
void free_registry_value( REGISTRY_VALUE *val )
 
325
{
 
326
        if ( !val )
 
327
                return;
 
328
 
 
329
        SAFE_FREE( val->data_p );
 
330
        SAFE_FREE( val );
 
331
 
 
332
        return;
 
333
}
 
334
 
 
335
/**********************************************************************
 
336
 *********************************************************************/
 
337
 
 
338
uint8* regval_data_p( REGISTRY_VALUE *val )
 
339
{
 
340
        return val->data_p;
 
341
}
 
342
 
 
343
/**********************************************************************
 
344
 *********************************************************************/
 
345
 
 
346
uint32 regval_size( REGISTRY_VALUE *val )
 
347
{
 
348
        return val->size;
 
349
}
 
350
 
 
351
/**********************************************************************
 
352
 *********************************************************************/
 
353
 
 
354
char* regval_name( REGISTRY_VALUE *val )
 
355
{
 
356
        return val->valuename;
 
357
}
 
358
 
 
359
/**********************************************************************
 
360
 *********************************************************************/
 
361
 
 
362
uint32 regval_type( REGISTRY_VALUE *val )
 
363
{
 
364
        return val->type;
 
365
}
 
366
 
 
367
/***********************************************************************
 
368
 Retreive a pointer to a specific value.  Caller shoud dup the structure
 
369
 since this memory will go away when the ctr is free()'d
 
370
 **********************************************************************/
 
371
 
 
372
REGISTRY_VALUE* regval_ctr_specific_value( REGVAL_CTR *ctr, uint32 idx )
 
373
{
 
374
        if ( !(idx < ctr->num_values) )
 
375
                return NULL;
 
376
 
 
377
        return ctr->values[idx];
 
378
}
 
379
 
 
380
/***********************************************************************
 
381
 Check for the existance of a value
 
382
 **********************************************************************/
 
383
 
 
384
bool regval_ctr_key_exists( REGVAL_CTR *ctr, const char *value )
 
385
{
 
386
        int     i;
 
387
 
 
388
        for ( i=0; i<ctr->num_values; i++ ) {
 
389
                if ( strequal( ctr->values[i]->valuename, value) )
 
390
                        return True;
 
391
        }
 
392
 
 
393
        return False;
 
394
}
 
395
 
 
396
/***********************************************************************
 
397
 * compose a REGISTRY_VALUE from input data
 
398
 **********************************************************************/
 
399
 
 
400
REGISTRY_VALUE *regval_compose(TALLOC_CTX *ctx, const char *name, uint16 type,
 
401
                               const char *data_p, size_t size)
 
402
{
 
403
        REGISTRY_VALUE *regval = TALLOC_P(ctx, REGISTRY_VALUE);
 
404
 
 
405
        if (regval == NULL) {
 
406
                return NULL;
 
407
        }
 
408
 
 
409
        fstrcpy(regval->valuename, name);
 
410
        regval->type = type;
 
411
        if (size) {
 
412
                regval->data_p = (uint8 *)TALLOC_MEMDUP(regval, data_p, size);
 
413
                if (!regval->data_p) {
 
414
                        TALLOC_FREE(regval);
 
415
                        return NULL;
 
416
                }
 
417
        } else {
 
418
                regval->data_p = NULL;
 
419
        }
 
420
        regval->size = size;
 
421
 
 
422
        return regval;
 
423
}
 
424
 
 
425
/***********************************************************************
 
426
 Add a new registry value to the array
 
427
 **********************************************************************/
 
428
 
 
429
int regval_ctr_addvalue( REGVAL_CTR *ctr, const char *name, uint16 type,
 
430
                         const char *data_p, size_t size )
 
431
{
 
432
        if ( !name )
 
433
                return ctr->num_values;
 
434
 
 
435
        /* Delete the current value (if it exists) and add the new one */
 
436
 
 
437
        regval_ctr_delvalue( ctr, name );
 
438
 
 
439
        /* allocate a slot in the array of pointers */
 
440
 
 
441
        if (  ctr->num_values == 0 ) {
 
442
                ctr->values = TALLOC_P( ctr, REGISTRY_VALUE *);
 
443
        } else {
 
444
                ctr->values = TALLOC_REALLOC_ARRAY(ctr, ctr->values,
 
445
                                                   REGISTRY_VALUE *,
 
446
                                                   ctr->num_values+1);
 
447
        }
 
448
 
 
449
        if (!ctr->values) {
 
450
                ctr->num_values = 0;
 
451
                return 0;
 
452
        }
 
453
 
 
454
        /* allocate a new value and store the pointer in the arrya */
 
455
 
 
456
        ctr->values[ctr->num_values] = regval_compose(ctr, name, type, data_p,
 
457
                                                      size);
 
458
        if (ctr->values[ctr->num_values] == NULL) {
 
459
                ctr->num_values = 0;
 
460
                return 0;
 
461
        }
 
462
        ctr->num_values++;
 
463
 
 
464
        return ctr->num_values;
 
465
}
 
466
 
 
467
/***********************************************************************
 
468
 Add a new registry value to the array
 
469
 **********************************************************************/
 
470
 
 
471
int regval_ctr_copyvalue( REGVAL_CTR *ctr, REGISTRY_VALUE *val )
 
472
{
 
473
        if ( val ) {
 
474
                regval_ctr_addvalue(ctr, val->valuename, val->type,
 
475
                                    (char *)val->data_p, val->size);
 
476
        }
 
477
 
 
478
        return ctr->num_values;
 
479
}
 
480
 
 
481
/***********************************************************************
 
482
 Delete a single value from the registry container.
 
483
 No need to free memory since it is talloc'd.
 
484
 **********************************************************************/
 
485
 
 
486
int regval_ctr_delvalue( REGVAL_CTR *ctr, const char *name )
 
487
{
 
488
        int     i;
 
489
 
 
490
        for ( i=0; i<ctr->num_values; i++ ) {
 
491
                if ( strequal( ctr->values[i]->valuename, name ) )
 
492
                        break;
 
493
        }
 
494
 
 
495
        /* just return if we don't find it */
 
496
 
 
497
        if ( i == ctr->num_values )
 
498
                return ctr->num_values;
 
499
 
 
500
        /* If 'i' was not the last element, just shift everything down one */
 
501
        ctr->num_values--;
 
502
        if ( i < ctr->num_values )
 
503
                memmove(&ctr->values[i], &ctr->values[i+1],
 
504
                        sizeof(REGISTRY_VALUE*)*(ctr->num_values-i));
 
505
 
 
506
        return ctr->num_values;
 
507
}
 
508
 
 
509
/***********************************************************************
 
510
 Retrieve single value from the registry container.
 
511
 No need to free memory since it is talloc'd.
 
512
 **********************************************************************/
 
513
 
 
514
REGISTRY_VALUE* regval_ctr_getvalue( REGVAL_CTR *ctr, const char *name )
 
515
{
 
516
        int     i;
 
517
 
 
518
        /* search for the value */
 
519
 
 
520
        for ( i=0; i<ctr->num_values; i++ ) {
 
521
                if ( strequal( ctr->values[i]->valuename, name ) )
 
522
                        return ctr->values[i];
 
523
        }
 
524
 
 
525
        return NULL;
 
526
}
 
527
 
 
528
/***********************************************************************
 
529
 return the data_p as a uint32
 
530
 **********************************************************************/
 
531
 
 
532
uint32 regval_dword( REGISTRY_VALUE *val )
 
533
{
 
534
        uint32 data;
 
535
 
 
536
        data = IVAL( regval_data_p(val), 0 );
 
537
 
 
538
        return data;
 
539
}
 
540
 
 
541
/***********************************************************************
 
542
 return the data_p as a character string
 
543
 **********************************************************************/
 
544
 
 
545
char *regval_sz(REGISTRY_VALUE *val)
 
546
{
 
547
        char *data = NULL;
 
548
 
 
549
        rpcstr_pull_talloc(talloc_tos(), &data,
 
550
                        regval_data_p(val), regval_size(val),0);
 
551
        return data;
 
552
}