2007-10-06 04:17:44 +04:00
/*
2007-08-26 19:16:40 +04:00
Unix SMB / CIFS implementation .
Registry interface
2008-09-13 14:10:00 +04:00
Copyright ( C ) 2004 - 2007 , Jelmer Vernooij , jelmer @ samba . org
2010-03-06 21:20:48 +03:00
Copyright ( C ) 2008 - 2010 , Matthias Dieter Wallnöfer , mdw @ samba . org
2007-10-06 04:17:44 +04:00
2007-08-26 19:16:40 +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 3 of the License , or
( at your option ) any later version .
2007-10-06 04:17:44 +04:00
2007-08-26 19:16:40 +04:00
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 .
2007-10-06 04:17:44 +04:00
2007-08-26 19:16:40 +04:00
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "registry.h"
2011-02-10 06:12:51 +03:00
# include <ldb.h>
# include <ldb_errors.h>
2007-11-16 22:12:00 +03:00
# include "ldb_wrap.h"
2007-08-26 19:16:40 +04:00
# include "librpc/gen_ndr/winreg.h"
2007-10-01 22:52:55 +04:00
# include "param/param.h"
2020-07-03 09:11:20 +03:00
# include "lib/util/smb_strtox.h"
2007-08-26 19:16:40 +04:00
2020-10-01 15:22:12 +03:00
# undef strcasecmp
2007-08-26 19:16:40 +04:00
static struct hive_operations reg_backend_ldb ;
2007-10-06 04:17:44 +04:00
struct ldb_key_data
2007-08-26 19:16:40 +04:00
{
struct hive_key key ;
struct ldb_context * ldb ;
struct ldb_dn * dn ;
struct ldb_message * * subkeys , * * values ;
2009-11-07 23:07:20 +03:00
unsigned int subkey_count , value_count ;
2010-06-28 23:15:17 +04:00
const char * classname ;
2007-08-26 19:16:40 +04:00
} ;
2010-03-06 21:39:45 +03:00
static void reg_ldb_unpack_value ( TALLOC_CTX * mem_ctx ,
2008-02-21 19:54:24 +03:00
struct ldb_message * msg ,
2007-10-06 04:17:44 +04:00
const char * * name , uint32_t * type ,
DATA_BLOB * data )
2007-08-26 19:16:40 +04:00
{
const struct ldb_val * val ;
2008-01-07 23:11:29 +03:00
uint32_t value_type ;
2010-03-06 21:20:48 +03:00
if ( name ! = NULL ) {
2007-10-06 04:17:44 +04:00
* name = talloc_strdup ( mem_ctx ,
ldb_msg_find_attr_as_string ( msg , " value " ,
2010-03-22 01:36:09 +03:00
" " ) ) ;
2010-03-06 21:20:48 +03:00
}
2007-08-26 19:16:40 +04:00
2008-01-07 23:11:29 +03:00
value_type = ldb_msg_find_attr_as_uint ( msg , " type " , 0 ) ;
2010-03-06 21:39:45 +03:00
* type = value_type ;
2008-09-15 20:21:45 +04:00
2008-09-15 19:21:35 +04:00
val = ldb_msg_find_ldb_val ( msg , " data " ) ;
2007-08-26 19:16:40 +04:00
2008-09-15 19:21:35 +04:00
switch ( value_type )
{
case REG_SZ :
case REG_EXPAND_SZ :
2010-03-06 21:20:48 +03:00
if ( val ! = NULL ) {
2010-03-23 02:09:22 +03:00
/* The data should be provided as UTF16 string */
convert_string_talloc ( mem_ctx , CH_UTF8 , CH_UTF16 ,
val - > data , val - > length ,
2011-03-24 02:59:41 +03:00
( void * * ) & data - > data , & data - > length ) ;
2010-03-06 21:20:48 +03:00
} else {
2008-09-18 18:51:48 +04:00
data - > data = NULL ;
data - > length = 0 ;
}
2008-09-15 19:21:35 +04:00
break ;
2010-03-06 21:20:48 +03:00
case REG_DWORD :
2010-03-15 20:55:33 +03:00
case REG_DWORD_BIG_ENDIAN :
2010-03-06 21:20:48 +03:00
if ( val ! = NULL ) {
2019-01-30 11:31:34 +03:00
int error = 0 ;
2010-03-23 02:09:22 +03:00
/* The data is a plain DWORD */
2019-01-30 11:31:34 +03:00
uint32_t tmp ;
2019-06-04 10:06:37 +03:00
tmp = smb_strtoul ( ( char * ) val - > data ,
NULL ,
0 ,
& error ,
SMB_STR_STANDARD ) ;
2019-01-30 11:31:34 +03:00
if ( error ! = 0 ) {
data - > data = NULL ;
data - > length = 0 ;
break ;
}
2010-03-23 02:09:22 +03:00
data - > data = talloc_size ( mem_ctx , sizeof ( uint32_t ) ) ;
if ( data - > data ! = NULL ) {
SIVAL ( data - > data , 0 , tmp ) ;
2010-03-13 22:03:03 +03:00
}
2010-03-23 02:09:22 +03:00
data - > length = sizeof ( uint32_t ) ;
2010-03-06 21:20:48 +03:00
} else {
2008-09-15 19:21:35 +04:00
data - > data = NULL ;
data - > length = 0 ;
2008-09-09 19:49:41 +04:00
}
2008-09-15 19:21:35 +04:00
break ;
2010-03-15 13:07:36 +03:00
case REG_QWORD :
if ( val ! = NULL ) {
2019-01-30 11:31:34 +03:00
int error = 0 ;
2010-03-23 02:09:22 +03:00
/* The data is a plain QWORD */
2019-01-30 11:31:34 +03:00
uint64_t tmp ;
2019-06-04 10:06:37 +03:00
tmp = smb_strtoull ( ( char * ) val - > data ,
NULL ,
0 ,
& error ,
SMB_STR_STANDARD ) ;
2019-01-30 11:31:34 +03:00
if ( error ! = 0 ) {
data - > data = NULL ;
data - > length = 0 ;
break ;
}
2010-03-23 02:09:22 +03:00
data - > data = talloc_size ( mem_ctx , sizeof ( uint64_t ) ) ;
if ( data - > data ! = NULL ) {
SBVAL ( data - > data , 0 , tmp ) ;
2010-03-15 13:07:36 +03:00
}
2010-03-23 02:09:22 +03:00
data - > length = sizeof ( uint64_t ) ;
2010-03-15 13:07:36 +03:00
} else {
data - > data = NULL ;
data - > length = 0 ;
}
break ;
2010-03-06 21:20:48 +03:00
case REG_BINARY :
2008-09-15 19:21:35 +04:00
default :
2010-03-06 21:20:48 +03:00
if ( val ! = NULL ) {
2010-03-13 22:03:03 +03:00
data - > data = talloc_memdup ( mem_ctx , val - > data ,
val - > length ) ;
data - > length = val - > length ;
2010-03-06 21:20:48 +03:00
} else {
data - > data = NULL ;
data - > length = 0 ;
}
2008-09-15 19:21:35 +04:00
break ;
2007-08-26 19:16:40 +04:00
}
}
2007-10-06 04:17:44 +04:00
static struct ldb_message * reg_ldb_pack_value ( struct ldb_context * ctx ,
TALLOC_CTX * mem_ctx ,
const char * name ,
uint32_t type , DATA_BLOB data )
2007-08-26 19:16:40 +04:00
{
2010-03-13 21:29:03 +03:00
struct ldb_message * msg ;
char * name_dup , * type_str ;
int ret ;
2007-08-26 19:16:40 +04:00
2019-04-15 14:20:46 +03:00
msg = ldb_msg_new ( mem_ctx ) ;
2010-03-13 21:29:03 +03:00
if ( msg = = NULL ) {
return NULL ;
}
name_dup = talloc_strdup ( msg , name ) ;
if ( name_dup = = NULL ) {
talloc_free ( msg ) ;
return NULL ;
}
ret = ldb_msg_add_string ( msg , " value " , name_dup ) ;
if ( ret ! = LDB_SUCCESS ) {
talloc_free ( msg ) ;
return NULL ;
}
2007-08-26 19:16:40 +04:00
switch ( type ) {
case REG_SZ :
case REG_EXPAND_SZ :
2010-03-19 20:23:00 +03:00
if ( ( data . length > 0 ) & & ( data . data ! = NULL ) ) {
2010-03-13 20:39:54 +03:00
struct ldb_val * val ;
2010-03-19 20:23:00 +03:00
bool ret2 = false ;
2010-03-13 20:39:54 +03:00
val = talloc_zero ( msg , struct ldb_val ) ;
2010-03-13 21:29:03 +03:00
if ( val = = NULL ) {
talloc_free ( msg ) ;
return NULL ;
}
2010-03-23 02:24:32 +03:00
/* The data is provided as UTF16 string */
ret2 = convert_string_talloc ( mem_ctx , CH_UTF16 , CH_UTF8 ,
( void * ) data . data , data . length ,
2011-03-24 02:59:41 +03:00
( void * * ) & val - > data , & val - > length ) ;
2010-03-23 02:09:22 +03:00
if ( ret2 ) {
ret = ldb_msg_add_value ( msg , " data " , val , NULL ) ;
2010-03-23 18:19:26 +03:00
} else {
/* workaround for non-standard data */
ret = ldb_msg_add_empty ( msg , " data " , LDB_FLAG_MOD_DELETE , NULL ) ;
2010-03-14 12:30:19 +03:00
}
2008-09-18 18:51:48 +04:00
} else {
2010-03-13 21:29:03 +03:00
ret = ldb_msg_add_empty ( msg , " data " , LDB_FLAG_MOD_DELETE , NULL ) ;
2008-09-18 18:51:48 +04:00
}
2007-08-26 19:16:40 +04:00
break ;
2010-03-06 21:20:48 +03:00
case REG_DWORD :
2010-03-15 20:55:33 +03:00
case REG_DWORD_BIG_ENDIAN :
2010-03-06 21:20:48 +03:00
if ( ( data . length > 0 ) & & ( data . data ! = NULL ) ) {
2010-03-14 19:18:29 +03:00
if ( data . length = = sizeof ( uint32_t ) ) {
char * conv_str ;
2010-03-13 21:29:03 +03:00
2010-03-19 21:55:32 +03:00
conv_str = talloc_asprintf ( msg , " 0x%8.8x " ,
IVAL ( data . data , 0 ) ) ;
2010-03-14 19:18:29 +03:00
if ( conv_str = = NULL ) {
talloc_free ( msg ) ;
return NULL ;
}
ret = ldb_msg_add_string ( msg , " data " , conv_str ) ;
2010-03-23 18:19:26 +03:00
} else {
/* workaround for non-standard data */
2010-03-29 23:09:23 +04:00
talloc_free ( msg ) ;
return NULL ;
2010-03-15 13:07:36 +03:00
}
} else {
ret = ldb_msg_add_empty ( msg , " data " , LDB_FLAG_MOD_DELETE , NULL ) ;
}
break ;
case REG_QWORD :
if ( ( data . length > 0 ) & & ( data . data ! = NULL ) ) {
if ( data . length = = sizeof ( uint64_t ) ) {
char * conv_str ;
2010-03-23 18:17:25 +03:00
conv_str = talloc_asprintf ( msg , " 0x%16.16llx " ,
2010-09-13 17:07:10 +04:00
( unsigned long long ) BVAL ( data . data , 0 ) ) ;
2010-03-15 13:07:36 +03:00
if ( conv_str = = NULL ) {
talloc_free ( msg ) ;
return NULL ;
}
ret = ldb_msg_add_string ( msg , " data " , conv_str ) ;
2010-03-23 18:19:26 +03:00
} else {
/* workaround for non-standard data */
2010-03-29 23:09:23 +04:00
talloc_free ( msg ) ;
return NULL ;
2010-03-14 19:18:29 +03:00
}
2010-03-06 21:20:48 +03:00
} else {
2010-03-13 21:29:03 +03:00
ret = ldb_msg_add_empty ( msg , " data " , LDB_FLAG_MOD_DELETE , NULL ) ;
2010-03-06 21:20:48 +03:00
}
2008-09-09 19:49:41 +04:00
break ;
2010-03-06 21:20:48 +03:00
case REG_BINARY :
2007-08-26 19:16:40 +04:00
default :
2010-03-21 16:10:17 +03:00
if ( ( data . length > 0 ) & & ( data . data ! = NULL ) ) {
2010-03-13 21:29:03 +03:00
ret = ldb_msg_add_value ( msg , " data " , & data , NULL ) ;
2010-03-06 21:20:48 +03:00
} else {
2010-03-13 21:29:03 +03:00
ret = ldb_msg_add_empty ( msg , " data " , LDB_FLAG_MOD_DELETE , NULL ) ;
2010-03-06 21:20:48 +03:00
}
break ;
2007-08-26 19:16:40 +04:00
}
2010-03-13 21:29:03 +03:00
if ( ret ! = LDB_SUCCESS ) {
talloc_free ( msg ) ;
return NULL ;
}
type_str = talloc_asprintf ( mem_ctx , " %u " , type ) ;
if ( type_str = = NULL ) {
talloc_free ( msg ) ;
return NULL ;
}
ret = ldb_msg_add_string ( msg , " type " , type_str ) ;
if ( ret ! = LDB_SUCCESS ) {
talloc_free ( msg ) ;
return NULL ;
}
2007-08-26 19:16:40 +04:00
return msg ;
}
2008-01-18 03:50:33 +03:00
static char * reg_ldb_escape ( TALLOC_CTX * mem_ctx , const char * value )
{
struct ldb_val val ;
val . data = discard_const_p ( uint8_t , value ) ;
val . length = strlen ( value ) ;
return ldb_dn_escape_value ( mem_ctx , val ) ;
}
2007-08-26 19:16:40 +04:00
static int reg_close_ldb_key ( struct ldb_key_data * key )
{
if ( key - > subkeys ! = NULL ) {
2007-10-06 04:17:44 +04:00
talloc_free ( key - > subkeys ) ;
2007-08-26 19:16:40 +04:00
key - > subkeys = NULL ;
}
if ( key - > values ! = NULL ) {
2007-10-06 04:17:44 +04:00
talloc_free ( key - > values ) ;
2007-08-26 19:16:40 +04:00
key - > values = NULL ;
}
return 0 ;
}
2007-10-06 04:17:44 +04:00
static struct ldb_dn * reg_path_to_ldb ( TALLOC_CTX * mem_ctx ,
const struct hive_key * from ,
const char * path , const char * add )
2007-08-26 19:16:40 +04:00
{
struct ldb_dn * ret ;
2010-06-24 23:12:19 +04:00
char * mypath ;
2007-08-26 19:16:40 +04:00
char * begin ;
struct ldb_key_data * kd = talloc_get_type ( from , struct ldb_key_data ) ;
struct ldb_context * ldb = kd - > ldb ;
2010-06-24 23:12:19 +04:00
mypath = talloc_strdup ( mem_ctx , path ) ;
if ( mypath = = NULL ) {
return NULL ;
}
2010-03-10 11:10:53 +03:00
ret = ldb_dn_new ( mem_ctx , ldb , add ) ;
2007-08-26 19:16:40 +04:00
if ( ! ldb_dn_validate ( ret ) ) {
talloc_free ( ret ) ;
return NULL ;
}
2010-06-24 23:12:19 +04:00
if ( ! ldb_dn_add_base ( ret , kd - > dn ) ) {
talloc_free ( ret ) ;
return NULL ;
}
2007-08-26 19:16:40 +04:00
2010-06-24 23:12:19 +04:00
while ( mypath [ 0 ] ! = ' \0 ' ) {
begin = strchr ( mypath , ' \\ ' ) ;
if ( begin ! = NULL ) {
* begin = ' \0 ' ;
}
2007-08-26 19:16:40 +04:00
2010-06-24 23:12:19 +04:00
if ( ! ldb_dn_add_child_fmt ( ret , " key=%s " ,
reg_ldb_escape ( mem_ctx , mypath ) ) ) {
talloc_free ( ret ) ;
return NULL ;
2007-08-26 19:16:40 +04:00
}
2010-06-24 23:12:19 +04:00
if ( begin ! = NULL ) {
mypath = begin + 1 ;
2007-08-26 19:16:40 +04:00
} else {
break ;
}
}
return ret ;
}
static WERROR cache_subkeys ( struct ldb_key_data * kd )
{
struct ldb_context * c = kd - > ldb ;
struct ldb_result * res ;
int ret ;
2010-06-24 18:05:31 +04:00
ret = ldb_search ( c , c , & res , kd - > dn , LDB_SCOPE_ONELEVEL ,
NULL , " (key=*) " ) ;
2007-08-26 19:16:40 +04:00
if ( ret ! = LDB_SUCCESS ) {
2007-10-06 04:17:44 +04:00
DEBUG ( 0 , ( " Error getting subkeys for '%s': %s \n " ,
ldb_dn_get_linearized ( kd - > dn ) , ldb_errstring ( c ) ) ) ;
2007-08-26 19:16:40 +04:00
return WERR_FOOBAR ;
}
kd - > subkey_count = res - > count ;
kd - > subkeys = talloc_steal ( kd , res - > msgs ) ;
talloc_free ( res ) ;
return WERR_OK ;
}
static WERROR cache_values ( struct ldb_key_data * kd )
{
struct ldb_context * c = kd - > ldb ;
struct ldb_result * res ;
int ret ;
2008-09-23 22:30:06 +04:00
ret = ldb_search ( c , c , & res , kd - > dn , LDB_SCOPE_ONELEVEL ,
NULL , " (value=*) " ) ;
2007-08-26 19:16:40 +04:00
if ( ret ! = LDB_SUCCESS ) {
2007-10-06 04:17:44 +04:00
DEBUG ( 0 , ( " Error getting values for '%s': %s \n " ,
ldb_dn_get_linearized ( kd - > dn ) , ldb_errstring ( c ) ) ) ;
2007-08-26 19:16:40 +04:00
return WERR_FOOBAR ;
}
2008-09-14 05:51:35 +04:00
2007-08-26 19:16:40 +04:00
kd - > value_count = res - > count ;
kd - > values = talloc_steal ( kd , res - > msgs ) ;
talloc_free ( res ) ;
2008-09-14 05:51:35 +04:00
2007-08-26 19:16:40 +04:00
return WERR_OK ;
}
2007-10-06 04:17:44 +04:00
static WERROR ldb_get_subkey_by_id ( TALLOC_CTX * mem_ctx ,
const struct hive_key * k , uint32_t idx ,
const char * * name ,
const char * * classname ,
NTTIME * last_mod_time )
2007-08-26 19:16:40 +04:00
{
struct ldb_key_data * kd = talloc_get_type ( k , struct ldb_key_data ) ;
2010-03-06 21:39:45 +03:00
2008-09-13 15:32:39 +04:00
/* Initialization */
if ( name ! = NULL )
* name = NULL ;
if ( classname ! = NULL )
2010-06-24 18:17:16 +04:00
* classname = NULL ;
2008-09-13 15:32:39 +04:00
if ( last_mod_time ! = NULL )
* last_mod_time = 0 ; /* TODO: we need to add this to the
ldb backend properly */
2007-08-26 19:16:40 +04:00
/* Do a search if necessary */
if ( kd - > subkeys = = NULL ) {
W_ERROR_NOT_OK_RETURN ( cache_subkeys ( kd ) ) ;
2007-10-06 04:17:44 +04:00
}
2007-08-26 19:16:40 +04:00
2007-10-06 04:17:44 +04:00
if ( idx > = kd - > subkey_count )
2007-08-26 19:16:40 +04:00
return WERR_NO_MORE_ITEMS ;
if ( name ! = NULL )
2010-06-24 18:17:16 +04:00
* name = talloc_strdup ( mem_ctx ,
ldb_msg_find_attr_as_string ( kd - > subkeys [ idx ] , " key " , NULL ) ) ;
if ( classname ! = NULL )
* classname = talloc_strdup ( mem_ctx ,
ldb_msg_find_attr_as_string ( kd - > subkeys [ idx ] , " classname " , NULL ) ) ;
2007-08-26 19:16:40 +04:00
return WERR_OK ;
}
2010-03-22 00:02:19 +03:00
static WERROR ldb_get_default_value ( TALLOC_CTX * mem_ctx ,
const struct hive_key * k ,
2010-03-21 23:51:06 +03:00
const char * * name , uint32_t * data_type ,
DATA_BLOB * data )
2008-09-09 19:49:41 +04:00
{
struct ldb_key_data * kd = talloc_get_type ( k , struct ldb_key_data ) ;
struct ldb_context * c = kd - > ldb ;
const char * attrs [ ] = { " data " , " type " , NULL } ;
struct ldb_result * res ;
int ret ;
2011-10-25 22:08:31 +04:00
ret = ldb_search ( c , mem_ctx , & res , kd - > dn , LDB_SCOPE_BASE , attrs ,
NULL ) ;
2008-09-09 19:49:41 +04:00
if ( ret ! = LDB_SUCCESS ) {
DEBUG ( 0 , ( " Error getting default value for '%s': %s \n " ,
ldb_dn_get_linearized ( kd - > dn ) , ldb_errstring ( c ) ) ) ;
return WERR_FOOBAR ;
}
2010-07-01 18:35:12 +04:00
if ( res - > count = = 0 | | res - > msgs [ 0 ] - > num_elements = = 0 ) {
talloc_free ( res ) ;
2015-12-03 17:24:12 +03:00
return WERR_FILE_NOT_FOUND ;
2010-07-01 18:35:12 +04:00
}
2008-09-09 19:49:41 +04:00
2010-03-22 00:01:06 +03:00
if ( ( data_type ! = NULL ) & & ( data ! = NULL ) ) {
reg_ldb_unpack_value ( mem_ctx , res - > msgs [ 0 ] , name , data_type ,
data ) ;
}
2008-09-09 19:49:41 +04:00
talloc_free ( res ) ;
return WERR_OK ;
}
2007-12-14 12:38:26 +03:00
static WERROR ldb_get_value_by_id ( TALLOC_CTX * mem_ctx , struct hive_key * k ,
2009-11-07 23:07:20 +03:00
uint32_t idx , const char * * name ,
2007-10-06 04:17:44 +04:00
uint32_t * data_type , DATA_BLOB * data )
2007-08-26 19:16:40 +04:00
{
struct ldb_key_data * kd = talloc_get_type ( k , struct ldb_key_data ) ;
2010-06-24 18:06:11 +04:00
/* if the default value exists, give it back */
2008-09-14 05:51:35 +04:00
if ( W_ERROR_IS_OK ( ldb_get_default_value ( mem_ctx , k , name , data_type ,
data ) ) ) {
2008-09-13 14:10:00 +04:00
if ( idx = = 0 )
return WERR_OK ;
else
- - idx ;
2008-09-14 05:51:35 +04:00
}
2007-08-26 19:16:40 +04:00
2008-09-13 14:10:00 +04:00
/* Do the search if necessary */
if ( kd - > values = = NULL ) {
W_ERROR_NOT_OK_RETURN ( cache_values ( kd ) ) ;
}
2007-08-26 19:16:40 +04:00
2008-09-13 14:10:00 +04:00
if ( idx > = kd - > value_count )
return WERR_NO_MORE_ITEMS ;
2008-09-09 19:49:41 +04:00
2008-10-24 16:31:16 +04:00
reg_ldb_unpack_value ( mem_ctx , kd - > values [ idx ] , name , data_type , data ) ;
2007-08-26 19:16:40 +04:00
return WERR_OK ;
}
2007-10-06 04:17:44 +04:00
static WERROR ldb_get_value ( TALLOC_CTX * mem_ctx , struct hive_key * k ,
const char * name , uint32_t * data_type ,
DATA_BLOB * data )
2007-08-26 19:16:40 +04:00
{
struct ldb_key_data * kd = talloc_get_type ( k , struct ldb_key_data ) ;
2010-06-24 18:06:39 +04:00
const char * res_name ;
uint32_t idx ;
2007-08-26 19:16:40 +04:00
2010-06-24 18:06:39 +04:00
/* the default value was requested, give it back */
2010-03-10 11:47:02 +03:00
if ( name [ 0 ] = = ' \0 ' ) {
2008-09-09 19:49:41 +04:00
return ldb_get_default_value ( mem_ctx , k , NULL , data_type , data ) ;
2010-06-24 18:06:39 +04:00
}
2007-08-26 19:16:40 +04:00
2010-06-24 18:06:39 +04:00
/* Do the search if necessary */
if ( kd - > values = = NULL ) {
W_ERROR_NOT_OK_RETURN ( cache_values ( kd ) ) ;
}
2007-08-26 19:16:40 +04:00
2010-06-24 18:06:39 +04:00
for ( idx = 0 ; idx < kd - > value_count ; idx + + ) {
res_name = ldb_msg_find_attr_as_string ( kd - > values [ idx ] , " value " ,
" " ) ;
if ( ldb_attr_cmp ( name , res_name ) = = 0 ) {
reg_ldb_unpack_value ( mem_ctx , kd - > values [ idx ] , NULL ,
data_type , data ) ;
return WERR_OK ;
}
2008-09-09 19:49:41 +04:00
}
2007-08-26 19:16:40 +04:00
2015-12-03 17:24:12 +03:00
return WERR_FILE_NOT_FOUND ;
2007-08-26 19:16:40 +04:00
}
2007-10-06 04:17:44 +04:00
static WERROR ldb_open_key ( TALLOC_CTX * mem_ctx , const struct hive_key * h ,
const char * name , struct hive_key * * key )
2007-08-26 19:16:40 +04:00
{
struct ldb_result * res ;
2010-06-29 19:37:45 +04:00
struct ldb_dn * ldb_path ;
2007-08-26 19:16:40 +04:00
int ret ;
struct ldb_key_data * newkd ;
struct ldb_key_data * kd = talloc_get_type ( h , struct ldb_key_data ) ;
struct ldb_context * c = kd - > ldb ;
2010-06-29 19:37:45 +04:00
ldb_path = reg_path_to_ldb ( mem_ctx , h , name , NULL ) ;
W_ERROR_HAVE_NO_MEMORY ( ldb_path ) ;
2007-08-26 19:16:40 +04:00
2011-10-25 22:08:31 +04:00
ret = ldb_search ( c , mem_ctx , & res , ldb_path , LDB_SCOPE_BASE , NULL ,
NULL ) ;
2007-08-26 19:16:40 +04:00
if ( ret ! = LDB_SUCCESS ) {
2007-10-06 04:17:44 +04:00
DEBUG ( 3 , ( " Error opening key '%s': %s \n " ,
2010-06-29 19:37:45 +04:00
ldb_dn_get_linearized ( ldb_path ) , ldb_errstring ( c ) ) ) ;
2007-08-26 19:16:40 +04:00
return WERR_FOOBAR ;
} else if ( res - > count = = 0 ) {
2007-10-06 04:17:44 +04:00
DEBUG ( 3 , ( " Key '%s' not found \n " ,
2010-06-29 19:37:45 +04:00
ldb_dn_get_linearized ( ldb_path ) ) ) ;
2007-08-26 19:16:40 +04:00
talloc_free ( res ) ;
2015-12-03 17:24:12 +03:00
return WERR_FILE_NOT_FOUND ;
2007-08-26 19:16:40 +04:00
}
newkd = talloc_zero ( mem_ctx , struct ldb_key_data ) ;
2010-06-28 23:17:37 +04:00
W_ERROR_HAVE_NO_MEMORY ( newkd ) ;
2007-08-26 19:16:40 +04:00
newkd - > key . ops = & reg_backend_ldb ;
newkd - > ldb = talloc_reference ( newkd , kd - > ldb ) ;
2010-06-28 23:17:37 +04:00
newkd - > dn = ldb_dn_copy ( newkd , res - > msgs [ 0 ] - > dn ) ;
2010-06-28 23:15:17 +04:00
newkd - > classname = talloc_steal ( newkd ,
2010-06-29 01:12:10 +04:00
ldb_msg_find_attr_as_string ( res - > msgs [ 0 ] , " classname " , NULL ) ) ;
2007-08-26 19:16:40 +04:00
2010-06-28 23:17:37 +04:00
talloc_free ( res ) ;
2007-08-26 19:16:40 +04:00
* key = ( struct hive_key * ) newkd ;
return WERR_OK ;
}
2007-10-06 04:17:44 +04:00
WERROR reg_open_ldb_file ( TALLOC_CTX * parent_ctx , const char * location ,
2007-10-01 22:52:55 +04:00
struct auth_session_info * session_info ,
struct cli_credentials * credentials ,
2008-12-29 22:24:57 +03:00
struct tevent_context * ev_ctx ,
2007-12-14 02:27:31 +03:00
struct loadparm_context * lp_ctx ,
2007-10-01 22:52:55 +04:00
struct hive_key * * k )
2007-08-26 19:16:40 +04:00
{
struct ldb_key_data * kd ;
struct ldb_context * wrap ;
2008-01-08 08:41:55 +03:00
struct ldb_message * attrs_msg ;
2007-08-26 19:16:40 +04:00
2007-10-06 04:17:44 +04:00
if ( location = = NULL )
2015-12-03 17:24:26 +03:00
return WERR_INVALID_PARAMETER ;
2007-08-26 19:16:40 +04:00
2008-04-17 14:23:44 +04:00
wrap = ldb_wrap_connect ( parent_ctx , ev_ctx , lp_ctx ,
2009-10-23 07:27:00 +04:00
location , session_info , credentials , 0 ) ;
2007-08-26 19:16:40 +04:00
if ( wrap = = NULL ) {
DEBUG ( 1 , ( __FILE__ " : unable to connect \n " ) ) ;
return WERR_FOOBAR ;
}
2008-01-08 08:41:55 +03:00
attrs_msg = ldb_msg_new ( wrap ) ;
W_ERROR_HAVE_NO_MEMORY ( attrs_msg ) ;
attrs_msg - > dn = ldb_dn_new ( attrs_msg , wrap , " @ATTRIBUTES " ) ;
W_ERROR_HAVE_NO_MEMORY ( attrs_msg - > dn ) ;
ldb_msg_add_string ( attrs_msg , " key " , " CASE_INSENSITIVE " ) ;
ldb_msg_add_string ( attrs_msg , " value " , " CASE_INSENSITIVE " ) ;
ldb_add ( wrap , attrs_msg ) ;
2007-08-26 19:16:40 +04:00
ldb_set_debug_stderr ( wrap ) ;
kd = talloc_zero ( parent_ctx , struct ldb_key_data ) ;
kd - > key . ops = & reg_backend_ldb ;
kd - > ldb = talloc_reference ( kd , wrap ) ;
talloc_set_destructor ( kd , reg_close_ldb_key ) ;
kd - > dn = ldb_dn_new ( kd , wrap , " hive=NONE " ) ;
* k = ( struct hive_key * ) kd ;
return WERR_OK ;
}
2007-10-06 04:17:44 +04:00
static WERROR ldb_add_key ( TALLOC_CTX * mem_ctx , const struct hive_key * parent ,
const char * name , const char * classname ,
struct security_descriptor * sd ,
struct hive_key * * newkey )
2007-08-26 19:16:40 +04:00
{
2008-02-09 19:18:51 +03:00
struct ldb_key_data * parentkd = discard_const_p ( struct ldb_key_data , parent ) ;
2010-06-29 17:52:19 +04:00
struct ldb_dn * ldb_path ;
2007-08-26 19:16:40 +04:00
struct ldb_message * msg ;
struct ldb_key_data * newkd ;
int ret ;
2010-06-29 17:52:19 +04:00
ldb_path = reg_path_to_ldb ( mem_ctx , parent , name , NULL ) ;
W_ERROR_HAVE_NO_MEMORY ( ldb_path ) ;
2007-08-26 19:16:40 +04:00
msg = ldb_msg_new ( mem_ctx ) ;
2010-03-13 21:37:13 +03:00
W_ERROR_HAVE_NO_MEMORY ( msg ) ;
2007-08-26 19:16:40 +04:00
2010-06-29 17:52:19 +04:00
msg - > dn = ldb_path ;
2007-08-26 19:16:40 +04:00
2010-06-29 17:52:19 +04:00
ldb_msg_add_string ( msg , " key " , name ) ;
if ( classname ! = NULL ) {
ldb_msg_add_string ( msg , " classname " , classname ) ;
}
2007-08-26 19:16:40 +04:00
ret = ldb_add ( parentkd - > ldb , msg ) ;
2010-06-29 17:52:19 +04:00
talloc_free ( msg ) ;
2008-01-18 04:45:00 +03:00
if ( ret = = LDB_ERR_ENTRY_ALREADY_EXISTS ) {
return WERR_ALREADY_EXISTS ;
}
2008-01-18 03:48:48 +03:00
if ( ret ! = LDB_SUCCESS ) {
2008-01-18 04:45:00 +03:00
DEBUG ( 1 , ( " ldb_add: %s \n " , ldb_errstring ( parentkd - > ldb ) ) ) ;
2007-08-26 19:16:40 +04:00
return WERR_FOOBAR ;
2007-10-06 04:17:44 +04:00
}
2007-08-26 19:16:40 +04:00
2010-06-29 17:52:19 +04:00
DEBUG ( 2 , ( " key added: %s \n " , ldb_dn_get_linearized ( ldb_path ) ) ) ;
2007-08-26 19:16:40 +04:00
newkd = talloc_zero ( mem_ctx , struct ldb_key_data ) ;
2010-03-13 21:37:13 +03:00
W_ERROR_HAVE_NO_MEMORY ( newkd ) ;
2007-08-26 19:16:40 +04:00
newkd - > ldb = talloc_reference ( newkd , parentkd - > ldb ) ;
newkd - > key . ops = & reg_backend_ldb ;
2010-06-29 17:52:19 +04:00
newkd - > dn = talloc_steal ( newkd , ldb_path ) ;
2010-06-28 23:15:17 +04:00
newkd - > classname = talloc_steal ( newkd , classname ) ;
2007-08-26 19:16:40 +04:00
* newkey = ( struct hive_key * ) newkd ;
2008-01-18 05:37:06 +03:00
/* reset cache */
talloc_free ( parentkd - > subkeys ) ;
parentkd - > subkeys = NULL ;
2007-08-26 19:16:40 +04:00
return WERR_OK ;
}
2010-03-22 21:18:56 +03:00
static WERROR ldb_del_value ( TALLOC_CTX * mem_ctx , struct hive_key * key ,
const char * child )
2007-08-26 19:16:40 +04:00
{
int ret ;
struct ldb_key_data * kd = talloc_get_type ( key , struct ldb_key_data ) ;
2008-09-09 19:49:41 +04:00
struct ldb_message * msg ;
2007-08-26 19:16:40 +04:00
struct ldb_dn * childdn ;
2010-03-29 22:53:38 +04:00
if ( child [ 0 ] = = ' \0 ' ) {
2008-09-09 19:49:41 +04:00
/* default value */
2019-04-15 14:20:46 +03:00
msg = ldb_msg_new ( mem_ctx ) ;
2010-03-13 21:37:13 +03:00
W_ERROR_HAVE_NO_MEMORY ( msg ) ;
2008-09-09 19:49:41 +04:00
msg - > dn = ldb_dn_copy ( msg , kd - > dn ) ;
2010-03-13 21:37:13 +03:00
W_ERROR_HAVE_NO_MEMORY ( msg - > dn ) ;
2012-12-13 20:48:45 +04:00
ret = ldb_msg_add_empty ( msg , " data " , LDB_FLAG_MOD_DELETE , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
return WERR_FOOBAR ;
}
2015-03-06 14:02:49 +03:00
ret = ldb_msg_add_empty ( msg , " type " , LDB_FLAG_MOD_DELETE ,
NULL ) ;
2012-12-13 20:48:45 +04:00
if ( ret ! = LDB_SUCCESS ) {
return WERR_FOOBAR ;
}
2008-09-09 19:49:41 +04:00
ret = ldb_modify ( kd - > ldb , msg ) ;
2010-07-01 18:35:12 +04:00
talloc_free ( msg ) ;
2011-10-28 21:52:49 +04:00
if ( ret = = LDB_ERR_NO_SUCH_ATTRIBUTE ) {
2015-12-03 17:24:12 +03:00
return WERR_FILE_NOT_FOUND ;
2011-10-28 21:52:49 +04:00
} else if ( ret ! = LDB_SUCCESS ) {
2008-09-09 19:49:41 +04:00
DEBUG ( 1 , ( " ldb_del_value: %s \n " , ldb_errstring ( kd - > ldb ) ) ) ;
return WERR_FOOBAR ;
}
} else {
/* normal value */
childdn = ldb_dn_copy ( kd - > ldb , kd - > dn ) ;
if ( ! ldb_dn_add_child_fmt ( childdn , " value=%s " ,
2008-01-18 03:50:33 +03:00
reg_ldb_escape ( childdn , child ) ) )
2008-09-09 19:49:41 +04:00
{
talloc_free ( childdn ) ;
return WERR_FOOBAR ;
}
2007-08-26 19:16:40 +04:00
2008-09-09 19:49:41 +04:00
ret = ldb_delete ( kd - > ldb , childdn ) ;
2007-08-26 19:16:40 +04:00
2008-09-09 19:49:41 +04:00
talloc_free ( childdn ) ;
2007-08-26 19:16:40 +04:00
2008-09-09 19:49:41 +04:00
if ( ret = = LDB_ERR_NO_SUCH_OBJECT ) {
2015-12-03 17:24:12 +03:00
return WERR_FILE_NOT_FOUND ;
2008-09-09 19:49:41 +04:00
} else if ( ret ! = LDB_SUCCESS ) {
DEBUG ( 1 , ( " ldb_del_value: %s \n " , ldb_errstring ( kd - > ldb ) ) ) ;
return WERR_FOOBAR ;
}
}
2008-01-18 05:37:06 +03:00
2008-09-12 18:31:57 +04:00
/* reset cache */
talloc_free ( kd - > values ) ;
kd - > values = NULL ;
2007-08-26 19:16:40 +04:00
return WERR_OK ;
}
2010-03-22 21:18:56 +03:00
static WERROR ldb_del_key ( TALLOC_CTX * mem_ctx , const struct hive_key * key ,
const char * name )
2008-02-17 00:08:28 +03:00
{
2009-11-07 23:07:20 +03:00
unsigned int i ;
int ret ;
2008-02-17 00:08:28 +03:00
struct ldb_key_data * parentkd = talloc_get_type ( key , struct ldb_key_data ) ;
2010-06-29 19:37:45 +04:00
struct ldb_dn * ldb_path ;
2008-02-17 00:08:28 +03:00
struct ldb_context * c = parentkd - > ldb ;
struct ldb_result * res_keys ;
struct ldb_result * res_vals ;
WERROR werr ;
struct hive_key * hk ;
/* Verify key exists by opening it */
werr = ldb_open_key ( mem_ctx , key , name , & hk ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
return werr ;
}
2010-06-29 19:37:45 +04:00
ldb_path = reg_path_to_ldb ( mem_ctx , key , name , NULL ) ;
W_ERROR_HAVE_NO_MEMORY ( ldb_path ) ;
2008-02-17 00:08:28 +03:00
/* Search for subkeys */
2010-06-29 19:37:45 +04:00
ret = ldb_search ( c , mem_ctx , & res_keys , ldb_path , LDB_SCOPE_ONELEVEL ,
2008-09-23 22:30:06 +04:00
NULL , " (key=*) " ) ;
2008-02-17 00:08:28 +03:00
if ( ret ! = LDB_SUCCESS ) {
DEBUG ( 0 , ( " Error getting subkeys for '%s': %s \n " ,
2010-06-29 19:37:45 +04:00
ldb_dn_get_linearized ( ldb_path ) , ldb_errstring ( c ) ) ) ;
2008-02-17 00:08:28 +03:00
return WERR_FOOBAR ;
}
/* Search for values */
2010-06-29 19:37:45 +04:00
ret = ldb_search ( c , mem_ctx , & res_vals , ldb_path , LDB_SCOPE_ONELEVEL ,
2008-09-23 22:30:06 +04:00
NULL , " (value=*) " ) ;
2008-02-17 00:08:28 +03:00
if ( ret ! = LDB_SUCCESS ) {
DEBUG ( 0 , ( " Error getting values for '%s': %s \n " ,
2010-06-29 19:37:45 +04:00
ldb_dn_get_linearized ( ldb_path ) , ldb_errstring ( c ) ) ) ;
2008-02-17 00:08:28 +03:00
return WERR_FOOBAR ;
}
/* Start an explicit transaction */
ret = ldb_transaction_start ( c ) ;
if ( ret ! = LDB_SUCCESS ) {
DEBUG ( 0 , ( " ldb_transaction_start: %s \n " , ldb_errstring ( c ) ) ) ;
return WERR_FOOBAR ;
}
if ( res_keys - > count | | res_vals - > count )
{
/* Delete any subkeys */
for ( i = 0 ; i < res_keys - > count ; i + + )
{
2010-03-22 21:18:56 +03:00
werr = ldb_del_key ( mem_ctx , hk ,
ldb_msg_find_attr_as_string (
2008-02-17 00:08:28 +03:00
res_keys - > msgs [ i ] ,
" key " , NULL ) ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
ret = ldb_transaction_cancel ( c ) ;
return werr ;
}
}
/* Delete any values */
for ( i = 0 ; i < res_vals - > count ; i + + )
{
2010-03-22 21:18:56 +03:00
werr = ldb_del_value ( mem_ctx , hk ,
ldb_msg_find_attr_as_string (
2008-02-17 00:08:28 +03:00
res_vals - > msgs [ i ] ,
" value " , NULL ) ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
ret = ldb_transaction_cancel ( c ) ;
return werr ;
}
}
}
2010-07-01 18:35:12 +04:00
talloc_free ( res_keys ) ;
talloc_free ( res_vals ) ;
2008-02-17 00:08:28 +03:00
/* Delete the key itself */
2010-06-29 19:37:45 +04:00
ret = ldb_delete ( c , ldb_path ) ;
2008-02-17 00:08:28 +03:00
if ( ret ! = LDB_SUCCESS )
{
DEBUG ( 1 , ( " ldb_del_key: %s \n " , ldb_errstring ( c ) ) ) ;
ret = ldb_transaction_cancel ( c ) ;
return WERR_FOOBAR ;
}
/* Commit the transaction */
ret = ldb_transaction_commit ( c ) ;
if ( ret ! = LDB_SUCCESS )
{
DEBUG ( 0 , ( " ldb_transaction_commit: %s \n " , ldb_errstring ( c ) ) ) ;
ret = ldb_transaction_cancel ( c ) ;
return WERR_FOOBAR ;
}
/* reset cache */
talloc_free ( parentkd - > subkeys ) ;
parentkd - > subkeys = NULL ;
return WERR_OK ;
}
2007-10-06 04:17:44 +04:00
static WERROR ldb_set_value ( struct hive_key * parent ,
const char * name , uint32_t type ,
const DATA_BLOB data )
2007-08-26 19:16:40 +04:00
{
struct ldb_message * msg ;
struct ldb_key_data * kd = talloc_get_type ( parent , struct ldb_key_data ) ;
2010-03-06 21:36:01 +03:00
unsigned int i ;
2007-08-26 19:16:40 +04:00
int ret ;
TALLOC_CTX * mem_ctx = talloc_init ( " ldb_set_value " ) ;
msg = reg_ldb_pack_value ( kd - > ldb , mem_ctx , name , type , data ) ;
2010-03-13 21:37:13 +03:00
W_ERROR_HAVE_NO_MEMORY ( msg ) ;
2007-08-26 19:16:40 +04:00
msg - > dn = ldb_dn_copy ( msg , kd - > dn ) ;
2010-03-13 21:37:13 +03:00
W_ERROR_HAVE_NO_MEMORY ( msg - > dn ) ;
2010-03-06 21:36:01 +03:00
2010-03-29 22:53:38 +04:00
if ( name [ 0 ] ! = ' \0 ' ) {
2008-09-09 19:49:41 +04:00
/* For a default value, we add/overwrite the attributes to/of the hive.
2010-02-21 09:24:08 +03:00
For a normal value , we create a new child . */
2008-09-09 19:49:41 +04:00
if ( ! ldb_dn_add_child_fmt ( msg - > dn , " value=%s " ,
2008-01-18 03:50:33 +03:00
reg_ldb_escape ( mem_ctx , name ) ) )
2008-09-09 19:49:41 +04:00
{
talloc_free ( mem_ctx ) ;
return WERR_FOOBAR ;
}
2008-01-18 03:50:33 +03:00
}
2007-08-26 19:16:40 +04:00
2010-03-06 21:36:01 +03:00
/* Try first a "modify" and if this doesn't work do try an "add" */
for ( i = 0 ; i < msg - > num_elements ; i + + ) {
2022-06-14 12:12:39 +03:00
if ( LDB_FLAG_MOD_TYPE ( msg - > elements [ i ] . flags ) ! = LDB_FLAG_MOD_DELETE ) {
2010-03-06 21:36:01 +03:00
msg - > elements [ i ] . flags = LDB_FLAG_MOD_REPLACE ;
2007-08-26 19:16:40 +04:00
}
2010-03-06 21:36:01 +03:00
}
ret = ldb_modify ( kd - > ldb , msg ) ;
if ( ret = = LDB_ERR_NO_SUCH_OBJECT ) {
i = 0 ;
while ( i < msg - > num_elements ) {
2010-08-17 05:21:11 +04:00
if ( LDB_FLAG_MOD_TYPE ( msg - > elements [ i ] . flags ) = = LDB_FLAG_MOD_DELETE ) {
2010-03-06 21:36:01 +03:00
ldb_msg_remove_element ( msg , & msg - > elements [ i ] ) ;
} else {
+ + i ;
}
}
ret = ldb_add ( kd - > ldb , msg ) ;
}
if ( ret = = LDB_ERR_NO_SUCH_ATTRIBUTE ) {
/* ignore this -> the value didn't exist and also now doesn't */
ret = LDB_SUCCESS ;
2008-01-18 03:47:10 +03:00
}
2010-07-01 18:35:12 +04:00
talloc_free ( msg ) ;
2008-01-18 03:47:10 +03:00
if ( ret ! = LDB_SUCCESS ) {
2008-09-09 19:49:41 +04:00
DEBUG ( 1 , ( " ldb_set_value: %s \n " , ldb_errstring ( kd - > ldb ) ) ) ;
2008-01-18 03:47:10 +03:00
talloc_free ( mem_ctx ) ;
return WERR_FOOBAR ;
2007-08-26 19:16:40 +04:00
}
2007-10-06 04:17:44 +04:00
2008-01-18 05:37:06 +03:00
/* reset cache */
talloc_free ( kd - > values ) ;
kd - > values = NULL ;
2007-08-26 19:16:40 +04:00
talloc_free ( mem_ctx ) ;
return WERR_OK ;
}
2007-10-06 04:17:44 +04:00
static WERROR ldb_get_key_info ( TALLOC_CTX * mem_ctx ,
const struct hive_key * key ,
const char * * classname ,
uint32_t * num_subkeys ,
uint32_t * num_values ,
2008-01-07 23:11:29 +03:00
NTTIME * last_change_time ,
uint32_t * max_subkeynamelen ,
uint32_t * max_valnamelen ,
uint32_t * max_valbufsize )
2007-08-26 19:16:40 +04:00
{
struct ldb_key_data * kd = talloc_get_type ( key , struct ldb_key_data ) ;
2010-03-22 00:01:06 +03:00
uint32_t default_value_type = REG_NONE ;
DATA_BLOB default_value = { NULL , 0 } ;
WERROR werr ;
2007-08-26 19:16:40 +04:00
2008-09-13 15:32:39 +04:00
/* Initialization */
if ( classname ! = NULL )
* classname = NULL ;
if ( num_subkeys ! = NULL )
* num_subkeys = 0 ;
if ( num_values ! = NULL )
* num_values = 0 ;
if ( last_change_time ! = NULL )
* last_change_time = 0 ;
if ( max_subkeynamelen ! = NULL )
* max_subkeynamelen = 0 ;
if ( max_valnamelen ! = NULL )
* max_valnamelen = 0 ;
if ( max_valbufsize ! = NULL )
* max_valbufsize = 0 ;
2010-03-22 00:01:06 +03:00
/* We need this to get the default value (if it exists) for counting
* the values under the key and for finding out the longest value buffer
* size . If no default value exists the DATA_BLOB " default_value " will
* remain { NULL , 0 } . */
werr = ldb_get_default_value ( mem_ctx , key , NULL , & default_value_type ,
& default_value ) ;
2015-12-03 17:24:12 +03:00
if ( ( ! W_ERROR_IS_OK ( werr ) ) & & ( ! W_ERROR_EQUAL ( werr , WERR_FILE_NOT_FOUND ) ) ) {
2010-03-22 00:01:06 +03:00
return werr ;
}
2008-01-18 05:37:06 +03:00
if ( kd - > subkeys = = NULL ) {
W_ERROR_NOT_OK_RETURN ( cache_subkeys ( kd ) ) ;
}
if ( kd - > values = = NULL ) {
W_ERROR_NOT_OK_RETURN ( cache_values ( kd ) ) ;
}
2010-06-28 23:15:17 +04:00
if ( classname ! = NULL ) {
* classname = kd - > classname ;
}
2007-08-26 19:16:40 +04:00
if ( num_subkeys ! = NULL ) {
* num_subkeys = kd - > subkey_count ;
}
if ( num_values ! = NULL ) {
* num_values = kd - > value_count ;
2010-03-22 00:01:06 +03:00
/* also consider the default value if it exists */
if ( default_value . data ! = NULL ) {
+ + ( * num_values ) ;
}
2007-08-26 19:16:40 +04:00
}
2008-01-07 23:11:29 +03:00
if ( max_subkeynamelen ! = NULL ) {
2009-11-07 23:07:20 +03:00
unsigned int i ;
2008-01-07 23:11:29 +03:00
struct ldb_message_element * el ;
for ( i = 0 ; i < kd - > subkey_count ; i + + ) {
el = ldb_msg_find_element ( kd - > subkeys [ i ] , " key " ) ;
* max_subkeynamelen = MAX ( * max_subkeynamelen , el - > values [ 0 ] . length ) ;
}
}
if ( max_valnamelen ! = NULL | | max_valbufsize ! = NULL ) {
2009-11-07 23:07:20 +03:00
unsigned int i ;
2008-01-07 23:11:29 +03:00
struct ldb_message_element * el ;
W_ERROR_NOT_OK_RETURN ( cache_values ( kd ) ) ;
2010-03-22 00:01:06 +03:00
/* also consider the default value if it exists */
if ( ( max_valbufsize ! = NULL ) & & ( default_value . data ! = NULL ) ) {
* max_valbufsize = MAX ( * max_valbufsize ,
default_value . length ) ;
}
2008-01-07 23:11:29 +03:00
for ( i = 0 ; i < kd - > value_count ; i + + ) {
if ( max_valnamelen ! = NULL ) {
el = ldb_msg_find_element ( kd - > values [ i ] , " value " ) ;
* max_valnamelen = MAX ( * max_valnamelen , el - > values [ 0 ] . length ) ;
}
if ( max_valbufsize ! = NULL ) {
2008-09-15 21:21:38 +04:00
uint32_t data_type ;
2008-01-07 23:11:29 +03:00
DATA_BLOB data ;
2010-03-06 21:39:45 +03:00
reg_ldb_unpack_value ( mem_ctx ,
kd - > values [ i ] , NULL ,
2008-09-15 21:21:38 +04:00
& data_type , & data ) ;
2008-01-07 23:11:29 +03:00
* max_valbufsize = MAX ( * max_valbufsize , data . length ) ;
talloc_free ( data . data ) ;
}
}
}
2010-03-22 00:01:06 +03:00
talloc_free ( default_value . data ) ;
2007-08-26 19:16:40 +04:00
return WERR_OK ;
}
static struct hive_operations reg_backend_ldb = {
. name = " ldb " ,
. add_key = ldb_add_key ,
. del_key = ldb_del_key ,
. get_key_by_name = ldb_open_key ,
. enum_value = ldb_get_value_by_id ,
. enum_key = ldb_get_subkey_by_id ,
. set_value = ldb_set_value ,
. get_value_by_name = ldb_get_value ,
. delete_value = ldb_del_value ,
. get_key_info = ldb_get_key_info ,
} ;