2002-07-19 03:00:24 +04:00
/*
* Unix SMB / CIFS implementation .
2005-05-23 20:25:31 +04:00
* Virtual Windows Registry Layer
* Copyright ( C ) Gerald Carter 2002 - 2005
2002-07-19 03:00:24 +04:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
/* Implementation of internal registry database functions. */
# include "includes.h"
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_RPC_SRV
static TDB_CONTEXT * tdb_reg ;
2005-06-25 21:31:40 +04:00
# define VALUE_PREFIX "SAMBA_REGVAL"
2005-05-23 20:25:31 +04:00
/* 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
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
" HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion " and then we ' ll hook
the reg_printing backend onto the last component of the path ( see
KEY_PRINTING_2K in include / rpc_reg . h ) - - jerry */
static const char * builtin_registry_paths [ ] = {
2005-06-30 23:43:53 +04:00
KEY_PRINTING_2K ,
KEY_PRINTING_PORTS ,
KEY_PRINTING ,
KEY_SHARES ,
KEY_EVENTLOG ,
2005-07-02 02:24:00 +04:00
" HKLM \\ SYSTEM \\ CurrentControlSet \\ Control \\ Print \\ Monitors " ,
2005-05-23 20:25:31 +04:00
" HKLM \\ SYSTEM \\ CurrentControlSet \\ Control \\ ProductOptions " ,
" HKLM \\ SYSTEM \\ CurrentControlSet \\ Services \\ TcpIp \\ Parameters " ,
" HKLM \\ SYSTEM \\ CurrentControlSet \\ Services \\ Netlogon \\ Parameters " ,
" HKU " ,
" HKCR " ,
NULL } ;
2005-06-17 19:53:01 +04:00
2005-06-25 02:34:40 +04:00
struct builtin_regkey_value {
const char * path ;
const char * valuename ;
uint32 type ;
union {
const char * string ;
uint32 dw_value ;
} data ;
} ;
2005-06-25 21:31:40 +04:00
static struct builtin_regkey_value builtin_registry_values [ ] = {
2005-07-02 02:24:00 +04:00
{ " HKLM \\ SOFTWARE \\ Microsoft \\ Windows NT \\ CurrentVersion " ,
" SystemRoot " , REG_SZ , { " c: \\ Windows " } } ,
{ " HKLM \\ SOFTWARE \\ Microsoft \\ Windows NT \\ CurrentVersion \\ Ports " ,
" Samba Printer Port " , REG_SZ , { " " } } ,
{ " HKLM \\ SOFTWARE \\ Microsoft \\ Windows NT \\ CurrentVersion \\ Print \\ Printers " ,
" DefaultSpoolDirectory " , REG_SZ , { " c: \\ windows \\ system32 \\ spool \\ printers " } } ,
2005-06-25 21:31:40 +04:00
{ NULL , NULL , 0 , { NULL } }
2005-06-25 02:34:40 +04:00
} ;
2005-06-17 19:53:01 +04:00
# define REGVER_V1 1 /* first db version with write support */
2005-05-23 20:25:31 +04:00
2002-07-19 03:00:24 +04:00
/***********************************************************************
Open the registry data in the tdb
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL init_registry_data ( void )
{
2005-05-23 20:25:31 +04:00
pstring path , base , remaining ;
fstring keyname , subkeyname ;
2002-07-19 22:49:44 +04:00
REGSUBKEY_CTR subkeys ;
2005-06-25 21:31:40 +04:00
REGVAL_CTR values ;
2005-05-23 20:25:31 +04:00
int i ;
const char * p , * p2 ;
2005-06-25 21:31:40 +04:00
UNISTR2 data ;
2005-05-23 20:25:31 +04:00
/* loop over all of the predefined paths and add each component */
for ( i = 0 ; builtin_registry_paths [ i ] ! = NULL ; i + + ) {
2005-05-09 17:51:44 +04:00
2005-05-23 20:25:31 +04:00
DEBUG ( 6 , ( " init_registry_data: Adding [%s] \n " , builtin_registry_paths [ i ] ) ) ;
2005-05-09 17:51:44 +04:00
2005-05-23 20:25:31 +04:00
pstrcpy ( path , builtin_registry_paths [ i ] ) ;
pstrcpy ( base , " " ) ;
p = path ;
2002-07-19 03:00:24 +04:00
2005-05-23 20:25:31 +04:00
while ( next_token ( & p , keyname , " \\ " , sizeof ( keyname ) ) ) {
2002-07-19 03:00:24 +04:00
2005-05-23 20:25:31 +04:00
/* build up the registry path from the components */
if ( * base )
pstrcat ( base , " \\ " ) ;
pstrcat ( base , keyname ) ;
/* get the immediate subkeyname (if we have one ) */
* subkeyname = ' \0 ' ;
if ( * p ) {
pstrcpy ( remaining , p ) ;
p2 = remaining ;
if ( ! next_token ( & p2 , subkeyname , " \\ " , sizeof ( subkeyname ) ) )
fstrcpy ( subkeyname , p2 ) ;
}
2005-05-09 17:51:44 +04:00
2005-05-23 20:25:31 +04:00
DEBUG ( 10 , ( " init_registry_data: Storing key [%s] with subkey [%s] \n " ,
base , * subkeyname ? subkeyname : " NULL " ) ) ;
/* we don't really care if the lookup succeeds or not since
we are about to update the record . We just want any
subkeys already present */
regsubkey_ctr_init ( & subkeys ) ;
2005-06-30 06:59:29 +04:00
regdb_fetch_keys ( base , & subkeys ) ;
2005-05-23 20:25:31 +04:00
if ( * subkeyname )
regsubkey_ctr_addkey ( & subkeys , subkeyname ) ;
2005-06-30 06:59:29 +04:00
if ( ! regdb_store_keys ( base , & subkeys ) )
2005-05-23 20:25:31 +04:00
return False ;
regsubkey_ctr_destroy ( & subkeys ) ;
}
}
2005-05-09 17:51:44 +04:00
2005-06-25 21:31:40 +04:00
/* 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 ) ;
2005-06-30 06:59:29 +04:00
regdb_fetch_values ( builtin_registry_values [ i ] . path , & values ) ;
2005-06-25 21:31:40 +04:00
switch ( builtin_registry_values [ i ] . type ) {
case REG_DWORD :
regval_ctr_addvalue ( & values ,
builtin_registry_values [ i ] . valuename ,
REG_DWORD ,
( char * ) & builtin_registry_values [ i ] . data . dw_value ,
sizeof ( uint32 ) ) ;
break ;
case REG_SZ :
init_unistr2 ( & data , builtin_registry_values [ i ] . data . string , UNI_STR_TERMINATE ) ;
regval_ctr_addvalue ( & values ,
builtin_registry_values [ i ] . valuename ,
REG_SZ ,
( char * ) data . buffer ,
data . uni_str_len * sizeof ( uint16 ) ) ;
break ;
default :
DEBUG ( 0 , ( " init_registry_data: invalid value type in builtin_registry_values [%d] \n " ,
builtin_registry_values [ i ] . type ) ) ;
}
2005-06-30 06:59:29 +04:00
regdb_store_values ( builtin_registry_values [ i ] . path , & values ) ;
2005-06-25 21:31:40 +04:00
regval_ctr_destroy ( & values ) ;
}
2002-07-19 03:00:24 +04:00
return True ;
}
/***********************************************************************
Open the registry database
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL init_registry_db ( void )
{
2005-06-17 19:53:01 +04:00
const char * vstring = " INFO/version " ;
uint32 vers_id ;
2002-07-19 03:00:24 +04:00
2005-06-17 19:53:01 +04:00
if ( tdb_reg )
2002-07-19 03:00:24 +04:00
return True ;
2005-05-23 20:25:31 +04:00
/* placeholder tdb; reinit upon startup */
2002-07-19 03:00:24 +04:00
2005-06-17 19:53:01 +04:00
if ( ! ( tdb_reg = tdb_open_log ( lock_path ( " registry.tdb " ) , 0 , TDB_DEFAULT , O_RDWR , 0600 ) ) )
2002-07-19 03:00:24 +04:00
{
tdb_reg = tdb_open_log ( lock_path ( " registry.tdb " ) , 0 , TDB_DEFAULT , O_RDWR | O_CREAT , 0600 ) ;
if ( ! tdb_reg ) {
DEBUG ( 0 , ( " init_registry: Failed to open registry %s (%s) \n " ,
lock_path ( " registry.tdb " ) , strerror ( errno ) ) ) ;
return False ;
}
DEBUG ( 10 , ( " init_registry: Successfully created registry tdb \n " ) ) ;
2005-05-23 20:25:31 +04:00
}
2002-07-19 03:00:24 +04:00
2005-05-23 20:25:31 +04:00
2005-06-17 19:53:01 +04:00
vers_id = tdb_fetch_int32 ( tdb_reg , vstring ) ;
if ( vers_id ! = REGVER_V1 ) {
/* create the registry here */
if ( ! init_registry_data ( ) ) {
DEBUG ( 0 , ( " init_registry: Failed to initiailize data in registry! \n " ) ) ;
return False ;
}
2002-07-19 03:00:24 +04:00
}
return True ;
}
/***********************************************************************
Add subkey strings to the registry tdb under a defined key
fmt is the same format as tdb_pack except this function only supports
fstrings
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-30 06:59:29 +04:00
static BOOL regdb_store_keys_internal ( const char * key , REGSUBKEY_CTR * ctr )
2002-07-19 03:00:24 +04:00
{
TDB_DATA kbuf , dbuf ;
char * buffer , * tmpbuf ;
int i = 0 ;
uint32 len , buflen ;
BOOL ret = True ;
2002-07-19 22:49:44 +04:00
uint32 num_subkeys = regsubkey_ctr_numkeys ( ctr ) ;
2005-05-23 20:25:31 +04:00
pstring keyname ;
2002-07-19 03:00:24 +04:00
2005-05-23 20:25:31 +04:00
if ( ! key )
2002-07-19 03:00:24 +04:00
return False ;
2005-05-23 20:25:31 +04:00
pstrcpy ( keyname , key ) ;
2005-06-17 22:57:37 +04:00
normalize_reg_path ( keyname ) ;
2002-07-19 03:00:24 +04:00
/* allocate some initial memory */
2004-12-07 21:25:53 +03:00
buffer = SMB_MALLOC ( sizeof ( pstring ) ) ;
2002-07-19 03:00:24 +04:00
buflen = sizeof ( pstring ) ;
len = 0 ;
/* store the number of subkeys */
2002-07-19 22:49:44 +04:00
len + = tdb_pack ( buffer + len , buflen - len , " d " , num_subkeys ) ;
2002-07-19 03:00:24 +04:00
/* pack all the strings */
for ( i = 0 ; i < num_subkeys ; i + + ) {
2002-07-19 22:49:44 +04:00
len + = tdb_pack ( buffer + len , buflen - len , " f " , regsubkey_ctr_specific_key ( ctr , i ) ) ;
2002-07-19 03:00:24 +04:00
if ( len > buflen ) {
/* allocate some extra space */
2004-12-07 21:25:53 +03:00
if ( ( tmpbuf = SMB_REALLOC ( buffer , len * 2 ) ) = = NULL ) {
2005-06-30 06:59:29 +04:00
DEBUG ( 0 , ( " regdb_store_keys: Failed to realloc memory of size [%d] \n " , len * 2 ) ) ;
2002-07-19 03:00:24 +04:00
ret = False ;
goto done ;
}
buffer = tmpbuf ;
buflen = len * 2 ;
2002-07-19 22:49:44 +04:00
len = tdb_pack ( buffer + len , buflen - len , " f " , regsubkey_ctr_specific_key ( ctr , i ) ) ;
2002-07-19 03:00:24 +04:00
}
}
/* finally write out the data */
kbuf . dptr = keyname ;
kbuf . dsize = strlen ( keyname ) + 1 ;
dbuf . dptr = buffer ;
dbuf . dsize = len ;
if ( tdb_store ( tdb_reg , kbuf , dbuf , TDB_REPLACE ) = = - 1 ) {
ret = False ;
goto done ;
}
done :
SAFE_FREE ( buffer ) ;
2002-07-20 08:27:30 +04:00
2002-07-19 03:00:24 +04:00
return ret ;
}
2005-06-17 19:35:31 +04:00
/***********************************************************************
Store the new subkey record and create any child key records that
do not currently exist
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-30 06:59:29 +04:00
BOOL regdb_store_keys ( const char * key , REGSUBKEY_CTR * ctr )
2005-06-17 19:35:31 +04:00
{
int num_subkeys , i ;
pstring path ;
2005-06-17 22:57:37 +04:00
REGSUBKEY_CTR subkeys , old_subkeys ;
char * oldkeyname ;
2005-06-27 07:40:03 +04:00
/* fetch a list of the old subkeys so we can determine if any were deleted */
2005-06-17 22:57:37 +04:00
regsubkey_ctr_init ( & old_subkeys ) ;
2005-06-30 06:59:29 +04:00
regdb_fetch_keys ( key , & old_subkeys ) ;
2005-06-17 19:35:31 +04:00
/* store the subkey list for the parent */
2005-06-30 06:59:29 +04:00
if ( ! regdb_store_keys_internal ( key , ctr ) ) {
DEBUG ( 0 , ( " regdb_store_keys: Failed to store new subkey list for parent [%s} \n " , key ) ) ;
2005-06-17 19:35:31 +04:00
return False ;
}
2005-06-17 22:57:37 +04:00
/* now delete removed keys */
num_subkeys = regsubkey_ctr_numkeys ( & old_subkeys ) ;
for ( i = 0 ; i < num_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 ) ;
tdb_delete_bystring ( tdb_reg , path ) ;
}
}
2005-06-27 07:40:03 +04:00
regsubkey_ctr_destroy ( & old_subkeys ) ;
2005-06-17 22:57:37 +04:00
2005-06-17 19:35:31 +04:00
/* 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 ) ;
2005-06-30 06:59:29 +04:00
if ( regdb_fetch_keys ( path , & subkeys ) = = - 1 ) {
2005-06-17 19:35:31 +04:00
/* create a record with 0 subkeys */
2005-06-30 06:59:29 +04:00
if ( ! regdb_store_keys_internal ( path , & subkeys ) ) {
DEBUG ( 0 , ( " regdb_store_keys: Failed to store new record for key [%s} \n " , path ) ) ;
2005-06-17 22:57:37 +04:00
regsubkey_ctr_destroy ( & subkeys ) ;
2005-06-17 19:35:31 +04:00
return False ;
}
}
regsubkey_ctr_destroy ( & subkeys ) ;
}
return True ;
}
2002-07-19 03:00:24 +04:00
/***********************************************************************
Retrieve an array of strings containing subkeys . Memory should be
2005-06-25 21:31:40 +04:00
released by the caller .
2002-07-19 03:00:24 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-30 06:59:29 +04:00
int regdb_fetch_keys ( const char * key , REGSUBKEY_CTR * ctr )
2002-07-19 03:00:24 +04:00
{
pstring path ;
uint32 num_items ;
TDB_DATA dbuf ;
char * buf ;
uint32 buflen , len ;
int i ;
2002-07-19 22:49:44 +04:00
fstring subkeyname ;
2002-07-19 03:00:24 +04:00
2005-06-30 06:59:29 +04:00
DEBUG ( 10 , ( " regdb_fetch_keys: Enter key => [%s] \n " , key ? key : " NULL " ) ) ;
2002-07-19 03:00:24 +04:00
pstrcpy ( path , key ) ;
/* convert to key format */
2002-07-20 08:27:30 +04:00
pstring_sub ( path , " \\ " , " / " ) ;
2002-08-06 14:10:54 +04:00
strupper_m ( path ) ;
2002-07-19 03:00:24 +04:00
2003-07-11 00:37:01 +04:00
dbuf = tdb_fetch_bystring ( tdb_reg , path ) ;
2002-07-19 03:00:24 +04:00
buf = dbuf . dptr ;
buflen = dbuf . dsize ;
if ( ! buf ) {
2005-06-30 06:59:29 +04:00
DEBUG ( 5 , ( " regdb_fetch_keys: tdb lookup failed to locate key [%s] \n " , key ) ) ;
2002-07-24 23:53:49 +04:00
return - 1 ;
2002-07-19 03:00:24 +04:00
}
len = tdb_unpack ( buf , buflen , " d " , & num_items ) ;
for ( i = 0 ; i < num_items ; i + + ) {
2002-07-19 22:49:44 +04:00
len + = tdb_unpack ( buf + len , buflen - len , " f " , subkeyname ) ;
regsubkey_ctr_addkey ( ctr , subkeyname ) ;
2002-07-19 03:00:24 +04:00
}
2002-07-20 08:27:30 +04:00
SAFE_FREE ( dbuf . dptr ) ;
2005-06-30 06:59:29 +04:00
DEBUG ( 10 , ( " regdb_fetch_keys: Exit [%d] items \n " , num_items ) ) ;
2002-07-24 10:42:09 +04:00
2002-07-19 03:00:24 +04:00
return num_items ;
}
2005-06-25 21:31:40 +04:00
/****************************************************************************
Unpack a list of registry values frem the TDB
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int regdb_unpack_values ( REGVAL_CTR * values , char * buf , int buflen )
{
int len = 0 ;
uint32 type ;
pstring valuename ;
2005-06-29 20:35:32 +04:00
uint32 size ;
2005-06-25 21:31:40 +04:00
uint8 * data_p ;
uint32 num_values = 0 ;
int i ;
/* loop and unpack the rest of the registry values */
len + = tdb_unpack ( buf + len , buflen - len , " d " , & num_values ) ;
for ( i = 0 ; i < num_values ; i + + ) {
/* unpack the next regval */
2005-06-29 20:35:32 +04:00
type = REG_NONE ;
size = 0 ;
data_p = NULL ;
2005-06-25 21:31:40 +04:00
len + = tdb_unpack ( buf + len , buflen - len , " fdB " ,
valuename ,
& type ,
& size ,
& data_p ) ;
2005-06-29 20:35:32 +04:00
/* add the new value. Paranoid protective code -- make sure data_p is valid */
2005-06-25 21:31:40 +04:00
2005-06-29 20:35:32 +04:00
if ( size & & data_p ) {
regval_ctr_addvalue ( values , valuename , type , ( const char * ) data_p , size ) ;
SAFE_FREE ( data_p ) ; /* 'B' option to tdb_unpack does a malloc() */
}
2005-06-25 21:31:40 +04:00
DEBUG ( 8 , ( " specific: [%s], len: %d \n " , valuename , size ) ) ;
}
return len ;
}
/****************************************************************************
Pack all values in all printer keys
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int regdb_pack_values ( REGVAL_CTR * values , char * buf , int buflen )
{
int len = 0 ;
int i ;
REGISTRY_VALUE * val ;
int num_values = regval_ctr_numvals ( values ) ;
if ( ! values )
return 0 ;
/* pack the number of values first */
len + = tdb_pack ( buf + len , buflen - len , " d " , num_values ) ;
/* loop over all values */
for ( i = 0 ; i < num_values ; i + + ) {
val = regval_ctr_specific_value ( values , i ) ;
len + = tdb_pack ( buf + len , buflen - len , " fdB " ,
regval_name ( val ) ,
regval_type ( val ) ,
regval_size ( val ) ,
regval_data_p ( val ) ) ;
}
return len ;
}
2002-07-19 22:49:44 +04:00
2002-07-19 03:00:24 +04:00
/***********************************************************************
2002-07-19 22:49:44 +04:00
Retrieve an array of strings containing subkeys . Memory should be
2005-06-25 21:31:40 +04:00
released by the caller .
2002-07-19 03:00:24 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-30 06:59:29 +04:00
int regdb_fetch_values ( const char * key , REGVAL_CTR * values )
2002-07-19 03:00:24 +04:00
{
2005-06-25 21:31:40 +04:00
TDB_DATA data ;
pstring keystr ;
int len ;
2005-05-09 17:51:44 +04:00
2005-06-30 06:59:29 +04:00
DEBUG ( 10 , ( " regdb_fetch_values: Looking for value of key [%s] \n " , key ) ) ;
2005-06-25 21:31:40 +04:00
pstr_sprintf ( keystr , " %s/%s " , VALUE_PREFIX , key ) ;
normalize_reg_path ( keystr ) ;
data = tdb_fetch_bystring ( tdb_reg , keystr ) ;
2005-06-27 07:40:03 +04:00
if ( ! data . dptr ) {
/* all keys have zero values by default */
2005-06-25 21:31:40 +04:00
return 0 ;
2005-06-27 07:40:03 +04:00
}
2005-06-25 21:31:40 +04:00
len = regdb_unpack_values ( values , data . dptr , data . dsize ) ;
SAFE_FREE ( data . dptr ) ;
return regval_ctr_numvals ( values ) ;
2002-07-19 03:00:24 +04:00
}
/***********************************************************************
2002-07-19 22:49:44 +04:00
Stub function since we do not currently support storing registry
values in the registry . tdb
2002-07-19 03:00:24 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-30 06:59:29 +04:00
BOOL regdb_store_values ( const char * key , REGVAL_CTR * values )
2002-07-19 03:00:24 +04:00
{
2005-06-25 21:31:40 +04:00
TDB_DATA data ;
pstring keystr ;
int len , ret ;
2005-06-30 06:59:29 +04:00
DEBUG ( 10 , ( " regdb_store_values: Looking for value of key [%s] \n " , key ) ) ;
2005-06-25 21:31:40 +04:00
ZERO_STRUCT ( data ) ;
len = regdb_pack_values ( values , data . dptr , data . dsize ) ;
if ( len < = 0 ) {
2005-06-30 06:59:29 +04:00
DEBUG ( 0 , ( " regdb_store_values: unable to pack values. len <= 0 \n " ) ) ;
2005-06-25 21:31:40 +04:00
return False ;
}
data . dptr = SMB_MALLOC_ARRAY ( char , len ) ;
data . dsize = len ;
len = regdb_pack_values ( values , data . dptr , data . dsize ) ;
SMB_ASSERT ( len = = data . dsize ) ;
pstr_sprintf ( keystr , " %s/%s " , VALUE_PREFIX , key ) ;
normalize_reg_path ( keystr ) ;
ret = tdb_store_bystring ( tdb_reg , keystr , data , TDB_REPLACE ) ;
SAFE_FREE ( data . dptr ) ;
return ret ! = - 1 ;
2002-07-19 03:00:24 +04:00
}
2002-07-19 22:49:44 +04:00
/*
* Table of function pointers for default access
*/
REGISTRY_OPS regdb_ops = {
2005-06-30 06:59:29 +04:00
regdb_fetch_keys ,
regdb_fetch_values ,
regdb_store_keys ,
regdb_store_values ,
2005-06-17 00:45:55 +04:00
NULL
2002-07-19 22:49:44 +04:00
} ;