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 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
) )
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
)
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
;
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
*) );
235 ppreg
= talloc_realloc( ctr
->ctx
, ctr
->values
, sizeof(REGISTRY_VALUE
*)*(ctr
->num_values
+1) );
240 /* allocate a new valuie and store the pointer in the arrya */
242 ctr
->values
[ctr
->num_values
] = talloc( ctr
->ctx
, sizeof(REGISTRY_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
;
253 return ctr
->num_values
;
256 /***********************************************************************
257 free memory held by a REGVAL_CTR structure
258 **********************************************************************/
260 void regval_ctr_destroy( REGVAL_CTR
*ctr
)
263 talloc_destroy( ctr
->ctx
);
268 /***********************************************************************
269 Open the registry database and initialize the REGISTRY_HOOK cache
270 ***********************************************************************/
272 BOOL
init_registry( void )
276 if ( !init_registry_db() ) {
277 DEBUG(0,("init_registry: failed to initialize the registry tdb!\n"));
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(®_hooks
[i
]) )
290 if ( DEBUGLEVEL
>= 20 )
291 reghook_dump_cache(20);
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
);
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
);
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
)
334 if ( key
->hook
&& key
->hook
->ops
&& key
->hook
->ops
->subkey_fn
)
335 result
= key
->hook
->ops
->subkey_fn( key
->name
, subkey_ctr
);
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
;
354 /* simple caching for performance; very basic heuristic */
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 )
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 )
382 if ( !(s
= regsubkey_ctr_specific_key( &ctr
, key_index
)) )
385 *subkey
= strdup( s
);
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
)
400 if ( key
->hook
&& key
->hook
->ops
&& key
->hook
->ops
->value_fn
)
401 result
= key
->hook
->ops
->value_fn( key
->name
, val
);
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
;
421 /* simple caching for performance; very basic heuristic */
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 )
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 )
450 if ( !(v
= regval_ctr_specific_value( &ctr
, val_index
)) )
453 *val
= dup_registry_value( v
);
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
463 WARNING!! Does modify the original string!
464 ***********************************************************************/
466 BOOL
reg_split_path( char *path
, char **base
, char **new_path
)
470 *new_path
= *base
= NULL
;
477 p
= strchr( path
, '\\' );