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 ( strequal( ctr
->values
[i
]->valuename
, name
) )
336 return ctr
->values
[i
];
342 /***********************************************************************
343 free memory held by a REGVAL_CTR structure
344 **********************************************************************/
346 void regval_ctr_destroy( REGVAL_CTR
*ctr
)
349 talloc_destroy( ctr
->ctx
);
354 /***********************************************************************
355 Open the registry database and initialize the REGISTRY_HOOK cache
356 ***********************************************************************/
358 BOOL
init_registry( void )
362 if ( !init_registry_db() ) {
363 DEBUG(0,("init_registry: failed to initialize the registry tdb!\n"));
367 /* build the cache tree of registry hooks */
369 reghook_cache_init();
371 for ( i
=0; reg_hooks
[i
].keyname
; i
++ ) {
372 if ( !reghook_cache_add(®_hooks
[i
]) )
376 if ( DEBUGLEVEL
>= 20 )
377 reghook_dump_cache(20);
385 /***********************************************************************
386 High level wrapper function for storing registry subkeys
387 ***********************************************************************/
389 BOOL
store_reg_keys( REGISTRY_KEY
*key
, REGSUBKEY_CTR
*subkeys
)
391 if ( key
->hook
&& key
->hook
->ops
&& key
->hook
->ops
->store_subkeys_fn
)
392 return key
->hook
->ops
->store_subkeys_fn( key
->name
, subkeys
);
398 /***********************************************************************
399 High level wrapper function for storing registry values
400 ***********************************************************************/
402 BOOL
store_reg_values( REGISTRY_KEY
*key
, REGVAL_CTR
*val
)
404 if ( key
->hook
&& key
->hook
->ops
&& key
->hook
->ops
->store_values_fn
)
405 return key
->hook
->ops
->store_values_fn( key
->name
, val
);
411 /***********************************************************************
412 High level wrapper function for enumerating registry subkeys
413 Initialize the TALLOC_CTX if necessary
414 ***********************************************************************/
416 int fetch_reg_keys( REGISTRY_KEY
*key
, REGSUBKEY_CTR
*subkey_ctr
)
420 if ( key
->hook
&& key
->hook
->ops
&& key
->hook
->ops
->subkey_fn
)
421 result
= key
->hook
->ops
->subkey_fn( key
->name
, subkey_ctr
);
426 /***********************************************************************
427 retreive a specific subkey specified by index. Caller is
428 responsible for freeing memory
429 ***********************************************************************/
431 BOOL
fetch_reg_keys_specific( REGISTRY_KEY
*key
, char** subkey
, uint32 key_index
)
433 static REGSUBKEY_CTR ctr
;
434 static pstring save_path
;
435 static BOOL ctr_init
= False
;
440 /* simple caching for performance; very basic heuristic */
443 DEBUG(8,("fetch_reg_keys_specific: Initializing cache of subkeys for [%s]\n", key
->name
));
444 ZERO_STRUCTP( &ctr
);
445 regsubkey_ctr_init( &ctr
);
447 pstrcpy( save_path
, key
->name
);
449 if ( fetch_reg_keys( key
, &ctr
) == -1 )
454 /* clear the cache when key_index == 0 or the path has changed */
455 else if ( !key_index
|| StrCaseCmp( save_path
, key
->name
) ) {
457 DEBUG(8,("fetch_reg_keys_specific: Updating cache of subkeys for [%s]\n", key
->name
));
459 regsubkey_ctr_destroy( &ctr
);
460 regsubkey_ctr_init( &ctr
);
462 pstrcpy( save_path
, key
->name
);
464 if ( fetch_reg_keys( key
, &ctr
) == -1 )
468 if ( !(s
= regsubkey_ctr_specific_key( &ctr
, key_index
)) )
471 *subkey
= strdup( s
);
477 /***********************************************************************
478 High level wrapper function for enumerating registry values
479 Initialize the TALLOC_CTX if necessary
480 ***********************************************************************/
482 int fetch_reg_values( REGISTRY_KEY
*key
, REGVAL_CTR
*val
)
486 if ( key
->hook
&& key
->hook
->ops
&& key
->hook
->ops
->value_fn
)
487 result
= key
->hook
->ops
->value_fn( key
->name
, val
);
493 /***********************************************************************
494 retreive a specific subkey specified by index. Caller is
495 responsible for freeing memory
496 ***********************************************************************/
498 BOOL
fetch_reg_values_specific( REGISTRY_KEY
*key
, REGISTRY_VALUE
**val
, uint32 val_index
)
500 static REGVAL_CTR ctr
;
501 static pstring save_path
;
502 static BOOL ctr_init
= False
;
507 /* simple caching for performance; very basic heuristic */
510 DEBUG(8,("fetch_reg_values_specific: Initializing cache of values for [%s]\n", key
->name
));
512 ZERO_STRUCTP( &ctr
);
513 regval_ctr_init( &ctr
);
515 pstrcpy( save_path
, key
->name
);
517 if ( fetch_reg_values( key
, &ctr
) == -1 )
522 /* clear the cache when val_index == 0 or the path has changed */
523 else if ( !val_index
|| StrCaseCmp(save_path
, key
->name
) ) {
525 DEBUG(8,("fetch_reg_values_specific: Updating cache of values for [%s]\n", key
->name
));
527 regval_ctr_destroy( &ctr
);
528 regval_ctr_init( &ctr
);
530 pstrcpy( save_path
, key
->name
);
532 if ( fetch_reg_values( key
, &ctr
) == -1 )
536 if ( !(v
= regval_ctr_specific_value( &ctr
, val_index
)) )
539 *val
= dup_registry_value( v
);
544 /***********************************************************************
545 Utility function for splitting the base path of a registry path off
546 by setting base and new_path to the apprapriate offsets withing the
549 WARNING!! Does modify the original string!
550 ***********************************************************************/
552 BOOL
reg_split_path( char *path
, char **base
, char **new_path
)
556 *new_path
= *base
= NULL
;
563 p
= strchr( path
, '\\' );