2007-10-06 04:17:44 +04:00
/*
2007-08-26 19:16:40 +04:00
Unix SMB / CIFS implementation .
Transparent registry backend handling
Copyright ( C ) Jelmer Vernooij 2003 - 2007.
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 .
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 , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
2008-10-11 23:31:42 +04:00
# include "../lib/util/dlinklist.h"
2007-08-26 19:16:40 +04:00
# include "lib/registry/registry.h"
# include "system/filesys.h"
2020-08-07 23:27:39 +03:00
# undef strcasecmp
2007-08-26 19:16:40 +04:00
/**
* @ file
* @ brief Main registry functions
*/
const struct reg_predefined_key reg_predefined_keys [ ] = {
{ HKEY_CLASSES_ROOT , " HKEY_CLASSES_ROOT " } ,
{ HKEY_CURRENT_USER , " HKEY_CURRENT_USER " } ,
{ HKEY_LOCAL_MACHINE , " HKEY_LOCAL_MACHINE " } ,
{ HKEY_PERFORMANCE_DATA , " HKEY_PERFORMANCE_DATA " } ,
{ HKEY_USERS , " HKEY_USERS " } ,
{ HKEY_CURRENT_CONFIG , " HKEY_CURRENT_CONFIG " } ,
{ HKEY_DYN_DATA , " HKEY_DYN_DATA " } ,
{ HKEY_PERFORMANCE_TEXT , " HKEY_PERFORMANCE_TEXT " } ,
{ HKEY_PERFORMANCE_NLSTEXT , " HKEY_PERFORMANCE_NLSTEXT " } ,
{ 0 , NULL }
} ;
/** Obtain name of specific hkey. */
_PUBLIC_ const char * reg_get_predef_name ( uint32_t hkey )
{
2009-11-07 23:07:20 +03:00
unsigned int i ;
2007-08-26 19:16:40 +04:00
for ( i = 0 ; reg_predefined_keys [ i ] . name ; i + + ) {
2007-10-06 04:17:44 +04:00
if ( reg_predefined_keys [ i ] . handle = = hkey )
2007-08-26 19:16:40 +04:00
return reg_predefined_keys [ i ] . name ;
}
return NULL ;
}
/** Get predefined key by name. */
2007-10-06 04:17:44 +04:00
_PUBLIC_ WERROR reg_get_predefined_key_by_name ( struct registry_context * ctx ,
const char * name ,
struct registry_key * * key )
2007-08-26 19:16:40 +04:00
{
2009-11-07 23:07:20 +03:00
unsigned int i ;
2007-10-06 04:17:44 +04:00
2007-08-26 19:16:40 +04:00
for ( i = 0 ; reg_predefined_keys [ i ] . name ; i + + ) {
2007-10-06 04:17:44 +04:00
if ( ! strcasecmp ( reg_predefined_keys [ i ] . name , name ) )
return reg_get_predefined_key ( ctx ,
reg_predefined_keys [ i ] . handle ,
key ) ;
2007-08-26 19:16:40 +04:00
}
DEBUG ( 1 , ( " No predefined key with name '%s' \n " , name ) ) ;
2007-10-06 04:17:44 +04:00
2015-12-03 17:24:12 +03:00
return WERR_FILE_NOT_FOUND ;
2007-08-26 19:16:40 +04:00
}
/** Get predefined key by id. */
2007-12-14 12:38:26 +03:00
_PUBLIC_ WERROR reg_get_predefined_key ( struct registry_context * ctx ,
2007-10-06 04:17:44 +04:00
uint32_t hkey , struct registry_key * * key )
2007-08-26 19:16:40 +04:00
{
return ctx - > ops - > get_predefined_key ( ctx , hkey , key ) ;
}
/**
2007-10-06 04:17:44 +04:00
* Open a key
2007-08-26 19:16:40 +04:00
* First tries to use the open_key function from the backend
2007-10-06 04:17:44 +04:00
* then falls back to get_subkey_by_name and later get_subkey_by_index
2007-08-26 19:16:40 +04:00
*/
2007-10-06 04:17:44 +04:00
_PUBLIC_ WERROR reg_open_key ( TALLOC_CTX * mem_ctx , struct registry_key * parent ,
const char * name , struct registry_key * * result )
2007-08-26 19:16:40 +04:00
{
if ( parent = = NULL ) {
2007-10-06 04:17:44 +04:00
DEBUG ( 0 , ( " Invalid parent key specified for open of '%s' \n " ,
name ) ) ;
2015-12-03 17:24:26 +03:00
return WERR_INVALID_PARAMETER ;
2007-08-26 19:16:40 +04:00
}
if ( parent - > context - > ops - > open_key = = NULL ) {
DEBUG ( 0 , ( " Registry backend doesn't have open_key! \n " ) ) ;
return WERR_NOT_SUPPORTED ;
}
return parent - > context - > ops - > open_key ( mem_ctx , parent , name , result ) ;
}
/**
* Get value by index
*/
2007-10-06 04:17:44 +04:00
_PUBLIC_ WERROR reg_key_get_value_by_index ( TALLOC_CTX * mem_ctx ,
const struct registry_key * key ,
2007-09-16 23:14:46 +04:00
uint32_t idx , const char * * name ,
uint32_t * type , DATA_BLOB * data )
2007-08-26 19:16:40 +04:00
{
2007-10-06 04:17:44 +04:00
if ( key = = NULL )
2015-12-03 17:24:26 +03:00
return WERR_INVALID_PARAMETER ;
2007-08-26 19:16:40 +04:00
if ( key - > context - > ops - > enum_value = = NULL )
return WERR_NOT_SUPPORTED ;
2007-10-06 04:17:44 +04:00
return key - > context - > ops - > enum_value ( mem_ctx , key , idx , name ,
type , data ) ;
2007-08-26 19:16:40 +04:00
}
2007-10-06 04:17:44 +04:00
/**
2007-08-26 19:16:40 +04:00
* Get the number of subkeys .
*/
2007-10-06 04:17:44 +04:00
_PUBLIC_ WERROR reg_key_get_info ( TALLOC_CTX * mem_ctx ,
const struct registry_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
{
2007-10-06 04:17:44 +04:00
if ( key = = NULL )
2015-12-03 17:24:26 +03:00
return WERR_INVALID_PARAMETER ;
2007-10-06 04:17:44 +04:00
2007-08-26 19:16:40 +04:00
if ( key - > context - > ops - > get_key_info = = NULL )
return WERR_NOT_SUPPORTED ;
return key - > context - > ops - > get_key_info ( mem_ctx ,
2007-10-06 04:17:44 +04:00
key , classname , num_subkeys ,
2008-01-07 23:11:29 +03:00
num_values , last_change_time ,
max_subkeynamelen ,
max_valnamelen , max_valbufsize ) ;
2007-08-26 19:16:40 +04:00
}
/**
* Get subkey by index .
*/
2007-10-06 04:17:44 +04:00
_PUBLIC_ WERROR reg_key_get_subkey_by_index ( TALLOC_CTX * mem_ctx ,
const struct registry_key * key ,
2009-11-07 23:07:20 +03:00
uint32_t idx , const char * * name ,
2007-10-06 04:17:44 +04:00
const char * * keyclass ,
NTTIME * last_changed_time )
2007-08-26 19:16:40 +04:00
{
2007-10-06 04:17:44 +04:00
if ( key = = NULL )
2015-12-03 17:24:26 +03:00
return WERR_INVALID_PARAMETER ;
2007-08-26 19:16:40 +04:00
if ( key - > context - > ops - > enum_key = = NULL )
return WERR_NOT_SUPPORTED ;
return key - > context - > ops - > enum_key ( mem_ctx , key , idx , name ,
2007-10-06 04:17:44 +04:00
keyclass , last_changed_time ) ;
2007-08-26 19:16:40 +04:00
}
/**
* Get value by name .
*/
2007-10-06 04:17:44 +04:00
_PUBLIC_ WERROR reg_key_get_value_by_name ( TALLOC_CTX * mem_ctx ,
const struct registry_key * key ,
const char * name ,
uint32_t * type ,
DATA_BLOB * data )
2007-08-26 19:16:40 +04:00
{
2007-10-06 04:17:44 +04:00
if ( key = = NULL )
2015-12-03 17:24:26 +03:00
return WERR_INVALID_PARAMETER ;
2007-08-26 19:16:40 +04:00
if ( key - > context - > ops - > get_value = = NULL )
return WERR_NOT_SUPPORTED ;
return key - > context - > ops - > get_value ( mem_ctx , key , name , type , data ) ;
}
/**
* Delete a key .
*/
2010-03-22 21:18:56 +03:00
_PUBLIC_ WERROR reg_key_del ( TALLOC_CTX * mem_ctx , struct registry_key * parent ,
const char * name )
2007-08-26 19:16:40 +04:00
{
2007-10-06 04:17:44 +04:00
if ( parent = = NULL )
2015-12-03 17:24:26 +03:00
return WERR_INVALID_PARAMETER ;
2007-10-06 04:17:44 +04:00
2007-08-26 19:16:40 +04:00
if ( parent - > context - > ops - > delete_key = = NULL )
return WERR_NOT_SUPPORTED ;
2007-10-06 04:17:44 +04:00
2010-03-22 21:18:56 +03:00
return parent - > context - > ops - > delete_key ( mem_ctx , parent , name ) ;
2007-08-26 19:16:40 +04:00
}
/**
* Add a key .
*/
2007-10-06 04:17:44 +04:00
_PUBLIC_ WERROR reg_key_add_name ( TALLOC_CTX * mem_ctx ,
struct registry_key * parent ,
2010-06-29 20:08:47 +04:00
const char * path , const char * key_class ,
2007-10-06 04:17:44 +04:00
struct security_descriptor * desc ,
struct registry_key * * newkey )
2007-08-26 19:16:40 +04:00
{
2007-10-06 04:17:44 +04:00
if ( parent = = NULL )
2015-12-03 17:24:26 +03:00
return WERR_INVALID_PARAMETER ;
2007-10-06 04:17:44 +04:00
2007-08-26 19:16:40 +04:00
if ( parent - > context - > ops - > create_key = = NULL ) {
2007-10-06 04:17:44 +04:00
DEBUG ( 1 , ( " Backend '%s' doesn't support method add_key \n " ,
2007-08-26 19:16:40 +04:00
parent - > context - > ops - > name ) ) ;
return WERR_NOT_SUPPORTED ;
}
2010-06-29 20:08:47 +04:00
return parent - > context - > ops - > create_key ( mem_ctx , parent , path ,
2007-10-06 04:17:44 +04:00
key_class , desc , newkey ) ;
2007-08-26 19:16:40 +04:00
}
/**
* Set a value .
*/
2007-10-06 04:17:44 +04:00
_PUBLIC_ WERROR reg_val_set ( struct registry_key * key , const char * value ,
uint32_t type , const DATA_BLOB data )
2007-08-26 19:16:40 +04:00
{
if ( key = = NULL )
2015-12-03 17:24:26 +03:00
return WERR_INVALID_PARAMETER ;
2007-08-26 19:16:40 +04:00
/* A 'real' set function has preference */
if ( key - > context - > ops - > set_value = = NULL ) {
2007-10-06 04:17:44 +04:00
DEBUG ( 1 , ( " Backend '%s' doesn't support method set_value \n " ,
2007-08-26 19:16:40 +04:00
key - > context - > ops - > name ) ) ;
return WERR_NOT_SUPPORTED ;
}
return key - > context - > ops - > set_value ( key , value , type , data ) ;
}
/**
* Get the security descriptor on a key .
*/
2007-10-06 04:17:44 +04:00
_PUBLIC_ WERROR reg_get_sec_desc ( TALLOC_CTX * ctx ,
const struct registry_key * key ,
struct security_descriptor * * secdesc )
2007-08-26 19:16:40 +04:00
{
if ( key = = NULL )
2015-12-03 17:24:26 +03:00
return WERR_INVALID_PARAMETER ;
2007-08-26 19:16:40 +04:00
/* A 'real' set function has preference */
2008-04-15 00:52:51 +04:00
if ( key - > context - > ops - > get_sec_desc = = NULL )
2007-08-26 19:16:40 +04:00
return WERR_NOT_SUPPORTED ;
2008-04-15 00:52:51 +04:00
return key - > context - > ops - > get_sec_desc ( ctx , key , secdesc ) ;
2007-08-26 19:16:40 +04:00
}
/**
* Delete a value .
*/
2010-03-22 21:18:56 +03:00
_PUBLIC_ WERROR reg_del_value ( TALLOC_CTX * mem_ctx , struct registry_key * key ,
const char * valname )
2007-08-26 19:16:40 +04:00
{
if ( key = = NULL )
2015-12-03 17:24:26 +03:00
return WERR_INVALID_PARAMETER ;
2007-08-26 19:16:40 +04:00
if ( key - > context - > ops - > delete_value = = NULL )
return WERR_NOT_SUPPORTED ;
2010-03-22 21:18:56 +03:00
return key - > context - > ops - > delete_value ( mem_ctx , key , valname ) ;
2007-08-26 19:16:40 +04:00
}
/**
* Flush a key to disk .
*/
_PUBLIC_ WERROR reg_key_flush ( struct registry_key * key )
{
if ( key = = NULL )
2015-12-03 17:24:26 +03:00
return WERR_INVALID_PARAMETER ;
2007-10-06 04:17:44 +04:00
2007-08-26 19:16:40 +04:00
if ( key - > context - > ops - > flush_key = = NULL )
return WERR_NOT_SUPPORTED ;
return key - > context - > ops - > flush_key ( key ) ;
}
2007-08-28 02:01:58 +04:00
2008-04-15 00:52:51 +04:00
_PUBLIC_ WERROR reg_set_sec_desc ( struct registry_key * key ,
2008-04-16 00:19:05 +04:00
const struct security_descriptor * security )
2007-08-28 02:01:58 +04:00
{
if ( key = = NULL )
2015-12-03 17:24:26 +03:00
return WERR_INVALID_PARAMETER ;
2007-10-06 04:17:44 +04:00
2008-04-15 00:52:51 +04:00
if ( key - > context - > ops - > set_sec_desc = = NULL )
2007-08-28 02:01:58 +04:00
return WERR_NOT_SUPPORTED ;
2008-04-15 00:52:51 +04:00
return key - > context - > ops - > set_sec_desc ( key , security ) ;
2007-08-28 02:01:58 +04:00
}