This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.(This used to...
[sfrench/samba-autobuild/.git] / source3 / registry / reg_frontend.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Gerald Carter                     2002.
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 registry frontend view functions. */
22
23 #include "includes.h"
24
25 #undef DBGC_CLASS
26 #define DBGC_CLASS DBGC_RPC_SRV
27
28 extern REGISTRY_OPS printing_ops;
29 extern REGISTRY_OPS regdb_ops;          /* these are the default */
30
31 /* array of REGISTRY_HOOK's which are read into a tree for easy access */
32
33
34 REGISTRY_HOOK reg_hooks[] = {
35   { KEY_PRINTING,   &printing_ops },
36   { NULL, NULL }
37 };
38
39
40 /*
41  * Utility functions for REGSUBKEY_CTR
42  */
43
44 /***********************************************************************
45  Init the talloc context held by a REGSUBKEY_CTR structure
46  **********************************************************************/
47
48 void regsubkey_ctr_init( REGSUBKEY_CTR *ctr )
49 {
50         if ( !ctr->ctx )
51                 ctr->ctx = talloc_init();
52 }
53
54 /***********************************************************************
55  Add a new key to the array
56  **********************************************************************/
57
58 int regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, char *keyname )
59 {
60         uint32 len;
61         char **pp;
62         
63         if ( keyname )
64         {
65                 len = strlen( keyname );
66
67                 /* allocate a space for the char* in the array */
68                 
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;
75                 }
76
77                 /* allocate the string and save it in the array */
78                 
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++;
82         }
83         
84         return ctr->num_subkeys;
85 }
86  
87 /***********************************************************************
88  How many keys does the container hold ?
89  **********************************************************************/
90
91 int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr )
92 {
93         return ctr->num_subkeys;
94 }
95
96 /***********************************************************************
97  Retreive a specific key string
98  **********************************************************************/
99
100 char* regsubkey_ctr_specific_key( REGSUBKEY_CTR *ctr, uint32 key_index )
101 {
102         if ( ! (key_index < ctr->num_subkeys) )
103                 return NULL;
104                 
105         return ctr->subkeys[key_index];
106 }
107
108 /***********************************************************************
109  free memory held by a REGSUBKEY_CTR structure
110  **********************************************************************/
111
112 void regsubkey_ctr_destroy( REGSUBKEY_CTR *ctr )
113 {
114         if ( ctr ) {
115                 talloc_destroy( ctr->ctx );     
116                 ZERO_STRUCTP( ctr );
117         }
118 }
119
120
121 /*
122  * Utility functions for REGVAL_CTR
123  */
124
125 /***********************************************************************
126  Init the talloc context held by a REGSUBKEY_CTR structure
127  **********************************************************************/
128
129 void regval_ctr_init( REGVAL_CTR *ctr )
130 {
131         if ( !ctr->ctx )
132                 ctr->ctx = talloc_init();
133 }
134
135 /***********************************************************************
136  How many keys does the container hold ?
137  **********************************************************************/
138
139 int regval_ctr_numvals( REGVAL_CTR *ctr )
140 {
141         return ctr->num_values;
142 }
143
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  **********************************************************************/
148
149 REGISTRY_VALUE* dup_registry_value( REGISTRY_VALUE *val )
150 {
151         REGISTRY_VALUE  *copy = NULL;
152         
153         if ( !val )
154                 return NULL;
155         
156         if ( !(copy = malloc( sizeof(REGISTRY_VALUE) )) ) {
157                 DEBUG(0,("dup_registry_value: malloc() failed!\n"));
158                 return NULL;
159         }
160         
161         /* copy all the non-pointer initial data */
162         
163         memcpy( copy, val, sizeof(REGISTRY_VALUE) );
164         if ( val->data_p ) 
165         {
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 );
170                 }
171         }
172         
173         return copy;    
174 }
175
176 /**********************************************************************
177  free the memory allocated to a REGISTRY_VALUE 
178  *********************************************************************/
179  
180 void free_registry_value( REGISTRY_VALUE *val )
181 {
182         if ( !val )
183                 return;
184                 
185         SAFE_FREE( val->data_p );
186         SAFE_FREE( val );
187         
188         return;
189 }
190
191 /**********************************************************************
192  *********************************************************************/
193
194 uint8* regval_data_p( REGISTRY_VALUE *val )
195 {
196         return val->data_p;
197 }
198
199 /**********************************************************************
200  *********************************************************************/
201
202 int regval_size( REGISTRY_VALUE *val )
203 {
204         return val->size;
205 }
206
207 /**********************************************************************
208  *********************************************************************/
209
210 char* regval_name( REGISTRY_VALUE *val )
211 {
212         return val->valuename;
213 }
214
215 /**********************************************************************
216  *********************************************************************/
217
218 uint32 regval_type( REGISTRY_VALUE *val )
219 {
220         return val->type;
221 }
222
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  **********************************************************************/
227
228 REGISTRY_VALUE* regval_ctr_specific_value( REGVAL_CTR *ctr, uint32 idx )
229 {
230         if ( !(idx < ctr->num_values) )
231                 return NULL;
232                 
233         return ctr->values[idx];
234 }
235
236 /***********************************************************************
237  Retrive the TALLOC_CTX associated with a REGISTRY_VALUE 
238  **********************************************************************/
239
240 TALLOC_CTX* regval_ctr_getctx( REGVAL_CTR *val )
241 {
242         if ( !val )
243                 return NULL;
244
245         return val->ctx;
246 }
247
248 /***********************************************************************
249  Add a new registry value to the array
250  **********************************************************************/
251
252 int regval_ctr_addvalue( REGVAL_CTR *ctr, char *name, uint16 type, 
253                          char *data_p, size_t size )
254 {
255         REGISTRY_VALUE **ppreg;
256         uint16 len;
257         
258         if ( name )
259         {
260                 len = strlen( name );
261
262                 /* allocate a slot in the array of pointers */
263                 
264                 if (  ctr->num_values == 0 )
265                         ctr->values = talloc( ctr->ctx, sizeof(REGISTRY_VALUE*) );
266                 else {
267                         ppreg = talloc_realloc( ctr->ctx, ctr->values, sizeof(REGISTRY_VALUE*)*(ctr->num_values+1) );
268                         if ( ppreg )
269                                 ctr->values = ppreg;
270                 }
271
272                 /* allocate a new value and store the pointer in the arrya */
273                 
274                 ctr->values[ctr->num_values] = talloc( ctr->ctx, sizeof(REGISTRY_VALUE) );
275
276                 /* init the value */
277         
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;
282                 ctr->num_values++;
283         }
284
285         return ctr->num_values;
286 }
287
288 /***********************************************************************
289  Delete a single value from the registry container.
290  No need to free memory since it is talloc'd.
291  **********************************************************************/
292
293 int regval_ctr_delvalue( REGVAL_CTR *ctr, char *name )
294 {
295         int     i;
296         
297         /* search for the value */
298         
299         for ( i=0; i<ctr->num_values; i++ ) {
300                 if ( strcmp( ctr->values[i]->valuename, name ) == 0)
301                         break;
302         }
303         
304         /* just return if we don't find it */
305         
306         if ( i == ctr->num_values )
307                 return ctr->num_values;
308         
309         /* just shift everything down one */
310         
311         for ( /* use previous i */; i<(ctr->num_values-1); i++ )
312                 memcpy( ctr->values[i], ctr->values[i+1], sizeof(REGISTRY_VALUE) );
313                 
314         /* paranoia */
315         
316         ZERO_STRUCTP( ctr->values[i] );
317         
318         ctr->num_values--;
319         
320         return ctr->num_values;
321 }
322
323 /***********************************************************************
324  Delete a single value from the registry container.
325  No need to free memory since it is talloc'd.
326  **********************************************************************/
327
328 REGISTRY_VALUE* regval_ctr_getvalue( REGVAL_CTR *ctr, char *name )
329 {
330         int     i;
331         
332         /* search for the value */
333         
334         for ( i=0; i<ctr->num_values; i++ ) {
335                 if ( strcmp( ctr->values[i]->valuename, name ) == 0)
336                         return ctr->values[i];
337                 
338         }
339         
340         return NULL;
341 }
342
343 /***********************************************************************
344  free memory held by a REGVAL_CTR structure
345  **********************************************************************/
346
347 void regval_ctr_destroy( REGVAL_CTR *ctr )
348 {
349         if ( ctr ) {
350                 talloc_destroy( ctr->ctx );
351                 ZERO_STRUCTP( ctr );
352         }
353 }
354
355 /***********************************************************************
356  Open the registry database and initialize the REGISTRY_HOOK cache
357  ***********************************************************************/
358  
359 BOOL init_registry( void )
360 {
361         int i;
362         
363         if ( !init_registry_db() ) {
364                 DEBUG(0,("init_registry: failed to initialize the registry tdb!\n"));
365                 return False;
366         }
367                 
368         /* build the cache tree of registry hooks */
369         
370         reghook_cache_init();
371         
372         for ( i=0; reg_hooks[i].keyname; i++ ) {
373                 if ( !reghook_cache_add(&reg_hooks[i]) )
374                         return False;
375         }
376
377         if ( DEBUGLEVEL >= 20 )
378                 reghook_dump_cache(20);
379
380         return True;
381 }
382
383
384
385
386 /***********************************************************************
387  High level wrapper function for storing registry subkeys
388  ***********************************************************************/
389  
390 BOOL store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys )
391 {
392         if ( key->hook && key->hook->ops && key->hook->ops->store_subkeys_fn )
393                 return key->hook->ops->store_subkeys_fn( key->name, subkeys );
394         else
395                 return False;
396
397 }
398
399 /***********************************************************************
400  High level wrapper function for storing registry values
401  ***********************************************************************/
402  
403 BOOL store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
404 {
405         if ( key->hook && key->hook->ops && key->hook->ops->store_values_fn )
406                 return key->hook->ops->store_values_fn( key->name, val );
407         else
408                 return False;
409 }
410
411
412 /***********************************************************************
413  High level wrapper function for enumerating registry subkeys
414  Initialize the TALLOC_CTX if necessary
415  ***********************************************************************/
416
417 int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
418 {
419         int result = -1;
420         
421         if ( key->hook && key->hook->ops && key->hook->ops->subkey_fn )
422                 result = key->hook->ops->subkey_fn( key->name, subkey_ctr );
423
424         return result;
425 }
426
427 /***********************************************************************
428  retreive a specific subkey specified by index.  Caller is 
429  responsible for freeing memory
430  ***********************************************************************/
431
432 BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index )
433 {
434         static REGSUBKEY_CTR ctr;
435         static pstring save_path;
436         static BOOL ctr_init = False;
437         char *s;
438         
439         *subkey = NULL;
440         
441         /* simple caching for performance; very basic heuristic */
442         
443         if ( !ctr_init ) {
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 );
447                 
448                 pstrcpy( save_path, key->name );
449                 
450                 if ( fetch_reg_keys( key, &ctr) == -1 )
451                         return False;
452                         
453                 ctr_init = True;
454         }
455         /* clear the cache when key_index == 0 or the path has changed */
456         else if ( !key_index || StrCaseCmp( save_path, key->name) ) {
457
458                 DEBUG(8,("fetch_reg_keys_specific: Updating cache of subkeys for [%s]\n", key->name));
459                 
460                 regsubkey_ctr_destroy( &ctr );  
461                 regsubkey_ctr_init( &ctr );
462                 
463                 pstrcpy( save_path, key->name );
464                 
465                 if ( fetch_reg_keys( key, &ctr) == -1 )
466                         return False;
467         }
468         
469         if ( !(s = regsubkey_ctr_specific_key( &ctr, key_index )) )
470                 return False;
471
472         *subkey = strdup( s );
473
474         return True;
475 }
476
477
478 /***********************************************************************
479  High level wrapper function for enumerating registry values
480  Initialize the TALLOC_CTX if necessary
481  ***********************************************************************/
482
483 int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
484 {
485         int result = -1;
486         
487         if ( key->hook && key->hook->ops && key->hook->ops->value_fn )
488                 result = key->hook->ops->value_fn( key->name, val );
489
490         return result;
491 }
492
493
494 /***********************************************************************
495  retreive a specific subkey specified by index.  Caller is 
496  responsible for freeing memory
497  ***********************************************************************/
498
499 BOOL fetch_reg_values_specific( REGISTRY_KEY *key, REGISTRY_VALUE **val, uint32 val_index )
500 {
501         static REGVAL_CTR       ctr;
502         static pstring          save_path;
503         static BOOL             ctr_init = False;
504         REGISTRY_VALUE          *v;
505         
506         *val = NULL;
507         
508         /* simple caching for performance; very basic heuristic */
509         
510         if ( !ctr_init ) {
511                 DEBUG(8,("fetch_reg_values_specific: Initializing cache of values for [%s]\n", key->name));
512
513                 ZERO_STRUCTP( &ctr );   
514                 regval_ctr_init( &ctr );
515                 
516                 pstrcpy( save_path, key->name );
517                 
518                 if ( fetch_reg_values( key, &ctr) == -1 )
519                         return False;
520                         
521                 ctr_init = True;
522         }
523         /* clear the cache when val_index == 0 or the path has changed */
524         else if ( !val_index || StrCaseCmp(save_path, key->name) ) {
525
526                 DEBUG(8,("fetch_reg_values_specific: Updating cache of values for [%s]\n", key->name));         
527                 
528                 regval_ctr_destroy( &ctr );     
529                 regval_ctr_init( &ctr );
530                 
531                 pstrcpy( save_path, key->name );
532                 
533                 if ( fetch_reg_values( key, &ctr) == -1 )
534                         return False;
535         }
536         
537         if ( !(v = regval_ctr_specific_value( &ctr, val_index )) )
538                 return False;
539
540         *val = dup_registry_value( v );
541
542         return True;
543 }
544
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
548  path.
549  
550  WARNING!!  Does modify the original string!
551  ***********************************************************************/
552
553 BOOL reg_split_path( char *path, char **base, char **new_path )
554 {
555         char *p;
556         
557         *new_path = *base = NULL;
558         
559         if ( !path)
560                 return False;
561         
562         *base = path;
563         
564         p = strchr( path, '\\' );
565         
566         if ( p ) {
567                 *p = '\0';
568                 *new_path = p+1;
569         }
570         
571         return True;
572 }
573
574
575