r10656: BIG merge from trunk. Features not copied over
[vlendec/samba-autobuild/.git] / source3 / registry / reg_db.c
index ce9d68a26431af9e4ed709cdd6c55760d1169556..ab8fc14d909cd04c7787551749980f04881df763 100644 (file)
@@ -31,7 +31,7 @@ static TDB_CONTEXT *tdb_reg;
 
 /* List the deepest path into the registry.  All part components will be created.*/
 
-/* If you want to have a part of the path controlled by the tdb abd part by
+/* If you want to have a part of the path controlled by the tdb and part by
    a virtual registry db (e.g. printing), then you have to list the deepest path.
    For example,"HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Print" 
    allows the reg_db backend to handle everything up to 
@@ -40,16 +40,22 @@ static TDB_CONTEXT *tdb_reg;
    KEY_PRINTING_2K in include/rpc_reg.h)   --jerry */
 
 static const char *builtin_registry_paths[] = {
-       "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print",
-       "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Ports",
-       "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print",
+       KEY_PRINTING_2K,
+       KEY_PRINTING_PORTS,
+       KEY_PRINTING,
+       KEY_SHARES,
+       KEY_EVENTLOG,
+       "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib",
+       "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009",
+       "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors",
        "HKLM\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
-       "HKLM\\SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Shares",
-       "HKLM\\SYSTEM\\CurrentControlSet\\Services\\EventLog",
+       "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration",
        "HKLM\\SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters",
        "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Netlogon\\Parameters",
        "HKU",
        "HKCR",
+       "HKPD",
+       "HKPT",
         NULL };
 
 struct builtin_regkey_value {
@@ -63,7 +69,14 @@ struct builtin_regkey_value {
 };
 
 static struct builtin_regkey_value builtin_registry_values[] = {
-       { "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",      "SystemRoot",   REG_SZ,         { "c:\\Windows" } },
+       { KEY_PRINTING_PORTS,
+               SAMBA_PRINTER_PORT_NAME, REG_SZ, { "" } },
+       { KEY_PRINTING_2K,
+               "DefaultSpoolDirectory", REG_SZ, { "C:\\Windows\\System32\\Spool\\Printers" } },
+       { KEY_EVENTLOG,
+               "DisplayName", REG_SZ, { "Event Log" } }, 
+       { KEY_EVENTLOG,
+               "ErrorControl", REG_DWORD, { (char*)0x00000001 } },
        { NULL, NULL, 0, { NULL } }
 };
 
@@ -77,8 +90,8 @@ static BOOL init_registry_data( void )
 {
        pstring path, base, remaining;
        fstring keyname, subkeyname;
-       REGSUBKEY_CTR   subkeys;
-       REGVAL_CTR values;
+       REGSUBKEY_CTR *subkeys;
+       REGVAL_CTR *values;
        int i;
        const char *p, *p2;
        UNISTR2 data;
@@ -119,27 +132,38 @@ static BOOL init_registry_data( void )
                           we are about to update the record.  We just want any 
                           subkeys already present */
                        
-                       regsubkey_ctr_init( &subkeys );
-                                                  
-                       regdb_fetch_keys( base, &subkeys );
+                       if ( !(subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) ) {
+                               DEBUG(0,("talloc() failure!\n"));
+                               return False;
+                       }
+
+                       regdb_fetch_keys( base, subkeys );
                        if ( *subkeyname ) 
-                               regsubkey_ctr_addkey( &subkeys, subkeyname );
-                       if ( !regdb_store_keys( base, &subkeys ))
+                               regsubkey_ctr_addkey( subkeys, subkeyname );
+                       if ( !regdb_store_keys( base, subkeys ))
                                return False;
                        
-                       regsubkey_ctr_destroy( &subkeys );
+                       TALLOC_FREE( subkeys );
                }
        }
 
        /* loop over all of the predefined values and add each component */
        
        for ( i=0; builtin_registry_values[i].path != NULL; i++ ) {
-               regval_ctr_init( &values );
-               
-               regdb_fetch_values( builtin_registry_values[i].path, &values );
-               switch( builtin_registry_values[i].type ) {
+               if ( !(values = TALLOC_ZERO_P( NULL, REGVAL_CTR )) ) {
+                       DEBUG(0,("talloc() failure!\n"));
+                       return False;
+               }
+
+               regdb_fetch_values( builtin_registry_values[i].path, values );
+
+               /* preserve existing values across restarts.  Only add new ones */
+
+               if ( !regval_ctr_key_exists( values, builtin_registry_values[i].valuename ) ) 
+               {
+                       switch( builtin_registry_values[i].type ) {
                        case REG_DWORD:
-                               regval_ctr_addvalue( &values, 
+                               regval_ctr_addvalue( values, 
                                                     builtin_registry_values[i].valuename,
                                                     REG_DWORD,
                                                     (char*)&builtin_registry_values[i].data.dw_value,
@@ -148,7 +172,7 @@ static BOOL init_registry_data( void )
                                
                        case REG_SZ:
                                init_unistr2( &data, builtin_registry_values[i].data.string, UNI_STR_TERMINATE);
-                               regval_ctr_addvalue( &values, 
+                               regval_ctr_addvalue( values, 
                                                     builtin_registry_values[i].valuename,
                                                     REG_SZ,
                                                     (char*)data.buffer,
@@ -158,10 +182,11 @@ static BOOL init_registry_data( void )
                        default:
                                DEBUG(0,("init_registry_data: invalid value type in builtin_registry_values [%d]\n",
                                        builtin_registry_values[i].type));
+                       }
+                       regdb_store_values( builtin_registry_values[i].path, values );
                }
-               regdb_store_values( builtin_registry_values[i].path, &values );
                
-               regval_ctr_destroy( &values );
+               TALLOC_FREE( values );
        }
        
        return True;
@@ -179,8 +204,6 @@ BOOL init_registry_db( void )
        if ( tdb_reg )
                return True;
 
-       /* placeholder tdb; reinit upon startup */
-       
        if ( !(tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600)) )
        {
                tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
@@ -197,13 +220,14 @@ BOOL init_registry_db( void )
        vers_id = tdb_fetch_int32(tdb_reg, vstring);
 
        if ( vers_id != REGVER_V1 ) {
+               /* any upgrade code here if needed */
+       }
 
-               /* create the registry here */
+       /* always setup the necessary keys and values */
 
-               if ( !init_registry_data() ) {
-                       DEBUG(0,("init_registry: Failed to initiailize data in registry!\n"));
-                       return False;
-               }
+       if ( !init_registry_data() ) {
+               DEBUG(0,("init_registry: Failed to initiailize data in registry!\n"));
+               return False;
        }
 
        return True;
@@ -285,13 +309,17 @@ BOOL regdb_store_keys( const char *key, REGSUBKEY_CTR *ctr )
 {
        int num_subkeys, i;
        pstring path;
-       REGSUBKEY_CTR subkeys, old_subkeys;
+       REGSUBKEY_CTR *subkeys, *old_subkeys;
        char *oldkeyname;
        
        /* fetch a list of the old subkeys so we can determine if any were deleted */
        
-       regsubkey_ctr_init( &old_subkeys );
-       regdb_fetch_keys( key, &old_subkeys );
+       if ( !(old_subkeys = TALLOC_ZERO_P( ctr, REGSUBKEY_CTR )) ) {
+               DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
+               return False;
+       }
+
+       regdb_fetch_keys( key, old_subkeys );
        
        /* store the subkey list for the parent */
        
@@ -302,9 +330,9 @@ BOOL regdb_store_keys( const char *key, REGSUBKEY_CTR *ctr )
        
        /* now delete removed keys */
        
-       num_subkeys = regsubkey_ctr_numkeys( &old_subkeys );
+       num_subkeys = regsubkey_ctr_numkeys( old_subkeys );
        for ( i=0; i<num_subkeys; i++ ) {
-               oldkeyname = regsubkey_ctr_specific_key( &old_subkeys, i );
+               oldkeyname = regsubkey_ctr_specific_key( old_subkeys, i );
                if ( !regsubkey_ctr_key_exists( ctr, oldkeyname ) ) {
                        pstr_sprintf( path, "%s%c%s", key, '/', oldkeyname );
                        normalize_reg_path( path );
@@ -312,23 +340,29 @@ BOOL regdb_store_keys( const char *key, REGSUBKEY_CTR *ctr )
                }
        }
 
-       regsubkey_ctr_destroy( &old_subkeys );
+       TALLOC_FREE( old_subkeys );
        
        /* now create records for any subkeys that don't already exist */
        
        num_subkeys = regsubkey_ctr_numkeys( ctr );
        for ( i=0; i<num_subkeys; i++ ) {
                pstr_sprintf( path, "%s%c%s", key, '/', regsubkey_ctr_specific_key( ctr, i ) );
-               regsubkey_ctr_init( &subkeys );
-               if ( regdb_fetch_keys( path, &subkeys ) == -1 ) {
+
+               if ( !(subkeys = TALLOC_ZERO_P( ctr, REGSUBKEY_CTR )) ) {
+                       DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
+                       return False;
+               }
+
+               if ( regdb_fetch_keys( path, subkeys ) == -1 ) {
                        /* create a record with 0 subkeys */
-                       if ( !regdb_store_keys_internal( path, &subkeys ) ) {
+                       if ( !regdb_store_keys_internal( path, subkeys ) ) {
                                DEBUG(0,("regdb_store_keys: Failed to store new record for key [%s}\n", path ));
-                               regsubkey_ctr_destroy( &subkeys );
+                               TALLOC_FREE( subkeys );
                                return False;
                        }
                }
-               regsubkey_ctr_destroy( &subkeys );
+
+               TALLOC_FREE( subkeys );
        }
        
        return True;
@@ -350,7 +384,7 @@ int regdb_fetch_keys( const char* key, REGSUBKEY_CTR *ctr )
        int i;
        fstring subkeyname;
 
-       DEBUG(10,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL"));
+       DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL"));
        
        pstrcpy( path, key );
        
@@ -377,7 +411,7 @@ int regdb_fetch_keys( const char* key, REGSUBKEY_CTR *ctr )
 
        SAFE_FREE( dbuf.dptr );
        
-       DEBUG(10,("regdb_fetch_keys: Exit [%d] items\n", num_items));
+       DEBUG(11,("regdb_fetch_keys: Exit [%d] items\n", num_items));
        
        return num_items;
 }
@@ -468,7 +502,6 @@ int regdb_fetch_values( const char* key, REGVAL_CTR *values )
 {
        TDB_DATA data;
        pstring keystr;
-       int len;
 
        DEBUG(10,("regdb_fetch_values: Looking for value of key [%s] \n", key));
        
@@ -482,7 +515,7 @@ int regdb_fetch_values( const char* key, REGVAL_CTR *values )
                return 0;
        }
        
-       len = regdb_unpack_values( values, data.dptr, data.dsize );
+       regdb_unpack_values( values, data.dptr, data.dsize );
        
        SAFE_FREE( data.dptr );