* fix return code so we don't let a client just open any key it wants
[kai/samba.git] / source3 / registry / reg_db.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 internal registry database functions. */
22
23 #include "includes.h"
24
25 #undef DBGC_CLASS
26 #define DBGC_CLASS DBGC_RPC_SRV
27
28 static TDB_CONTEXT *tdb_reg;
29
30
31 /***********************************************************************
32  Open the registry data in the tdb
33  ***********************************************************************/
34  
35 static BOOL init_registry_data( void )
36 {
37         pstring         keyname;
38         REGSUBKEY_CTR   subkeys;
39
40         ZERO_STRUCTP( &subkeys );
41
42         /* HKEY_LOCAL_MACHINE */
43         
44         regsubkey_ctr_init( &subkeys );
45         pstrcpy( keyname, KEY_HKLM );
46         regsubkey_ctr_addkey( &subkeys, "SYSTEM" );
47         if ( !regdb_store_reg_keys( keyname, &subkeys ))
48                 return False;
49         regsubkey_ctr_destroy( &subkeys );
50                 
51         regsubkey_ctr_init( &subkeys );
52         pstrcpy( keyname, KEY_HKLM );
53         pstrcat( keyname, "/SYSTEM" );
54         regsubkey_ctr_addkey( &subkeys, "CurrentControlSet" );
55         if ( !regdb_store_reg_keys( keyname, &subkeys ))
56                 return False;
57         regsubkey_ctr_destroy( &subkeys );
58                 
59         regsubkey_ctr_init( &subkeys );
60         pstrcpy( keyname, KEY_HKLM );
61         pstrcat( keyname, "/SYSTEM/CurrentControlSet" );
62         regsubkey_ctr_addkey( &subkeys, "Control" );
63         regsubkey_ctr_addkey( &subkeys, "services" );
64         if ( !regdb_store_reg_keys( keyname, &subkeys ))
65                 return False;
66         regsubkey_ctr_destroy( &subkeys );
67
68         regsubkey_ctr_init( &subkeys );
69         pstrcpy( keyname, KEY_HKLM );
70         pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control" );
71         regsubkey_ctr_addkey( &subkeys, "Print" );
72         regsubkey_ctr_addkey( &subkeys, "ProductOptions" );
73         if ( !regdb_store_reg_keys( keyname, &subkeys ))
74                 return False;
75         regsubkey_ctr_destroy( &subkeys );
76
77         pstrcpy( keyname, KEY_HKLM );
78         pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control/ProductOptions" );
79         if ( !regdb_store_reg_keys( keyname, &subkeys ))
80                 return False;
81
82         regsubkey_ctr_init( &subkeys );
83         pstrcpy( keyname, KEY_HKLM );
84         pstrcat( keyname, "/SYSTEM/CurrentControlSet/services" );
85         regsubkey_ctr_addkey( &subkeys, "Netlogon" );
86         if ( !regdb_store_reg_keys( keyname, &subkeys ))
87                 return False;
88         regsubkey_ctr_destroy( &subkeys );
89                 
90         regsubkey_ctr_init( &subkeys );
91         pstrcpy( keyname, KEY_HKLM );
92         pstrcat( keyname, "/SYSTEM/CurrentControlSet/services/Netlogon" );
93         regsubkey_ctr_addkey( &subkeys, "parameters" );
94         if ( !regdb_store_reg_keys( keyname, &subkeys ))
95                 return False;
96         regsubkey_ctr_destroy( &subkeys );
97                 
98         pstrcpy( keyname, KEY_HKLM );
99         pstrcat( keyname, "/SYSTEM/CurrentControlSet/services/Netlogon/parameters" );
100         if ( !regdb_store_reg_keys( keyname, &subkeys ))
101                 return False;
102         
103         /* HKEY_USER */
104                 
105         pstrcpy( keyname, KEY_HKU );
106         if ( !regdb_store_reg_keys( keyname, &subkeys ) )
107                 return False;
108                 
109         /* HKEY_CLASSES_ROOT*/
110                 
111         pstrcpy( keyname, KEY_HKCR );
112         if ( !regdb_store_reg_keys( keyname, &subkeys ) )
113                 return False;
114                 
115         return True;
116 }
117
118 /***********************************************************************
119  Open the registry database
120  ***********************************************************************/
121  
122 BOOL init_registry_db( void )
123 {
124         static pid_t local_pid;
125
126         if (tdb_reg && local_pid == sys_getpid())
127                 return True;
128
129         /* 
130          * try to open first without creating so we can determine
131          * if we need to init the data in the registry
132          */
133         
134         tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600);
135         if ( !tdb_reg ) 
136         {
137                 tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
138                 if ( !tdb_reg ) {
139                         DEBUG(0,("init_registry: Failed to open registry %s (%s)\n",
140                                 lock_path("registry.tdb"), strerror(errno) ));
141                         return False;
142                 }
143                 
144                 DEBUG(10,("init_registry: Successfully created registry tdb\n"));
145                 
146                 /* create the registry here */
147                 if ( !init_registry_data() ) {
148                         DEBUG(0,("init_registry: Failed to initiailize data in registry!\n"));
149                         return False;
150                 }
151         }
152
153         local_pid = sys_getpid();
154                 
155         return True;
156 }
157
158
159
160 /***********************************************************************
161  Add subkey strings to the registry tdb under a defined key
162  fmt is the same format as tdb_pack except this function only supports
163  fstrings
164
165  The full path to the registry key is used as database after the 
166  \'s are converted to /'s.
167  ***********************************************************************/
168  
169 BOOL regdb_store_reg_keys( char *keyname, REGSUBKEY_CTR *ctr )
170 {
171         TDB_DATA kbuf, dbuf;
172         char *buffer, *tmpbuf;
173         int i = 0;
174         uint32 len, buflen;
175         BOOL ret = True;
176         uint32 num_subkeys = regsubkey_ctr_numkeys( ctr );
177         
178         if ( !keyname )
179                 return False;
180         
181         /* allocate some initial memory */
182                 
183         buffer = malloc(sizeof(pstring));
184         buflen = sizeof(pstring);
185         len = 0;
186         
187         /* store the number of subkeys */
188         
189         len += tdb_pack(buffer+len, buflen-len, "d", num_subkeys );
190         
191         /* pack all the strings */
192         
193         for (i=0; i<num_subkeys; i++) {
194                 len += tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) );
195                 if ( len > buflen ) {
196                         /* allocate some extra space */
197                         if ((tmpbuf = Realloc( buffer, len*2 )) == NULL) {
198                                 DEBUG(0,("regdb_store_reg_keys: Failed to realloc memory of size [%d]\n", len*2));
199                                 ret = False;
200                                 goto done;
201                         }
202                         buffer = tmpbuf;
203                         buflen = len*2;
204                                         
205                         len = tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) );
206                 }               
207         }
208         
209         /* finally write out the data */
210         
211         kbuf.dptr = keyname;
212         kbuf.dsize = strlen(keyname)+1;
213         dbuf.dptr = buffer;
214         dbuf.dsize = len;
215         if ( tdb_store( tdb_reg, kbuf, dbuf, TDB_REPLACE ) == -1) {
216                 ret = False;
217                 goto done;
218         }
219
220 done:           
221         SAFE_FREE( buffer );
222         
223         return ret;
224 }
225
226 /***********************************************************************
227  Retrieve an array of strings containing subkeys.  Memory should be 
228  released by the caller.  The subkeys are stored in a catenated string
229  of null terminated character strings
230  ***********************************************************************/
231
232 int regdb_fetch_reg_keys( char* key, REGSUBKEY_CTR *ctr )
233 {
234         pstring path;
235         uint32 num_items;
236         TDB_DATA dbuf;
237         char *buf;
238         uint32 buflen, len;
239         int i;
240         fstring subkeyname;
241
242         DEBUG(10,("regdb_fetch_reg_keys: Enter key => [%s]\n", key ? key : "NULL"));
243         
244         pstrcpy( path, key );
245         
246         /* convert to key format */
247         pstring_sub( path, "\\", "/" ); 
248         
249         dbuf = tdb_fetch_by_string( tdb_reg, path );
250         
251         buf = dbuf.dptr;
252         buflen = dbuf.dsize;
253         
254         if ( !buf ) {
255                 DEBUG(5,("regdb_fetch_reg_keys: tdb lookup failed to locate key [%s]\n", key));
256                 return -1;
257         }
258         
259         len = tdb_unpack( buf, buflen, "d", &num_items);
260         
261         for (i=0; i<num_items; i++) {
262                 len += tdb_unpack( buf+len, buflen-len, "f", subkeyname );
263                 regsubkey_ctr_addkey( ctr, subkeyname );
264         }
265
266         SAFE_FREE( dbuf.dptr );
267         
268         DEBUG(10,("regdb_fetch_reg_keys: Exit [%d] items\n", num_items));
269         
270         return num_items;
271 }
272
273
274 /***********************************************************************
275  Retrieve an array of strings containing subkeys.  Memory should be 
276  released by the caller.  The subkeys are stored in a catenated string
277  of null terminated character strings
278  ***********************************************************************/
279
280 int regdb_fetch_reg_values( char* key, REGVAL_CTR *val )
281 {
282         return 0;
283 }
284
285 /***********************************************************************
286  Stub function since we do not currently support storing registry 
287  values in the registry.tdb
288  ***********************************************************************/
289
290 BOOL regdb_store_reg_values( char *key, REGVAL_CTR *val )
291 {
292         return False;
293 }
294
295
296 /* 
297  * Table of function pointers for default access
298  */
299  
300 REGISTRY_OPS regdb_ops = {
301         regdb_fetch_reg_keys,
302         regdb_fetch_reg_values,
303         regdb_store_reg_keys,
304         regdb_store_reg_values
305 };
306
307