done! printer_info_2, devicemode, sec_desc, & printer data all enumerate
[Samba.git] / source / registry / reg_frontend.c
blobc0788c1b7532ea65c1e49eddc8fdb8f383356a21
1 /*
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. */
23 #include "includes.h"
25 #undef DBGC_CLASS
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 },
36 { NULL, NULL }
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 )
50 if ( !ctr->ctx )
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 )
60 uint32 len;
61 char **pp;
63 if ( 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*) );
71 else {
72 pp = talloc_realloc( ctr->ctx, ctr->subkeys, sizeof(char*)*(ctr->num_subkeys+1) );
73 if ( pp )
74 ctr->subkeys = pp;
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 );
81 ctr->num_subkeys++;
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) )
103 return NULL;
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 )
114 if ( ctr ) {
115 talloc_destroy( ctr->ctx );
116 ZERO_STRUCTP( ctr );
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 )
131 if ( !ctr->ctx )
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;
153 if ( !val )
154 return NULL;
156 if ( !(copy = malloc( sizeof(REGISTRY_VALUE) )) ) {
157 DEBUG(0,("dup_registry_value: malloc() failed!\n"));
158 return NULL;
161 /* copy all the non-pointer initial data */
163 memcpy( copy, val, sizeof(REGISTRY_VALUE) );
164 if ( val->data_p )
166 if ( !(copy->data_p = memdup( val->data_p, val->size )) ) {
167 DEBUG(0,("dup_registry_value: memdup() failed for [%d] bytes!\n",
168 val->size));
169 SAFE_FREE( copy );
173 return copy;
176 /**********************************************************************
177 free the memory allocated to a REGISTRY_VALUE
178 *********************************************************************/
180 void free_registry_value( REGISTRY_VALUE *val )
182 if ( !val )
183 return;
185 SAFE_FREE( val->data_p );
186 SAFE_FREE( val );
188 return;
191 /***********************************************************************
192 Retreive a pointer to a specific value. Caller shoud dup the structure
193 since this memory may go away with a regval_ctr_destroy()
194 **********************************************************************/
196 REGISTRY_VALUE* regval_ctr_specific_value( REGVAL_CTR *ctr, uint32 idx )
198 if ( !(idx < ctr->num_values) )
199 return NULL;
201 return ctr->values[idx];
204 /***********************************************************************
205 Retrive the TALLOC_CTX associated with a REGISTRY_VALUE
206 **********************************************************************/
208 TALLOC_CTX* regval_ctr_getctx( REGVAL_CTR *val )
210 if ( !val )
211 return NULL;
213 return val->ctx;
216 /***********************************************************************
217 Add a new regostry value to the array
218 **********************************************************************/
220 int regval_ctr_addvalue( REGVAL_CTR *ctr, char *name, uint16 type,
221 char *data_p, size_t size )
223 REGISTRY_VALUE **ppreg;
224 uint16 len;
226 if ( name )
228 len = strlen( name );
230 /* allocate a slot in the array of pointers */
232 if ( ctr->num_values == 0 )
233 ctr->values = talloc( ctr->ctx, sizeof(REGISTRY_VALUE*) );
234 else {
235 ppreg = talloc_realloc( ctr->ctx, ctr->values, sizeof(REGISTRY_VALUE*)*(ctr->num_values+1) );
236 if ( ppreg )
237 ctr->values = ppreg;
240 /* allocate a new valuie and store the pointer in the arrya */
242 ctr->values[ctr->num_values] = talloc( ctr->ctx, sizeof(REGISTRY_VALUE) );
244 /* init the value */
246 fstrcpy( ctr->values[ctr->num_values]->valuename, name );
247 ctr->values[ctr->num_values]->type = type;
248 ctr->values[ctr->num_values]->data_p = talloc_memdup( ctr->ctx, data_p, size );
249 ctr->values[ctr->num_values]->size = size;
250 ctr->num_values++;
253 return ctr->num_values;
256 /***********************************************************************
257 free memory held by a REGVAL_CTR structure
258 **********************************************************************/
260 void regval_ctr_destroy( REGVAL_CTR *ctr )
262 if ( ctr ) {
263 talloc_destroy( ctr->ctx );
264 ZERO_STRUCTP( ctr );
268 /***********************************************************************
269 Open the registry database and initialize the REGISTRY_HOOK cache
270 ***********************************************************************/
272 BOOL init_registry( void )
274 int i;
276 if ( !init_registry_db() ) {
277 DEBUG(0,("init_registry: failed to initialize the registry tdb!\n"));
278 return False;
281 /* build the cache tree of registry hooks */
283 reghook_cache_init();
285 for ( i=0; reg_hooks[i].keyname; i++ ) {
286 if ( !reghook_cache_add(&reg_hooks[i]) )
287 return False;
290 if ( DEBUGLEVEL >= 20 )
291 reghook_dump_cache(20);
293 return True;
299 /***********************************************************************
300 High level wrapper function for storing registry subkeys
301 ***********************************************************************/
303 BOOL store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys )
305 if ( key->hook && key->hook->ops && key->hook->ops->store_subkeys_fn )
306 return key->hook->ops->store_subkeys_fn( key->name, subkeys );
307 else
308 return False;
312 /***********************************************************************
313 High level wrapper function for storing registry values
314 ***********************************************************************/
316 BOOL store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
318 if ( key->hook && key->hook->ops && key->hook->ops->store_values_fn )
319 return key->hook->ops->store_values_fn( key->name, val );
320 else
321 return False;
325 /***********************************************************************
326 High level wrapper function for enumerating registry subkeys
327 Initialize the TALLOC_CTX if necessary
328 ***********************************************************************/
330 int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
332 int result = -1;
334 if ( key->hook && key->hook->ops && key->hook->ops->subkey_fn )
335 result = key->hook->ops->subkey_fn( key->name, subkey_ctr );
337 return result;
340 /***********************************************************************
341 retreive a specific subkey specified by index. Caller is
342 responsible for freeing memory
343 ***********************************************************************/
345 BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index )
347 static REGSUBKEY_CTR ctr;
348 static pstring save_path;
349 static BOOL ctr_init = False;
350 char *s;
352 *subkey = NULL;
354 /* simple caching for performance; very basic heuristic */
356 if ( !ctr_init ) {
357 DEBUG(8,("fetch_reg_keys_specific: Initializing cache of subkeys for [%s]\n", key->name));
358 ZERO_STRUCTP( &ctr );
359 regsubkey_ctr_init( &ctr );
361 pstrcpy( save_path, key->name );
363 if ( fetch_reg_keys( key, &ctr) == -1 )
364 return False;
366 ctr_init = True;
368 /* clear the cache when key_index == 0 or the path has changed */
369 else if ( !key_index || StrCaseCmp( save_path, key->name) ) {
371 DEBUG(8,("fetch_reg_keys_specific: Updating cache of subkeys for [%s]\n", key->name));
373 regsubkey_ctr_destroy( &ctr );
374 regsubkey_ctr_init( &ctr );
376 pstrcpy( save_path, key->name );
378 if ( fetch_reg_keys( key, &ctr) == -1 )
379 return False;
382 if ( !(s = regsubkey_ctr_specific_key( &ctr, key_index )) )
383 return False;
385 *subkey = strdup( s );
387 return True;
391 /***********************************************************************
392 High level wrapper function for enumerating registry values
393 Initialize the TALLOC_CTX if necessary
394 ***********************************************************************/
396 int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
398 int result = -1;
400 if ( key->hook && key->hook->ops && key->hook->ops->value_fn )
401 result = key->hook->ops->value_fn( key->name, val );
403 return result;
407 /***********************************************************************
408 retreive a specific subkey specified by index. Caller is
409 responsible for freeing memory
410 ***********************************************************************/
412 BOOL fetch_reg_values_specific( REGISTRY_KEY *key, REGISTRY_VALUE **val, uint32 val_index )
414 static REGVAL_CTR ctr;
415 static pstring save_path;
416 static BOOL ctr_init = False;
417 REGISTRY_VALUE *v;
419 *val = NULL;
421 /* simple caching for performance; very basic heuristic */
423 if ( !ctr_init ) {
424 DEBUG(8,("fetch_reg_values_specific: Initializing cache of values for [%s]\n", key->name));
426 ZERO_STRUCTP( &ctr );
427 regval_ctr_init( &ctr );
429 pstrcpy( save_path, key->name );
431 if ( fetch_reg_values( key, &ctr) == -1 )
432 return False;
434 ctr_init = True;
436 /* clear the cache when val_index == 0 or the path has changed */
437 else if ( !val_index || StrCaseCmp(save_path, key->name) ) {
439 DEBUG(8,("fetch_reg_values_specific: Updating cache of values for [%s]\n", key->name));
441 regval_ctr_destroy( &ctr );
442 regval_ctr_init( &ctr );
444 pstrcpy( save_path, key->name );
446 if ( fetch_reg_values( key, &ctr) == -1 )
447 return False;
450 if ( !(v = regval_ctr_specific_value( &ctr, val_index )) )
451 return False;
453 *val = dup_registry_value( v );
455 return True;
458 /***********************************************************************
459 Utility function for splitting the base path of a registry path off
460 by setting base and new_path to the apprapriate offsets withing the
461 path.
463 WARNING!! Does modify the original string!
464 ***********************************************************************/
466 BOOL reg_split_path( char *path, char **base, char **new_path )
468 char *p;
470 *new_path = *base = NULL;
472 if ( !path)
473 return False;
475 *base = path;
477 p = strchr( path, '\\' );
479 if ( p ) {
480 *p = '\0';
481 *new_path = p+1;
484 return True;