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
28extern REGISTRY_OPS printing_ops;
29extern 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
34REGISTRY_HOOK reg_hooks[] = {
35  { KEY_PRINTING,   &printing_ops },
36  { NULL, NULL }
37};
38
39
40/***********************************************************************
41 Open the registry database and initialize the REGISTRY_HOOK cache
42 ***********************************************************************/
43
44BOOL init_registry( void )
45{
46	int i;
47
48	if ( !init_registry_db() ) {
49		DEBUG(0,("init_registry: failed to initialize the registry tdb!\n"));
50		return False;
51	}
52
53	/* build the cache tree of registry hooks */
54
55	reghook_cache_init();
56
57	for ( i=0; reg_hooks[i].keyname; i++ ) {
58		if ( !reghook_cache_add(&reg_hooks[i]) )
59			return False;
60	}
61
62	if ( DEBUGLEVEL >= 20 )
63		reghook_dump_cache(20);
64
65	return True;
66}
67
68
69
70
71/***********************************************************************
72 High level wrapper function for storing registry subkeys
73 ***********************************************************************/
74
75BOOL store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys )
76{
77	if ( key->hook && key->hook->ops && key->hook->ops->store_subkeys_fn )
78		return key->hook->ops->store_subkeys_fn( key->name, subkeys );
79	else
80		return False;
81
82}
83
84/***********************************************************************
85 High level wrapper function for storing registry values
86 ***********************************************************************/
87
88BOOL store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
89{
90	if ( key->hook && key->hook->ops && key->hook->ops->store_values_fn )
91		return key->hook->ops->store_values_fn( key->name, val );
92	else
93		return False;
94}
95
96
97/***********************************************************************
98 High level wrapper function for enumerating registry subkeys
99 Initialize the TALLOC_CTX if necessary
100 ***********************************************************************/
101
102int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
103{
104	int result = -1;
105
106	if ( key->hook && key->hook->ops && key->hook->ops->subkey_fn )
107		result = key->hook->ops->subkey_fn( key->name, subkey_ctr );
108
109	return result;
110}
111
112/***********************************************************************
113 retreive a specific subkey specified by index.  Caller is
114 responsible for freeing memory
115 ***********************************************************************/
116
117BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index )
118{
119	static REGSUBKEY_CTR ctr;
120	static pstring save_path;
121	static BOOL ctr_init = False;
122	char *s;
123
124	*subkey = NULL;
125
126	/* simple caching for performance; very basic heuristic */
127
128	if ( !ctr_init ) {
129		DEBUG(8,("fetch_reg_keys_specific: Initializing cache of subkeys for [%s]\n", key->name));
130		ZERO_STRUCTP( &ctr );
131		regsubkey_ctr_init( &ctr );
132
133		pstrcpy( save_path, key->name );
134
135		if ( fetch_reg_keys( key, &ctr) == -1 )
136			return False;
137
138		ctr_init = True;
139	}
140	/* clear the cache when key_index == 0 or the path has changed */
141	else if ( !key_index || StrCaseCmp( save_path, key->name) ) {
142
143		DEBUG(8,("fetch_reg_keys_specific: Updating cache of subkeys for [%s]\n", key->name));
144
145		regsubkey_ctr_destroy( &ctr );
146		regsubkey_ctr_init( &ctr );
147
148		pstrcpy( save_path, key->name );
149
150		if ( fetch_reg_keys( key, &ctr) == -1 )
151			return False;
152	}
153
154	if ( !(s = regsubkey_ctr_specific_key( &ctr, key_index )) )
155		return False;
156
157	*subkey = SMB_STRDUP( s );
158
159	return True;
160}
161
162
163/***********************************************************************
164 High level wrapper function for enumerating registry values
165 Initialize the TALLOC_CTX if necessary
166 ***********************************************************************/
167
168int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
169{
170	int result = -1;
171
172	if ( key->hook && key->hook->ops && key->hook->ops->value_fn )
173		result = key->hook->ops->value_fn( key->name, val );
174
175	return result;
176}
177
178
179/***********************************************************************
180 retreive a specific subkey specified by index.  Caller is
181 responsible for freeing memory
182 ***********************************************************************/
183
184BOOL fetch_reg_values_specific( REGISTRY_KEY *key, REGISTRY_VALUE **val, uint32 val_index )
185{
186	static REGVAL_CTR 	ctr;
187	static pstring		save_path;
188	static BOOL		ctr_init = False;
189	REGISTRY_VALUE		*v;
190
191	*val = NULL;
192
193	/* simple caching for performance; very basic heuristic */
194
195	if ( !ctr_init ) {
196		DEBUG(8,("fetch_reg_values_specific: Initializing cache of values for [%s]\n", key->name));
197
198		ZERO_STRUCTP( &ctr );
199		regval_ctr_init( &ctr );
200
201		pstrcpy( save_path, key->name );
202
203		if ( fetch_reg_values( key, &ctr) == -1 )
204			return False;
205
206		ctr_init = True;
207	}
208	/* clear the cache when val_index == 0 or the path has changed */
209	else if ( !val_index || StrCaseCmp(save_path, key->name) ) {
210
211		DEBUG(8,("fetch_reg_values_specific: Updating cache of values for [%s]\n", key->name));
212
213		regval_ctr_destroy( &ctr );
214		regval_ctr_init( &ctr );
215
216		pstrcpy( save_path, key->name );
217
218		if ( fetch_reg_values( key, &ctr) == -1 )
219			return False;
220	}
221
222	if ( !(v = regval_ctr_specific_value( &ctr, val_index )) )
223		return False;
224
225	*val = dup_registry_value( v );
226
227	return True;
228}
229
230/***********************************************************************
231 Utility function for splitting the base path of a registry path off
232 by setting base and new_path to the apprapriate offsets withing the
233 path.
234
235 WARNING!!  Does modify the original string!
236 ***********************************************************************/
237
238BOOL reg_split_path( char *path, char **base, char **new_path )
239{
240	char *p;
241
242	*new_path = *base = NULL;
243
244	if ( !path)
245		return False;
246
247	*base = path;
248
249	p = strchr( path, '\\' );
250
251	if ( p ) {
252		*p = '\0';
253		*new_path = p+1;
254	}
255
256	return True;
257}
258
259
260
261