~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/registry/reg_db.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

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 2 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, write to the Free Software
18
 
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
 
 */
20
 
 
21
 
/* Implementation of internal registry database functions. */
22
 
 
23
 
#include "includes.h"
24
 
 
25
 
#undef DBGC_CLASS
26
 
#define DBGC_CLASS DBGC_RPC_SRV
27
 
 
28
 
static TDB_CONTEXT *tdb_reg;
29
 
static int tdb_refcount;
30
 
 
31
 
#define VALUE_PREFIX    "SAMBA_REGVAL"
32
 
 
33
 
/* List the deepest path into the registry.  All part components will be created.*/
34
 
 
35
 
/* If you want to have a part of the path controlled by the tdb and part by
36
 
   a virtual registry db (e.g. printing), then you have to list the deepest path.
37
 
   For example,"HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Print" 
38
 
   allows the reg_db backend to handle everything up to 
39
 
   "HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion" and then we'll hook 
40
 
   the reg_printing backend onto the last component of the path (see 
41
 
   KEY_PRINTING_2K in include/rpc_reg.h)   --jerry */
42
 
 
43
 
static const char *builtin_registry_paths[] = {
44
 
        KEY_PRINTING_2K,
45
 
        KEY_PRINTING_PORTS,
46
 
        KEY_PRINTING,
47
 
        KEY_SHARES,
48
 
        KEY_EVENTLOG,
49
 
        "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib",
50
 
        "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009",
51
 
        "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors",
52
 
        "HKLM\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
53
 
        "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration",
54
 
        "HKLM\\SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters",
55
 
        "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Netlogon\\Parameters",
56
 
        "HKU",
57
 
        "HKCR",
58
 
        "HKPD",
59
 
        "HKPT",
60
 
         NULL };
61
 
 
62
 
struct builtin_regkey_value {
63
 
        const char *path;
64
 
        const char *valuename;
65
 
        uint32 type;
66
 
        union {
67
 
                const char *string;
68
 
                uint32 dw_value;
69
 
        } data;
70
 
};
71
 
 
72
 
static struct builtin_regkey_value builtin_registry_values[] = {
73
 
        { KEY_PRINTING_PORTS,
74
 
                SAMBA_PRINTER_PORT_NAME, REG_SZ, { "" } },
75
 
        { KEY_PRINTING_2K,
76
 
                "DefaultSpoolDirectory", REG_SZ, { "C:\\Windows\\System32\\Spool\\Printers" } },
77
 
        { KEY_EVENTLOG,
78
 
                "DisplayName", REG_SZ, { "Event Log" } }, 
79
 
        { KEY_EVENTLOG,
80
 
                "ErrorControl", REG_DWORD, { (char*)0x00000001 } },
81
 
        { NULL, NULL, 0, { NULL } }
82
 
};
83
 
 
84
 
#define REGVER_V1       1       /* first db version with write support */
85
 
        
86
 
/***********************************************************************
87
 
 Open the registry data in the tdb
88
 
 ***********************************************************************/
89
 
 
90
 
static BOOL init_registry_data( void )
91
 
{
92
 
        pstring path, base, remaining;
93
 
        fstring keyname, subkeyname;
94
 
        REGSUBKEY_CTR *subkeys;
95
 
        REGVAL_CTR *values;
96
 
        int i;
97
 
        const char *p, *p2;
98
 
        UNISTR2 data;
99
 
        
100
 
        /* loop over all of the predefined paths and add each component */
101
 
        
102
 
        for ( i=0; builtin_registry_paths[i] != NULL; i++ ) {
103
 
 
104
 
                DEBUG(6,("init_registry_data: Adding [%s]\n", builtin_registry_paths[i]));
105
 
 
106
 
                pstrcpy( path, builtin_registry_paths[i] );
107
 
                pstrcpy( base, "" );
108
 
                p = path;
109
 
                
110
 
                while ( next_token(&p, keyname, "\\", sizeof(keyname)) ) {
111
 
                
112
 
                        /* build up the registry path from the components */
113
 
                        
114
 
                        if ( *base )
115
 
                                pstrcat( base, "\\" );
116
 
                        pstrcat( base, keyname );
117
 
                        
118
 
                        /* get the immediate subkeyname (if we have one ) */
119
 
                        
120
 
                        *subkeyname = '\0';
121
 
                        if ( *p ) {
122
 
                                pstrcpy( remaining, p );
123
 
                                p2 = remaining;
124
 
                                
125
 
                                if ( !next_token(&p2, subkeyname, "\\", sizeof(subkeyname)) )
126
 
                                        fstrcpy( subkeyname, p2 );
127
 
                        }
128
 
 
129
 
                        DEBUG(10,("init_registry_data: Storing key [%s] with subkey [%s]\n",
130
 
                                base, *subkeyname ? subkeyname : "NULL"));
131
 
                        
132
 
                        /* we don't really care if the lookup succeeds or not since
133
 
                           we are about to update the record.  We just want any 
134
 
                           subkeys already present */
135
 
                        
136
 
                        if ( !(subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) ) {
137
 
                                DEBUG(0,("talloc() failure!\n"));
138
 
                                return False;
139
 
                        }
140
 
 
141
 
                        regdb_fetch_keys( base, subkeys );
142
 
                        if ( *subkeyname ) 
143
 
                                regsubkey_ctr_addkey( subkeys, subkeyname );
144
 
                        if ( !regdb_store_keys( base, subkeys ))
145
 
                                return False;
146
 
                        
147
 
                        TALLOC_FREE( subkeys );
148
 
                }
149
 
        }
150
 
 
151
 
        /* loop over all of the predefined values and add each component */
152
 
        
153
 
        for ( i=0; builtin_registry_values[i].path != NULL; i++ ) {
154
 
                if ( !(values = TALLOC_ZERO_P( NULL, REGVAL_CTR )) ) {
155
 
                        DEBUG(0,("talloc() failure!\n"));
156
 
                        return False;
157
 
                }
158
 
 
159
 
                regdb_fetch_values( builtin_registry_values[i].path, values );
160
 
 
161
 
                /* preserve existing values across restarts.  Only add new ones */
162
 
 
163
 
                if ( !regval_ctr_key_exists( values, builtin_registry_values[i].valuename ) ) 
164
 
                {
165
 
                        switch( builtin_registry_values[i].type ) {
166
 
                        case REG_DWORD:
167
 
                                regval_ctr_addvalue( values, 
168
 
                                                     builtin_registry_values[i].valuename,
169
 
                                                     REG_DWORD,
170
 
                                                     (char*)&builtin_registry_values[i].data.dw_value,
171
 
                                                     sizeof(uint32) );
172
 
                                break;
173
 
                                
174
 
                        case REG_SZ:
175
 
                                init_unistr2( &data, builtin_registry_values[i].data.string, UNI_STR_TERMINATE);
176
 
                                regval_ctr_addvalue( values, 
177
 
                                                     builtin_registry_values[i].valuename,
178
 
                                                     REG_SZ,
179
 
                                                     (char*)data.buffer,
180
 
                                                     data.uni_str_len*sizeof(uint16) );
181
 
                                break;
182
 
                        
183
 
                        default:
184
 
                                DEBUG(0,("init_registry_data: invalid value type in builtin_registry_values [%d]\n",
185
 
                                        builtin_registry_values[i].type));
186
 
                        }
187
 
                        regdb_store_values( builtin_registry_values[i].path, values );
188
 
                }
189
 
                
190
 
                TALLOC_FREE( values );
191
 
        }
192
 
        
193
 
        return True;
194
 
}
195
 
 
196
 
/***********************************************************************
197
 
 Open the registry database
198
 
 ***********************************************************************/
199
 
 
200
 
BOOL regdb_init( void )
201
 
{
202
 
        const char *vstring = "INFO/version";
203
 
        uint32 vers_id;
204
 
 
205
 
        if ( tdb_reg )
206
 
                return True;
207
 
 
208
 
        if ( !(tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600)) )
209
 
        {
210
 
                tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
211
 
                if ( !tdb_reg ) {
212
 
                        DEBUG(0,("regdb_init: Failed to open registry %s (%s)\n",
213
 
                                lock_path("registry.tdb"), strerror(errno) ));
214
 
                        return False;
215
 
                }
216
 
                
217
 
                DEBUG(10,("regdb_init: Successfully created registry tdb\n"));
218
 
        }
219
 
 
220
 
        tdb_refcount = 1;
221
 
                
222
 
 
223
 
        vers_id = tdb_fetch_int32(tdb_reg, vstring);
224
 
 
225
 
        if ( vers_id != REGVER_V1 ) {
226
 
                /* any upgrade code here if needed */
227
 
        }
228
 
 
229
 
        /* always setup the necessary keys and values */
230
 
 
231
 
        if ( !init_registry_data() ) {
232
 
                DEBUG(0,("init_registry: Failed to initiailize data in registry!\n"));
233
 
                return False;
234
 
        }
235
 
 
236
 
        return True;
237
 
}
238
 
 
239
 
/***********************************************************************
240
 
 Open the registry.  Must already have been initialized by regdb_init()
241
 
 ***********************************************************************/
242
 
 
243
 
WERROR regdb_open( void )
244
 
{
245
 
        WERROR result = WERR_OK;
246
 
 
247
 
        if ( tdb_reg ) {
248
 
                DEBUG(10,("regdb_open: incrementing refcount (%d)\n", tdb_refcount));
249
 
                tdb_refcount++;
250
 
                return WERR_OK;
251
 
        }
252
 
        
253
 
        become_root();
254
 
 
255
 
        tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600);
256
 
        if ( !tdb_reg ) {
257
 
                result = ntstatus_to_werror( map_nt_error_from_unix( errno ) );
258
 
                DEBUG(0,("regdb_open: Failed to open %s! (%s)\n", 
259
 
                        lock_path("registry.tdb"), strerror(errno) ));
260
 
        }
261
 
 
262
 
        unbecome_root();
263
 
 
264
 
        tdb_refcount = 1;
265
 
        DEBUG(10,("regdb_open: refcount reset (%d)\n", tdb_refcount));
266
 
 
267
 
        return result;
268
 
}
269
 
 
270
 
/***********************************************************************
271
 
 ***********************************************************************/
272
 
 
273
 
int regdb_close( void )
274
 
{
275
 
        int ret;
276
 
 
277
 
        tdb_refcount--;
278
 
 
279
 
        DEBUG(10,("regdb_close: decrementing refcount (%d)\n", tdb_refcount));
280
 
 
281
 
        if ( tdb_refcount > 0 )
282
 
                return 0;
283
 
 
284
 
        SMB_ASSERT( tdb_refcount >= 0 );
285
 
 
286
 
        ret = tdb_close( tdb_reg );
287
 
        tdb_reg = NULL;
288
 
 
289
 
        return ret;
290
 
}
291
 
 
292
 
/***********************************************************************
293
 
 Add subkey strings to the registry tdb under a defined key
294
 
 fmt is the same format as tdb_pack except this function only supports
295
 
 fstrings
296
 
 ***********************************************************************/
297
 
 
298
 
static BOOL regdb_store_keys_internal( const char *key, REGSUBKEY_CTR *ctr )
299
 
{
300
 
        TDB_DATA kbuf, dbuf;
301
 
        char *buffer;
302
 
        int i = 0;
303
 
        uint32 len, buflen;
304
 
        BOOL ret = True;
305
 
        uint32 num_subkeys = regsubkey_ctr_numkeys( ctr );
306
 
        pstring keyname;
307
 
        
308
 
        if ( !key )
309
 
                return False;
310
 
 
311
 
        pstrcpy( keyname, key );
312
 
        normalize_reg_path( keyname );
313
 
 
314
 
        /* allocate some initial memory */
315
 
                
316
 
        buffer = SMB_MALLOC(sizeof(pstring));
317
 
        buflen = sizeof(pstring);
318
 
        len = 0;
319
 
        
320
 
        /* store the number of subkeys */
321
 
        
322
 
        len += tdb_pack(buffer+len, buflen-len, "d", num_subkeys );
323
 
        
324
 
        /* pack all the strings */
325
 
        
326
 
        for (i=0; i<num_subkeys; i++) {
327
 
                len += tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) );
328
 
                if ( len > buflen ) {
329
 
                        /* allocate some extra space */
330
 
                        if ((buffer = SMB_REALLOC( buffer, len*2 )) == NULL) {
331
 
                                DEBUG(0,("regdb_store_keys: Failed to realloc memory of size [%d]\n", len*2));
332
 
                                ret = False;
333
 
                                goto done;
334
 
                        }
335
 
                        buflen = len*2;
336
 
                                        
337
 
                        len = tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) );
338
 
                }               
339
 
        }
340
 
        
341
 
        /* finally write out the data */
342
 
        
343
 
        kbuf.dptr = keyname;
344
 
        kbuf.dsize = strlen(keyname)+1;
345
 
        dbuf.dptr = buffer;
346
 
        dbuf.dsize = len;
347
 
        if ( tdb_store( tdb_reg, kbuf, dbuf, TDB_REPLACE ) == -1) {
348
 
                ret = False;
349
 
                goto done;
350
 
        }
351
 
 
352
 
done:           
353
 
        SAFE_FREE( buffer );
354
 
        
355
 
        return ret;
356
 
}
357
 
 
358
 
/***********************************************************************
359
 
 Store the new subkey record and create any child key records that 
360
 
 do not currently exist
361
 
 ***********************************************************************/
362
 
 
363
 
BOOL regdb_store_keys( const char *key, REGSUBKEY_CTR *ctr )
364
 
{
365
 
        int num_subkeys, i;
366
 
        pstring path;
367
 
        REGSUBKEY_CTR *subkeys, *old_subkeys;
368
 
        char *oldkeyname;
369
 
        
370
 
        /* fetch a list of the old subkeys so we can determine if any were deleted */
371
 
        
372
 
        if ( !(old_subkeys = TALLOC_ZERO_P( ctr, REGSUBKEY_CTR )) ) {
373
 
                DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
374
 
                return False;
375
 
        }
376
 
 
377
 
        regdb_fetch_keys( key, old_subkeys );
378
 
        
379
 
        /* store the subkey list for the parent */
380
 
        
381
 
        if ( !regdb_store_keys_internal( key, ctr ) ) {
382
 
                DEBUG(0,("regdb_store_keys: Failed to store new subkey list for parent [%s}\n", key ));
383
 
                return False;
384
 
        }
385
 
        
386
 
        /* now delete removed keys */
387
 
        
388
 
        num_subkeys = regsubkey_ctr_numkeys( old_subkeys );
389
 
        for ( i=0; i<num_subkeys; i++ ) {
390
 
                oldkeyname = regsubkey_ctr_specific_key( old_subkeys, i );
391
 
                if ( !regsubkey_ctr_key_exists( ctr, oldkeyname ) ) {
392
 
                        pstr_sprintf( path, "%s%c%s", key, '/', oldkeyname );
393
 
                        normalize_reg_path( path );
394
 
                        tdb_delete_bystring( tdb_reg, path );
395
 
                }
396
 
        }
397
 
 
398
 
        TALLOC_FREE( old_subkeys );
399
 
        
400
 
        /* now create records for any subkeys that don't already exist */
401
 
        
402
 
        num_subkeys = regsubkey_ctr_numkeys( ctr );
403
 
        for ( i=0; i<num_subkeys; i++ ) {
404
 
                pstr_sprintf( path, "%s%c%s", key, '/', regsubkey_ctr_specific_key( ctr, i ) );
405
 
 
406
 
                if ( !(subkeys = TALLOC_ZERO_P( ctr, REGSUBKEY_CTR )) ) {
407
 
                        DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
408
 
                        return False;
409
 
                }
410
 
 
411
 
                if ( regdb_fetch_keys( path, subkeys ) == -1 ) {
412
 
                        /* create a record with 0 subkeys */
413
 
                        if ( !regdb_store_keys_internal( path, subkeys ) ) {
414
 
                                DEBUG(0,("regdb_store_keys: Failed to store new record for key [%s}\n", path ));
415
 
                                TALLOC_FREE( subkeys );
416
 
                                return False;
417
 
                        }
418
 
                }
419
 
 
420
 
                TALLOC_FREE( subkeys );
421
 
        }
422
 
        
423
 
        return True;
424
 
}
425
 
 
426
 
 
427
 
/***********************************************************************
428
 
 Retrieve an array of strings containing subkeys.  Memory should be 
429
 
 released by the caller.  
430
 
 ***********************************************************************/
431
 
 
432
 
int regdb_fetch_keys( const char* key, REGSUBKEY_CTR *ctr )
433
 
{
434
 
        pstring path;
435
 
        uint32 num_items;
436
 
        TDB_DATA dbuf;
437
 
        char *buf;
438
 
        uint32 buflen, len;
439
 
        int i;
440
 
        fstring subkeyname;
441
 
 
442
 
        DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL"));
443
 
        
444
 
        pstrcpy( path, key );
445
 
        
446
 
        /* convert to key format */
447
 
        pstring_sub( path, "\\", "/" ); 
448
 
        strupper_m( path );
449
 
        
450
 
        dbuf = tdb_fetch_bystring( tdb_reg, path );
451
 
        
452
 
        buf = dbuf.dptr;
453
 
        buflen = dbuf.dsize;
454
 
        
455
 
        if ( !buf ) {
456
 
                DEBUG(5,("regdb_fetch_keys: tdb lookup failed to locate key [%s]\n", key));
457
 
                return -1;
458
 
        }
459
 
        
460
 
        len = tdb_unpack( buf, buflen, "d", &num_items);
461
 
        
462
 
        for (i=0; i<num_items; i++) {
463
 
                len += tdb_unpack( buf+len, buflen-len, "f", subkeyname );
464
 
                regsubkey_ctr_addkey( ctr, subkeyname );
465
 
        }
466
 
 
467
 
        SAFE_FREE( dbuf.dptr );
468
 
        
469
 
        DEBUG(11,("regdb_fetch_keys: Exit [%d] items\n", num_items));
470
 
        
471
 
        return num_items;
472
 
}
473
 
 
474
 
/****************************************************************************
475
 
 Unpack a list of registry values frem the TDB
476
 
 ***************************************************************************/
477
 
 
478
 
static int regdb_unpack_values(REGVAL_CTR *values, char *buf, int buflen)
479
 
{
480
 
        int             len = 0;
481
 
        uint32          type;
482
 
        pstring         valuename;
483
 
        uint32          size;
484
 
        uint8           *data_p;
485
 
        uint32          num_values = 0;
486
 
        int             i;
487
 
        
488
 
        
489
 
        
490
 
        /* loop and unpack the rest of the registry values */
491
 
        
492
 
        len += tdb_unpack(buf+len, buflen-len, "d", &num_values);
493
 
        
494
 
        for ( i=0; i<num_values; i++ ) {
495
 
                /* unpack the next regval */
496
 
                
497
 
                type = REG_NONE;
498
 
                size = 0;
499
 
                data_p = NULL;
500
 
                len += tdb_unpack(buf+len, buflen-len, "fdB",
501
 
                                  valuename,
502
 
                                  &type,
503
 
                                  &size,
504
 
                                  &data_p);
505
 
                                
506
 
                /* add the new value. Paranoid protective code -- make sure data_p is valid */
507
 
 
508
 
                if ( size && data_p ) {
509
 
                        regval_ctr_addvalue( values, valuename, type, (const char *)data_p, size );
510
 
                        SAFE_FREE(data_p); /* 'B' option to tdb_unpack does a malloc() */
511
 
                }
512
 
 
513
 
                DEBUG(8,("specific: [%s], len: %d\n", valuename, size));
514
 
        }
515
 
 
516
 
        return len;
517
 
}
518
 
 
519
 
/****************************************************************************
520
 
 Pack all values in all printer keys
521
 
 ***************************************************************************/
522
 
 
523
 
static int regdb_pack_values(REGVAL_CTR *values, char *buf, int buflen)
524
 
{
525
 
        int             len = 0;
526
 
        int             i;
527
 
        REGISTRY_VALUE  *val;
528
 
        int             num_values;
529
 
 
530
 
        if ( !values )
531
 
                return 0;
532
 
 
533
 
        num_values = regval_ctr_numvals( values );
534
 
 
535
 
        /* pack the number of values first */
536
 
        
537
 
        len += tdb_pack( buf+len, buflen-len, "d", num_values );
538
 
        
539
 
        /* loop over all values */
540
 
                
541
 
        for ( i=0; i<num_values; i++ ) {                        
542
 
                val = regval_ctr_specific_value( values, i );
543
 
                len += tdb_pack(buf+len, buflen-len, "fdB",
544
 
                                regval_name(val),
545
 
                                regval_type(val),
546
 
                                regval_size(val),
547
 
                                regval_data_p(val) );
548
 
        }
549
 
 
550
 
        return len;
551
 
}
552
 
 
553
 
/***********************************************************************
554
 
 Retrieve an array of strings containing subkeys.  Memory should be 
555
 
 released by the caller.
556
 
 ***********************************************************************/
557
 
 
558
 
int regdb_fetch_values( const char* key, REGVAL_CTR *values )
559
 
{
560
 
        TDB_DATA data;
561
 
        pstring keystr;
562
 
 
563
 
        DEBUG(10,("regdb_fetch_values: Looking for value of key [%s] \n", key));
564
 
        
565
 
        pstr_sprintf( keystr, "%s/%s", VALUE_PREFIX, key );
566
 
        normalize_reg_path( keystr );
567
 
        
568
 
        data = tdb_fetch_bystring( tdb_reg, keystr );
569
 
        
570
 
        if ( !data.dptr ) {
571
 
                /* all keys have zero values by default */
572
 
                return 0;
573
 
        }
574
 
        
575
 
        regdb_unpack_values( values, data.dptr, data.dsize );
576
 
        
577
 
        SAFE_FREE( data.dptr );
578
 
        
579
 
        return regval_ctr_numvals(values);
580
 
}
581
 
 
582
 
/***********************************************************************
583
 
 Stub function since we do not currently support storing registry 
584
 
 values in the registry.tdb
585
 
 ***********************************************************************/
586
 
 
587
 
BOOL regdb_store_values( const char *key, REGVAL_CTR *values )
588
 
{
589
 
        TDB_DATA data;
590
 
        pstring keystr;
591
 
        int len, ret;
592
 
        
593
 
        DEBUG(10,("regdb_store_values: Looking for value of key [%s] \n", key));
594
 
        
595
 
        ZERO_STRUCT( data );
596
 
        
597
 
        len = regdb_pack_values( values, data.dptr, data.dsize );
598
 
        if ( len <= 0 ) {
599
 
                DEBUG(0,("regdb_store_values: unable to pack values. len <= 0\n"));
600
 
                return False;
601
 
        }
602
 
        
603
 
        data.dptr = SMB_MALLOC_ARRAY( char, len );
604
 
        data.dsize = len;
605
 
        
606
 
        len = regdb_pack_values( values, data.dptr, data.dsize );
607
 
        
608
 
        SMB_ASSERT( len == data.dsize );
609
 
        
610
 
        pstr_sprintf( keystr, "%s/%s", VALUE_PREFIX, key );
611
 
        normalize_reg_path( keystr );
612
 
        
613
 
        ret = tdb_store_bystring(tdb_reg, keystr, data, TDB_REPLACE);
614
 
        
615
 
        SAFE_FREE( data.dptr );
616
 
        
617
 
        return ret != -1 ;
618
 
}
619
 
 
620
 
 
621
 
/* 
622
 
 * Table of function pointers for default access
623
 
 */
624
 
 
625
 
REGISTRY_OPS regdb_ops = {
626
 
        regdb_fetch_keys,
627
 
        regdb_fetch_values,
628
 
        regdb_store_keys,
629
 
        regdb_store_values,
630
 
        NULL
631
 
};
632
 
 
633