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