r6680: event log patches from Marcin
[ira/wip.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         regsubkey_ctr_addkey( &subkeys, "SOFTWARE" ); 
48         if ( !regdb_store_reg_keys( keyname, &subkeys ))
49                 return False;
50         regsubkey_ctr_destroy( &subkeys );
51
52
53         regsubkey_ctr_init( &subkeys );
54         pstrcpy( keyname, KEY_HKLM );
55         pstrcat( keyname, "/SOFTWARE" );
56         regsubkey_ctr_addkey( &subkeys, "Microsoft" );
57         if ( !regdb_store_reg_keys( keyname, &subkeys ))
58                 return False;
59         regsubkey_ctr_destroy( &subkeys );
60
61         regsubkey_ctr_init( &subkeys );
62         pstrcpy( keyname, KEY_HKLM );
63         pstrcat( keyname, "/SOFTWARE/Microsoft" );
64         regsubkey_ctr_addkey( &subkeys, "Windows NT" );
65         if ( !regdb_store_reg_keys( keyname, &subkeys ))
66                 return False;
67         regsubkey_ctr_destroy( &subkeys );
68
69         regsubkey_ctr_init( &subkeys );
70         pstrcpy( keyname, KEY_HKLM );
71         pstrcat( keyname, "/SOFTWARE/Microsoft/Windows NT" );
72         regsubkey_ctr_addkey( &subkeys, "CurrentVersion" );
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, "/SOFTWARE/Microsoft/Windows NT/CurrentVersion" );
79         if ( !regdb_store_reg_keys( keyname, &subkeys ))
80                 return False;
81
82
83         regsubkey_ctr_init( &subkeys );
84         pstrcpy( keyname, KEY_HKLM );
85         pstrcat( keyname, "/SOFTWARE/Microsoft/Windows NT/CurrentVersion" );
86         regsubkey_ctr_addkey( &subkeys, "SystemRoot" );
87         if ( !regdb_store_reg_keys( keyname, &subkeys ))
88                 return False;
89         regsubkey_ctr_destroy( &subkeys );
90
91         pstrcpy( keyname, KEY_HKLM );
92         pstrcat( keyname, "/SOFTWARE/Microsoft/Windows NT/CurrentVersion/SystemRoot" );
93         if ( !regdb_store_reg_keys( keyname, &subkeys ))
94                 return False;
95
96
97         regsubkey_ctr_init( &subkeys );
98         pstrcpy( keyname, KEY_HKLM );
99         pstrcat( keyname, "/SYSTEM" );
100         regsubkey_ctr_addkey( &subkeys, "CurrentControlSet" );
101         if ( !regdb_store_reg_keys( keyname, &subkeys ))
102                 return False;
103         regsubkey_ctr_destroy( &subkeys );
104                 
105         regsubkey_ctr_init( &subkeys );
106         pstrcpy( keyname, KEY_HKLM );
107         pstrcat( keyname, "/SYSTEM/CurrentControlSet" );
108         regsubkey_ctr_addkey( &subkeys, "Control" );
109         regsubkey_ctr_addkey( &subkeys, "Services" );
110         if ( !regdb_store_reg_keys( keyname, &subkeys ))
111                 return False;
112         regsubkey_ctr_destroy( &subkeys );
113
114         regsubkey_ctr_init( &subkeys );
115         pstrcpy( keyname, KEY_HKLM );
116         pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control" );
117         regsubkey_ctr_addkey( &subkeys, "Print" );
118         regsubkey_ctr_addkey( &subkeys, "ProductOptions" );
119         if ( !regdb_store_reg_keys( keyname, &subkeys ))
120                 return False;
121         regsubkey_ctr_destroy( &subkeys );
122
123         regsubkey_ctr_init( &subkeys ); 
124         pstrcpy( keyname, KEY_HKLM );
125         pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control/ProductOptions" );
126         if ( !regdb_store_reg_keys( keyname, &subkeys ))
127                 return False;
128         regsubkey_ctr_destroy( &subkeys ); /* added */
129
130         /* ProductType is a VALUE under ProductOptions */
131
132         regsubkey_ctr_init( &subkeys );
133         pstrcpy( keyname, KEY_HKLM );
134         pstrcat( keyname, "/SYSTEM/CurrentControlSet/Services" );
135         regsubkey_ctr_addkey( &subkeys, "Netlogon" );
136         regsubkey_ctr_addkey( &subkeys, "Tcpip" );
137         regsubkey_ctr_addkey( &subkeys, "Eventlog" ); 
138
139         if ( !regdb_store_reg_keys( keyname, &subkeys ))
140                 return False;
141         regsubkey_ctr_destroy( &subkeys );
142                 
143         regsubkey_ctr_init( &subkeys );
144         pstrcpy( keyname, KEY_HKLM );
145         pstrcat( keyname, "/SYSTEM/CurrentControlSet/Services/Netlogon" );
146         regsubkey_ctr_addkey( &subkeys, "Parameters" );
147         if ( !regdb_store_reg_keys( keyname, &subkeys ))
148                 return False;
149         regsubkey_ctr_destroy( &subkeys );
150
151         pstrcpy( keyname, KEY_HKLM );
152         pstrcat( keyname, "/SYSTEM/CurrentControlSet/Services/Netlogon/Parameters" );
153         if ( !regdb_store_reg_keys( keyname, &subkeys ))
154                 return False;
155
156         regsubkey_ctr_init( &subkeys ); /*added */
157         pstrcpy( keyname, KEY_HKLM );  /*added */
158         pstrcat( keyname, "/SYSTEM/CurrentControlSet/Services/Tcpip" ); 
159         regsubkey_ctr_addkey( &subkeys, "Parameters" );  
160         if ( !regdb_store_reg_keys( keyname, &subkeys )) 
161                 return False; 
162         regsubkey_ctr_destroy( &subkeys ); 
163                 
164         pstrcpy( keyname, KEY_HKLM );
165         pstrcat( keyname, "/SYSTEM/CurrentControlSet/Services/Tcpip/Parameters" );
166         if ( !regdb_store_reg_keys( keyname, &subkeys )) 
167                 return False;
168
169         pstrcpy( keyname, KEY_HKLM ); 
170         pstrcat( keyname, "/SYSTEM/CurrentControlSet/Services/Eventlog" ); 
171         if ( !regdb_store_reg_keys( keyname, &subkeys )) 
172                 return False; 
173         
174         /* HKEY_USER */
175                 
176         pstrcpy( keyname, KEY_HKU );
177         if ( !regdb_store_reg_keys( keyname, &subkeys ) )
178                 return False;
179                 
180         /* HKEY_CLASSES_ROOT*/
181                 
182         pstrcpy( keyname, KEY_HKCR );
183         if ( !regdb_store_reg_keys( keyname, &subkeys ) )
184                 return False;
185                 
186         return True;
187 }
188
189 /***********************************************************************
190  Open the registry database
191  ***********************************************************************/
192  
193 BOOL init_registry_db( void )
194 {
195         static pid_t local_pid;
196
197         if (tdb_reg && local_pid == sys_getpid())
198                 return True;
199
200         /* 
201          * try to open first without creating so we can determine
202          * if we need to init the data in the registry
203          */
204         
205         tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600);
206         if ( !tdb_reg ) 
207         {
208                 tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
209                 if ( !tdb_reg ) {
210                         DEBUG(0,("init_registry: Failed to open registry %s (%s)\n",
211                                 lock_path("registry.tdb"), strerror(errno) ));
212                         return False;
213                 }
214                 
215                 DEBUG(10,("init_registry: Successfully created registry tdb\n"));
216                 
217                 /* create the registry here */
218                 if ( !init_registry_data() ) {
219                         DEBUG(0,("init_registry: Failed to initiailize data in registry!\n"));
220                         return False;
221                 }
222         }
223
224         local_pid = sys_getpid();
225                 
226         return True;
227 }
228
229
230
231 /***********************************************************************
232  Add subkey strings to the registry tdb under a defined key
233  fmt is the same format as tdb_pack except this function only supports
234  fstrings
235
236  The full path to the registry key is used as database after the 
237  \'s are converted to /'s.  Key string is also normalized to UPPER
238  case.
239  ***********************************************************************/
240  
241 BOOL regdb_store_reg_keys( char *keyname, REGSUBKEY_CTR *ctr )
242 {
243         TDB_DATA kbuf, dbuf;
244         char *buffer, *tmpbuf;
245         int i = 0;
246         uint32 len, buflen;
247         BOOL ret = True;
248         uint32 num_subkeys = regsubkey_ctr_numkeys( ctr );
249         
250         if ( !keyname )
251                 return False;
252         
253         strupper_m( keyname  );
254         
255         /* allocate some initial memory */
256                 
257         buffer = SMB_MALLOC(sizeof(pstring));
258         buflen = sizeof(pstring);
259         len = 0;
260         
261         /* store the number of subkeys */
262         
263         len += tdb_pack(buffer+len, buflen-len, "d", num_subkeys );
264         
265         /* pack all the strings */
266         
267         for (i=0; i<num_subkeys; i++) {
268                 len += tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) );
269                 if ( len > buflen ) {
270                         /* allocate some extra space */
271                         if ((tmpbuf = SMB_REALLOC( buffer, len*2 )) == NULL) {
272                                 DEBUG(0,("regdb_store_reg_keys: Failed to realloc memory of size [%d]\n", len*2));
273                                 ret = False;
274                                 goto done;
275                         }
276                         buffer = tmpbuf;
277                         buflen = len*2;
278                                         
279                         len = tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) );
280                 }               
281         }
282         
283         /* finally write out the data */
284         
285         kbuf.dptr = keyname;
286         kbuf.dsize = strlen(keyname)+1;
287         dbuf.dptr = buffer;
288         dbuf.dsize = len;
289         if ( tdb_store( tdb_reg, kbuf, dbuf, TDB_REPLACE ) == -1) {
290                 ret = False;
291                 goto done;
292         }
293
294 done:           
295         SAFE_FREE( buffer );
296         
297         return ret;
298 }
299
300 /***********************************************************************
301  Retrieve an array of strings containing subkeys.  Memory should be 
302  released by the caller.  The subkeys are stored in a catenated string
303  of null terminated character strings
304  ***********************************************************************/
305
306 int regdb_fetch_reg_keys( char* key, REGSUBKEY_CTR *ctr )
307 {
308         pstring path;
309         uint32 num_items;
310         TDB_DATA dbuf;
311         char *buf;
312         uint32 buflen, len;
313         int i;
314         fstring subkeyname;
315
316         DEBUG(10,("regdb_fetch_reg_keys: Enter key => [%s]\n", key ? key : "NULL"));
317         
318         pstrcpy( path, key );
319         
320         /* convert to key format */
321         pstring_sub( path, "\\", "/" ); 
322         strupper_m( path );
323         
324         dbuf = tdb_fetch_bystring( tdb_reg, path );
325         
326         buf = dbuf.dptr;
327         buflen = dbuf.dsize;
328         
329         if ( !buf ) {
330                 DEBUG(5,("regdb_fetch_reg_keys: tdb lookup failed to locate key [%s]\n", key));
331                 return -1;
332         }
333         
334         len = tdb_unpack( buf, buflen, "d", &num_items);
335         
336         for (i=0; i<num_items; i++) {
337                 len += tdb_unpack( buf+len, buflen-len, "f", subkeyname );
338                 regsubkey_ctr_addkey( ctr, subkeyname );
339         }
340
341         SAFE_FREE( dbuf.dptr );
342         
343         DEBUG(10,("regdb_fetch_reg_keys: Exit [%d] items\n", num_items));
344         
345         return num_items;
346 }
347
348
349 /***********************************************************************
350  Retrieve an array of strings containing subkeys.  Memory should be 
351  released by the caller.  The subkeys are stored in a catenated string
352  of null terminated character strings
353  ***********************************************************************/
354
355 int regdb_fetch_reg_values( char* key, REGVAL_CTR *val )
356 {
357         UNISTR2 data;
358         int    num_vals;
359         char   *hname;
360         fstring mydomainname;
361
362         DEBUG(10,("regdb_fetch_reg_values: Looking for value of key [%s] \n", key));
363
364         num_vals = 0;
365
366         if ( strequal(key, "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion" ) ) {
367                 DEBUG(10,("regdb_fetch_reg_values: Supplying SystemRoot \n"));
368                 init_unistr2( &data, "c:\\Windows", UNI_STR_TERMINATE);
369                 regval_ctr_addvalue( val, "SystemRoot",REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
370                 num_vals = 1;
371         } else if ( strequal(key, "HKLM\\System\\CurrentControlSet\\Control\\ProductOptions" ) ) {
372                 DEBUG(10,("regdb_fetch_reg_values: Supplying ProductType \n"));
373                 init_unistr2( &data, "WinNT", UNI_STR_TERMINATE);
374                 regval_ctr_addvalue( val, "ProductType",REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
375                 num_vals = 1;
376         } else if ( strequal(key, "HKLM\\System\\CurrentControlSet\\Services\\Tcpip\\Parameters" ) ) {
377                 DEBUG(10,("regdb_fetch_reg_values: Supplying Hostname & Domain Name\n"));
378                 hname = SMB_STRDUP(myhostname());
379                 get_mydnsdomname(mydomainname);
380                 init_unistr2( &data, hname, UNI_STR_TERMINATE);
381                 regval_ctr_addvalue( val, "Hostname",REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
382                 init_unistr2( &data, mydomainname, UNI_STR_TERMINATE);
383                 regval_ctr_addvalue( val, "Domain",REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
384                 num_vals = 2;
385         }
386
387
388
389         return num_vals;
390 }
391
392 /***********************************************************************
393  Stub function since we do not currently support storing registry 
394  values in the registry.tdb
395  ***********************************************************************/
396
397 BOOL regdb_store_reg_values( char *key, REGVAL_CTR *val )
398 {
399         return False;
400 }
401
402
403 /* 
404  * Table of function pointers for default access
405  */
406  
407 REGISTRY_OPS regdb_ops = {
408         regdb_fetch_reg_keys,
409         regdb_fetch_reg_values,
410         regdb_store_reg_keys,
411         regdb_store_reg_values
412 };
413
414