2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Gerald Carter 2002.
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.
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.
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.
21 /* Implementation of registry frontend view functions. */
26 #define DBGC_CLASS DBGC_RPC_SRV
28 extern REGISTRY_OPS printing_ops;
29 extern REGISTRY_OPS regdb_ops; /* these are the default */
31 /* array of REGISTRY_HOOK's which are read into a tree for easy access */
34 REGISTRY_HOOK reg_hooks[] = {
35 { KEY_PRINTING, &printing_ops },
41 * Utility functions for REGSUBKEY_CTR
44 /***********************************************************************
45 Init the talloc context held by a REGSUBKEY_CTR structure
46 **********************************************************************/
48 void regsubkey_ctr_init( REGSUBKEY_CTR *ctr )
51 ctr->ctx = talloc_init();
54 /***********************************************************************
55 Add a new key to the array
56 **********************************************************************/
58 int regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, char *keyname )
65 len = strlen( keyname );
67 /* allocate a space for the char* in the array */
69 if ( ctr->subkeys == 0 )
70 ctr->subkeys = talloc( ctr->ctx, sizeof(char*) );
72 pp = talloc_realloc( ctr->ctx, ctr->subkeys, sizeof(char*)*(ctr->num_subkeys+1) );
77 /* allocate the string and save it in the array */
79 ctr->subkeys[ctr->num_subkeys] = talloc( ctr->ctx, len+1 );
80 strncpy( ctr->subkeys[ctr->num_subkeys], keyname, len+1 );
84 return ctr->num_subkeys;
87 /***********************************************************************
88 How many keys does the container hold ?
89 **********************************************************************/
91 int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr )
93 return ctr->num_subkeys;
96 /***********************************************************************
97 Retreive a specific key string
98 **********************************************************************/
100 char* regsubkey_ctr_specific_key( REGSUBKEY_CTR *ctr, uint32 key_index )
102 if ( ! (key_index < ctr->num_subkeys) )
105 return ctr->subkeys[key_index];
108 /***********************************************************************
109 free memory held by a REGSUBKEY_CTR structure
110 **********************************************************************/
112 void regsubkey_ctr_destroy( REGSUBKEY_CTR *ctr )
115 talloc_destroy( ctr->ctx );
122 * Utility functions for REGVAL_CTR
125 /***********************************************************************
126 Init the talloc context held by a REGSUBKEY_CTR structure
127 **********************************************************************/
129 void regval_ctr_init( REGVAL_CTR *ctr )
132 ctr->ctx = talloc_init();
135 /***********************************************************************
136 How many keys does the container hold ?
137 **********************************************************************/
139 int regval_ctr_numvals( REGVAL_CTR *ctr )
141 return ctr->num_values;
144 /***********************************************************************
145 allocate memory for and duplicate a REGISTRY_VALUE.
146 This is malloc'd memory so the caller should free it when done
147 **********************************************************************/
149 REGISTRY_VALUE* dup_registry_value( REGISTRY_VALUE *val )
151 REGISTRY_VALUE *copy = NULL;
156 if ( !(copy = malloc( sizeof(REGISTRY_VALUE) )) ) {
157 DEBUG(0,("dup_registry_value: malloc() failed!\n"));
161 /* copy all the non-pointer initial data */
163 memcpy( copy, val, sizeof(REGISTRY_VALUE) );
166 if ( !(copy->data_p = memdup( val->data_p, val->size )) ) {
167 DEBUG(0,("dup_registry_value: memdup() failed for [%d] bytes!\n",
176 /**********************************************************************
177 free the memory allocated to a REGISTRY_VALUE
178 *********************************************************************/
180 void free_registry_value( REGISTRY_VALUE *val )
185 SAFE_FREE( val->data_p );
191 /**********************************************************************
192 *********************************************************************/
194 uint8* regval_data_p( REGISTRY_VALUE *val )
199 /**********************************************************************
200 *********************************************************************/
202 int regval_size( REGISTRY_VALUE *val )
207 /**********************************************************************
208 *********************************************************************/
210 char* regval_name( REGISTRY_VALUE *val )
212 return val->valuename;
215 /**********************************************************************
216 *********************************************************************/
218 uint32 regval_type( REGISTRY_VALUE *val )
223 /***********************************************************************
224 Retreive a pointer to a specific value. Caller shoud dup the structure
225 since this memory may go away with a regval_ctr_destroy()
226 **********************************************************************/
228 REGISTRY_VALUE* regval_ctr_specific_value( REGVAL_CTR *ctr, uint32 idx )
230 if ( !(idx < ctr->num_values) )
233 return ctr->values[idx];
236 /***********************************************************************
237 Retrive the TALLOC_CTX associated with a REGISTRY_VALUE
238 **********************************************************************/
240 TALLOC_CTX* regval_ctr_getctx( REGVAL_CTR *val )
248 /***********************************************************************
249 Add a new registry value to the array
250 **********************************************************************/
252 int regval_ctr_addvalue( REGVAL_CTR *ctr, char *name, uint16 type,
253 char *data_p, size_t size )
255 REGISTRY_VALUE **ppreg;
260 len = strlen( name );
262 /* allocate a slot in the array of pointers */
264 if ( ctr->num_values == 0 )
265 ctr->values = talloc( ctr->ctx, sizeof(REGISTRY_VALUE*) );
267 ppreg = talloc_realloc( ctr->ctx, ctr->values, sizeof(REGISTRY_VALUE*)*(ctr->num_values+1) );
272 /* allocate a new value and store the pointer in the arrya */
274 ctr->values[ctr->num_values] = talloc( ctr->ctx, sizeof(REGISTRY_VALUE) );
278 fstrcpy( ctr->values[ctr->num_values]->valuename, name );
279 ctr->values[ctr->num_values]->type = type;
280 ctr->values[ctr->num_values]->data_p = talloc_memdup( ctr->ctx, data_p, size );
281 ctr->values[ctr->num_values]->size = size;
285 return ctr->num_values;
288 /***********************************************************************
289 Delete a single value from the registry container.
290 No need to free memory since it is talloc'd.
291 **********************************************************************/
293 int regval_ctr_delvalue( REGVAL_CTR *ctr, char *name )
297 /* search for the value */
299 for ( i=0; i<ctr->num_values; i++ ) {
300 if ( strcmp( ctr->values[i]->valuename, name ) == 0)
304 /* just return if we don't find it */
306 if ( i == ctr->num_values )
307 return ctr->num_values;
309 /* just shift everything down one */
311 for ( /* use previous i */; i<(ctr->num_values-1); i++ )
312 memcpy( ctr->values[i], ctr->values[i+1], sizeof(REGISTRY_VALUE) );
316 ZERO_STRUCTP( ctr->values[i] );
320 return ctr->num_values;
323 /***********************************************************************
324 Delete a single value from the registry container.
325 No need to free memory since it is talloc'd.
326 **********************************************************************/
328 REGISTRY_VALUE* regval_ctr_getvalue( REGVAL_CTR *ctr, char *name )
332 /* search for the value */
334 for ( i=0; i<ctr->num_values; i++ ) {
335 if ( strcmp( ctr->values[i]->valuename, name ) == 0)
336 return ctr->values[i];
343 /***********************************************************************
344 free memory held by a REGVAL_CTR structure
345 **********************************************************************/
347 void regval_ctr_destroy( REGVAL_CTR *ctr )
350 talloc_destroy( ctr->ctx );
355 /***********************************************************************
356 Open the registry database and initialize the REGISTRY_HOOK cache
357 ***********************************************************************/
359 BOOL init_registry( void )
363 if ( !init_registry_db() ) {
364 DEBUG(0,("init_registry: failed to initialize the registry tdb!\n"));
368 /* build the cache tree of registry hooks */
370 reghook_cache_init();
372 for ( i=0; reg_hooks[i].keyname; i++ ) {
373 if ( !reghook_cache_add(®_hooks[i]) )
377 if ( DEBUGLEVEL >= 20 )
378 reghook_dump_cache(20);
386 /***********************************************************************
387 High level wrapper function for storing registry subkeys
388 ***********************************************************************/
390 BOOL store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys )
392 if ( key->hook && key->hook->ops && key->hook->ops->store_subkeys_fn )
393 return key->hook->ops->store_subkeys_fn( key->name, subkeys );
399 /***********************************************************************
400 High level wrapper function for storing registry values
401 ***********************************************************************/
403 BOOL store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
405 if ( key->hook && key->hook->ops && key->hook->ops->store_values_fn )
406 return key->hook->ops->store_values_fn( key->name, val );
412 /***********************************************************************
413 High level wrapper function for enumerating registry subkeys
414 Initialize the TALLOC_CTX if necessary
415 ***********************************************************************/
417 int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
421 if ( key->hook && key->hook->ops && key->hook->ops->subkey_fn )
422 result = key->hook->ops->subkey_fn( key->name, subkey_ctr );
427 /***********************************************************************
428 retreive a specific subkey specified by index. Caller is
429 responsible for freeing memory
430 ***********************************************************************/
432 BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index )
434 static REGSUBKEY_CTR ctr;
435 static pstring save_path;
436 static BOOL ctr_init = False;
441 /* simple caching for performance; very basic heuristic */
444 DEBUG(8,("fetch_reg_keys_specific: Initializing cache of subkeys for [%s]\n", key->name));
445 ZERO_STRUCTP( &ctr );
446 regsubkey_ctr_init( &ctr );
448 pstrcpy( save_path, key->name );
450 if ( fetch_reg_keys( key, &ctr) == -1 )
455 /* clear the cache when key_index == 0 or the path has changed */
456 else if ( !key_index || StrCaseCmp( save_path, key->name) ) {
458 DEBUG(8,("fetch_reg_keys_specific: Updating cache of subkeys for [%s]\n", key->name));
460 regsubkey_ctr_destroy( &ctr );
461 regsubkey_ctr_init( &ctr );
463 pstrcpy( save_path, key->name );
465 if ( fetch_reg_keys( key, &ctr) == -1 )
469 if ( !(s = regsubkey_ctr_specific_key( &ctr, key_index )) )
472 *subkey = strdup( s );
478 /***********************************************************************
479 High level wrapper function for enumerating registry values
480 Initialize the TALLOC_CTX if necessary
481 ***********************************************************************/
483 int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
487 if ( key->hook && key->hook->ops && key->hook->ops->value_fn )
488 result = key->hook->ops->value_fn( key->name, val );
494 /***********************************************************************
495 retreive a specific subkey specified by index. Caller is
496 responsible for freeing memory
497 ***********************************************************************/
499 BOOL fetch_reg_values_specific( REGISTRY_KEY *key, REGISTRY_VALUE **val, uint32 val_index )
501 static REGVAL_CTR ctr;
502 static pstring save_path;
503 static BOOL ctr_init = False;
508 /* simple caching for performance; very basic heuristic */
511 DEBUG(8,("fetch_reg_values_specific: Initializing cache of values for [%s]\n", key->name));
513 ZERO_STRUCTP( &ctr );
514 regval_ctr_init( &ctr );
516 pstrcpy( save_path, key->name );
518 if ( fetch_reg_values( key, &ctr) == -1 )
523 /* clear the cache when val_index == 0 or the path has changed */
524 else if ( !val_index || StrCaseCmp(save_path, key->name) ) {
526 DEBUG(8,("fetch_reg_values_specific: Updating cache of values for [%s]\n", key->name));
528 regval_ctr_destroy( &ctr );
529 regval_ctr_init( &ctr );
531 pstrcpy( save_path, key->name );
533 if ( fetch_reg_values( key, &ctr) == -1 )
537 if ( !(v = regval_ctr_specific_value( &ctr, val_index )) )
540 *val = dup_registry_value( v );
545 /***********************************************************************
546 Utility function for splitting the base path of a registry path off
547 by setting base and new_path to the apprapriate offsets withing the
550 WARNING!! Does modify the original string!
551 ***********************************************************************/
553 BOOL reg_split_path( char *path, char **base, char **new_path )
557 *new_path = *base = NULL;
564 p = strchr( path, '\\' );