2004-04-04 20:24:08 +04:00
/*
Unix SMB / CIFS implementation .
Transparent registry backend handling
Copyright ( C ) Jelmer Vernooij 2003 - 2004.
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 .
*/
# include "includes.h"
2005-09-04 18:47:19 +04:00
# include "lib/registry/registry.h"
2005-08-23 07:22:25 +04:00
# include "librpc/gen_ndr/winreg.h"
2004-04-04 20:24:08 +04:00
2004-12-15 03:16:54 +03:00
static const struct {
2005-01-31 18:58:54 +03:00
uint32_t id ;
2004-12-15 03:16:54 +03:00
const char * name ;
} reg_value_types [ ] = {
{ REG_SZ , " REG_SZ " } ,
{ REG_DWORD , " REG_DWORD " } ,
{ REG_BINARY , " REG_BINARY " } ,
{ REG_EXPAND_SZ , " REG_EXPAND_SZ " } ,
{ REG_NONE , " REG_NONE " } ,
{ 0 , NULL }
} ;
2004-04-04 20:24:08 +04:00
/* Return string description of registry value type */
const char * str_regtype ( int type )
{
2004-12-15 03:16:54 +03:00
int i ;
for ( i = 0 ; reg_value_types [ i ] . name ; i + + ) {
if ( reg_value_types [ i ] . id = = type )
return reg_value_types [ i ] . name ;
2004-04-04 20:24:08 +04:00
}
2004-12-15 03:16:54 +03:00
2004-04-04 20:24:08 +04:00
return " Unknown " ;
}
2005-09-29 15:51:06 +04:00
char * reg_val_data_string ( TALLOC_CTX * mem_ctx , uint32_t type , DATA_BLOB * data )
2004-04-04 20:24:08 +04:00
{
char * ret = NULL ;
2005-09-29 15:51:06 +04:00
if ( data - > length = = 0 ) return talloc_strdup ( mem_ctx , " " ) ;
2004-04-04 20:24:08 +04:00
2005-09-29 15:51:06 +04:00
switch ( type ) {
2004-04-04 20:24:08 +04:00
case REG_EXPAND_SZ :
2004-12-15 05:27:22 +03:00
case REG_SZ :
2005-09-29 15:51:06 +04:00
convert_string_talloc ( mem_ctx , CH_UTF16 , CH_UNIX , data - > data , data - > length , ( void * * ) & ret ) ;
2004-12-15 05:27:22 +03:00
return ret ;
2004-04-04 20:24:08 +04:00
case REG_BINARY :
2005-09-29 15:51:06 +04:00
ret = data_blob_hex_string ( mem_ctx , data ) ;
2004-04-04 20:24:08 +04:00
return ret ;
case REG_DWORD :
2005-09-29 15:51:06 +04:00
if ( * ( int * ) data - > data = = 0 )
2004-09-22 16:32:31 +04:00
return talloc_strdup ( mem_ctx , " 0 " ) ;
2005-09-29 15:51:06 +04:00
return talloc_asprintf ( mem_ctx , " 0x%x " , * ( int * ) data - > data ) ;
2004-04-04 20:24:08 +04:00
case REG_MULTI_SZ :
/* FIXME */
break ;
default :
break ;
}
return ret ;
}
2004-09-22 16:32:31 +04:00
char * reg_val_description ( TALLOC_CTX * mem_ctx , struct registry_value * val )
2004-04-04 20:24:08 +04:00
{
2005-09-29 15:51:06 +04:00
return talloc_asprintf ( mem_ctx , " %s = %s : %s " , val - > name ? val - > name : " <No Name> " , str_regtype ( val - > data_type ) , reg_val_data_string ( mem_ctx , val - > data_type , & val - > data ) ) ;
2004-04-04 20:24:08 +04:00
}
2005-09-29 15:51:06 +04:00
BOOL reg_string_to_val ( TALLOC_CTX * mem_ctx , const char * type_str , const char * data_str , uint32_t * type , DATA_BLOB * data )
2004-04-04 20:24:08 +04:00
{
2004-12-15 03:16:54 +03:00
int i ;
2005-09-29 15:51:06 +04:00
* type = - 1 ;
2004-12-15 03:16:54 +03:00
/* Find the correct type */
for ( i = 0 ; reg_value_types [ i ] . name ; i + + ) {
if ( ! strcmp ( reg_value_types [ i ] . name , type_str ) ) {
2005-09-29 15:51:06 +04:00
* type = reg_value_types [ i ] . id ;
2004-12-15 03:16:54 +03:00
break ;
}
}
2005-09-29 15:51:06 +04:00
if ( * type = = - 1 )
2004-12-15 03:16:54 +03:00
return False ;
/* Convert data appropriately */
2005-09-29 15:51:06 +04:00
switch ( * type )
2004-12-15 03:16:54 +03:00
{
case REG_SZ :
case REG_EXPAND_SZ :
2005-09-29 15:51:06 +04:00
data - > length = convert_string_talloc ( mem_ctx , CH_UNIX , CH_UTF16 , data_str , strlen ( data_str ) , ( void * * ) & data - > data ) ;
2004-12-15 03:16:54 +03:00
break ;
2005-09-03 21:17:30 +04:00
case REG_DWORD : {
uint32_t tmp = strtol ( data_str , NULL , 0 ) ;
2005-09-29 15:51:06 +04:00
* data = data_blob_talloc ( mem_ctx , & tmp , 4 ) ;
2005-09-03 21:17:30 +04:00
}
2004-12-15 03:16:54 +03:00
break ;
case REG_NONE :
2005-09-29 15:51:06 +04:00
ZERO_STRUCT ( data ) ;
2004-12-15 03:16:54 +03:00
break ;
2005-09-29 15:51:06 +04:00
case REG_BINARY :
* data = strhex_to_data_blob ( data_str ) ;
talloc_steal ( mem_ctx , data - > data ) ;
break ;
2004-12-15 03:16:54 +03:00
default :
2005-09-29 15:51:06 +04:00
/* FIXME */
2004-12-15 03:16:54 +03:00
return False ;
}
return True ;
2004-04-04 20:24:08 +04:00
}
2004-04-05 14:28:59 +04:00
/**
* Replace all \ ' s with / ' s
*/
2004-04-04 20:24:08 +04:00
char * reg_path_win2unix ( char * path )
{
int i ;
for ( i = 0 ; path [ i ] ; i + + ) {
if ( path [ i ] = = ' \\ ' ) path [ i ] = ' / ' ;
}
return path ;
}
2004-04-05 14:28:59 +04:00
/**
* Replace all / ' s with \ ' s
*/
2004-04-04 20:24:08 +04:00
char * reg_path_unix2win ( char * path )
{
int i ;
for ( i = 0 ; path [ i ] ; i + + ) {
if ( path [ i ] = = ' / ' ) path [ i ] = ' \\ ' ;
}
return path ;
}
2004-12-14 23:49:18 +03:00
/* Open a key by name (including the predefined key name!) */
WERROR reg_open_key_abs ( TALLOC_CTX * mem_ctx , struct registry_context * handle , const char * name , struct registry_key * * result )
{
struct registry_key * predef ;
WERROR error ;
int predeflength ;
char * predefname ;
if ( strchr ( name , ' \\ ' ) ) predeflength = strchr ( name , ' \\ ' ) - name ;
else predeflength = strlen ( name ) ;
predefname = strndup ( name , predeflength ) ;
error = reg_get_predefined_key_by_name ( handle , predefname , & predef ) ;
SAFE_FREE ( predefname ) ;
if ( ! W_ERROR_IS_OK ( error ) ) {
return error ;
}
if ( strchr ( name , ' \\ ' ) ) {
return reg_open_key ( mem_ctx , predef , strchr ( name , ' \\ ' ) + 1 , result ) ;
} else {
* result = predef ;
return WERR_OK ;
}
}
static WERROR get_abs_parent ( TALLOC_CTX * mem_ctx , struct registry_context * ctx , const char * path , struct registry_key * * parent , const char * * name )
{
char * parent_name ;
WERROR error ;
if ( strchr ( path , ' \\ ' ) = = NULL ) {
return WERR_FOOBAR ;
}
parent_name = talloc_strndup ( mem_ctx , path , strrchr ( path , ' \\ ' ) - 1 - path ) ;
error = reg_open_key_abs ( mem_ctx , ctx , parent_name , parent ) ;
if ( ! W_ERROR_IS_OK ( error ) ) {
return error ;
}
* name = talloc_strdup ( mem_ctx , strchr ( path , ' \\ ' ) + 1 ) ;
return WERR_OK ;
}
WERROR reg_key_del_abs ( struct registry_context * ctx , const char * path )
{
struct registry_key * parent ;
const char * n ;
TALLOC_CTX * mem_ctx = talloc_init ( " reg_key_del_abs " ) ;
WERROR error ;
if ( ! strchr ( path , ' \\ ' ) ) {
return WERR_FOOBAR ;
}
error = get_abs_parent ( mem_ctx , ctx , path , & parent , & n ) ;
if ( W_ERROR_IS_OK ( error ) ) {
error = reg_key_del ( parent , n ) ;
}
2005-01-27 10:08:20 +03:00
talloc_free ( mem_ctx ) ;
2004-12-14 23:49:18 +03:00
return error ;
}
2005-01-31 18:58:54 +03:00
WERROR reg_key_add_abs ( TALLOC_CTX * mem_ctx , struct registry_context * ctx , const char * path , uint32_t access_mask , struct security_descriptor * sec_desc , struct registry_key * * result )
2004-12-14 23:49:18 +03:00
{
struct registry_key * parent ;
const char * n ;
WERROR error ;
if ( ! strchr ( path , ' \\ ' ) ) {
return WERR_FOOBAR ;
}
error = get_abs_parent ( mem_ctx , ctx , path , & parent , & n ) ;
if ( W_ERROR_IS_OK ( error ) ) {
error = reg_key_add_name ( mem_ctx , parent , n , access_mask , sec_desc , result ) ;
}
return error ;
}