2008-01-17 01:18:07 +03:00
/*
2007-04-09 14:38:55 +04:00
* Unix SMB / CIFS implementation .
* Virtual Windows Registry Layer
* Copyright ( C ) Gerald Carter 2002 - 2005
2008-01-17 01:18:07 +03:00
* Copyright ( C ) Michael Adam 2006 - 2008
2007-04-09 14:38:55 +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
2007-07-09 23:25:36 +04:00
* the Free Software Foundation ; either version 3 of the License , or
2007-04-09 14:38:55 +04:00
* ( at your option ) any later version .
2008-01-17 01:18:07 +03:00
*
2007-04-09 14:38:55 +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 .
2008-01-17 01:18:07 +03:00
*
2007-04-09 14:38:55 +04:00
* You should have received a copy of the GNU General Public License
2007-07-10 09:23:25 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2007-04-09 14:38:55 +04:00
*/
2008-01-17 01:18:07 +03:00
/*
* Implementation of registry frontend view functions .
2007-04-09 14:38:55 +04:00
* Functions moved from reg_frontend . c to minimize linker deps .
*/
# include "includes.h"
2007-09-29 03:05:52 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_REGISTRY
2007-04-09 14:38:55 +04:00
2007-10-06 01:41:17 +04:00
static const struct generic_mapping reg_generic_map =
2007-04-09 14:38:55 +04:00
{ REG_KEY_READ , REG_KEY_WRITE , REG_KEY_EXECUTE , REG_KEY_ALL } ;
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-02-18 16:55:48 +03:00
static WERROR construct_registry_sd ( TALLOC_CTX * ctx , SEC_DESC * * psd )
2007-04-09 14:38:55 +04:00
{
2007-09-27 01:46:43 +04:00
SEC_ACE ace [ 3 ] ;
2007-04-09 14:38:55 +04:00
SEC_ACCESS mask ;
size_t i = 0 ;
SEC_DESC * sd ;
SEC_ACL * acl ;
size_t sd_size ;
/* basic access for Everyone */
2008-01-17 01:18:07 +03:00
2008-02-18 16:44:51 +03:00
init_sec_access ( & mask , REG_KEY_READ ) ;
init_sec_ace ( & ace [ i + + ] , & global_sid_World , SEC_ACE_TYPE_ACCESS_ALLOWED ,
mask , 0 ) ;
2008-01-17 01:18:07 +03:00
2007-04-09 14:38:55 +04:00
/* Full Access 'BUILTIN\Administrators' */
2008-01-17 01:18:07 +03:00
2008-02-18 16:44:51 +03:00
init_sec_access ( & mask , REG_KEY_ALL ) ;
init_sec_ace ( & ace [ i + + ] , & global_sid_Builtin_Administrators ,
SEC_ACE_TYPE_ACCESS_ALLOWED , mask , 0 ) ;
2007-09-27 01:46:43 +04:00
/* Full Access 'NT Authority\System' */
init_sec_access ( & mask , REG_KEY_ALL ) ;
2008-02-18 16:44:51 +03:00
init_sec_ace ( & ace [ i + + ] , & global_sid_System , SEC_ACE_TYPE_ACCESS_ALLOWED ,
mask , 0 ) ;
2007-09-27 01:46:43 +04:00
2007-04-09 14:38:55 +04:00
/* create the security descriptor */
2008-01-17 01:18:07 +03:00
2008-02-18 16:44:51 +03:00
acl = make_sec_acl ( ctx , NT4_ACL_REVISION , i , ace ) ;
if ( acl = = NULL ) {
2008-02-18 16:55:48 +03:00
return WERR_NOMEM ;
2008-02-18 16:44:51 +03:00
}
2007-04-09 14:38:55 +04:00
2008-02-18 16:44:51 +03:00
sd = make_sec_desc ( ctx , SEC_DESC_REVISION , SEC_DESC_SELF_RELATIVE ,
2008-02-18 18:03:16 +03:00
& global_sid_Builtin_Administrators ,
& global_sid_System , NULL , acl ,
2008-02-18 16:44:51 +03:00
& sd_size ) ;
if ( sd = = NULL ) {
2008-02-18 16:55:48 +03:00
return WERR_NOMEM ;
2008-02-18 16:44:51 +03:00
}
2007-04-09 14:38:55 +04:00
2008-02-18 16:55:48 +03:00
* psd = sd ;
return WERR_OK ;
2007-04-09 14:38:55 +04:00
}
/***********************************************************************
High level wrapper function for storing registry subkeys
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-01-17 01:18:07 +03:00
2007-10-19 04:40:25 +04:00
bool store_reg_keys ( REGISTRY_KEY * key , REGSUBKEY_CTR * subkeys )
2007-04-09 14:38:55 +04:00
{
2008-04-13 02:54:44 +04:00
if ( key - > ops & & key - > ops - > store_subkeys )
return key - > ops - > store_subkeys ( key - > name , subkeys ) ;
2007-04-09 14:38:55 +04:00
2008-01-17 01:19:38 +03:00
return false ;
2007-04-09 14:38:55 +04:00
}
/***********************************************************************
High level wrapper function for storing registry values
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-01-17 01:18:07 +03:00
2007-10-19 04:40:25 +04:00
bool store_reg_values ( REGISTRY_KEY * key , REGVAL_CTR * val )
2007-04-09 14:38:55 +04:00
{
2008-04-13 02:54:44 +04:00
if ( key - > ops & & key - > ops - > store_values )
return key - > ops - > store_values ( key - > name , val ) ;
2007-04-09 14:38:55 +04:00
2008-01-17 01:19:38 +03:00
return false ;
2007-04-09 14:38:55 +04:00
}
/***********************************************************************
High level wrapper function for enumerating registry subkeys
Initialize the TALLOC_CTX if necessary
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int fetch_reg_keys ( REGISTRY_KEY * key , REGSUBKEY_CTR * subkey_ctr )
{
int result = - 1 ;
2008-01-17 01:18:07 +03:00
2008-04-13 02:54:44 +04:00
if ( key - > ops & & key - > ops - > fetch_subkeys )
result = key - > ops - > fetch_subkeys ( key - > name , subkey_ctr ) ;
2007-04-09 14:38:55 +04:00
return result ;
}
/***********************************************************************
High level wrapper function for enumerating registry values
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int fetch_reg_values ( REGISTRY_KEY * key , REGVAL_CTR * val )
{
int result = - 1 ;
2008-01-17 01:18:07 +03:00
2008-01-18 19:57:32 +03:00
DEBUG ( 10 , ( " fetch_reg_values called for key '%s' (ops %p) \n " , key - > name ,
2008-04-13 02:54:44 +04:00
( key - > ops ) ? ( void * ) key - > ops : NULL ) ) ;
2008-01-18 19:57:32 +03:00
2008-04-13 02:54:44 +04:00
if ( key - > ops & & key - > ops - > fetch_values )
result = key - > ops - > fetch_values ( key - > name , val ) ;
2008-01-17 01:18:07 +03:00
2007-04-09 14:38:55 +04:00
return result ;
}
/***********************************************************************
2008-01-17 01:18:07 +03:00
High level access check for passing the required access mask to the
2007-04-09 14:38:55 +04:00
underlying registry backend
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
bool regkey_access_check ( REGISTRY_KEY * key , uint32 requested , uint32 * granted ,
2007-04-09 14:38:55 +04:00
const struct nt_user_token * token )
{
SEC_DESC * sec_desc ;
NTSTATUS status ;
WERROR err ;
TALLOC_CTX * mem_ctx ;
/* use the default security check if the backend has not defined its
* own */
2008-04-13 02:54:44 +04:00
if ( key - > ops & & key - > ops - > reg_access_check ) {
return key - > ops - > reg_access_check ( key - > name , requested ,
granted , token ) ;
2007-04-09 14:38:55 +04:00
}
/*
* The secdesc routines can ' t yet cope with a NULL talloc ctx sanely .
*/
if ( ! ( mem_ctx = talloc_init ( " regkey_access_check " ) ) ) {
2008-01-17 01:19:38 +03:00
return false ;
2007-04-09 14:38:55 +04:00
}
err = regkey_get_secdesc ( mem_ctx , key , & sec_desc ) ;
if ( ! W_ERROR_IS_OK ( err ) ) {
TALLOC_FREE ( mem_ctx ) ;
2008-01-17 01:19:38 +03:00
return false ;
2007-04-09 14:38:55 +04:00
}
se_map_generic ( & requested , & reg_generic_map ) ;
if ( ! se_access_check ( sec_desc , token , requested , granted , & status ) ) {
TALLOC_FREE ( mem_ctx ) ;
2008-01-17 01:19:38 +03:00
return false ;
2007-04-09 14:38:55 +04:00
}
TALLOC_FREE ( mem_ctx ) ;
return NT_STATUS_IS_OK ( status ) ;
}
WERROR regkey_get_secdesc ( TALLOC_CTX * mem_ctx , REGISTRY_KEY * key ,
struct security_descriptor * * psecdesc )
{
struct security_descriptor * secdesc ;
2008-02-18 16:55:48 +03:00
WERROR werr ;
2007-04-09 14:38:55 +04:00
2008-04-13 02:54:44 +04:00
if ( key - > ops & & key - > ops - > get_secdesc ) {
werr = key - > ops - > get_secdesc ( mem_ctx , key - > name , psecdesc ) ;
2008-02-18 16:55:48 +03:00
if ( W_ERROR_IS_OK ( werr ) ) {
2007-04-09 14:38:55 +04:00
return WERR_OK ;
}
}
2008-02-18 16:55:48 +03:00
werr = construct_registry_sd ( mem_ctx , & secdesc ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
return werr ;
2007-04-09 14:38:55 +04:00
}
* psecdesc = secdesc ;
return WERR_OK ;
}
2007-11-06 02:50:47 +03:00
WERROR regkey_set_secdesc ( REGISTRY_KEY * key ,
struct security_descriptor * psecdesc )
{
2008-04-13 02:54:44 +04:00
if ( key - > ops & & key - > ops - > set_secdesc ) {
return key - > ops - > set_secdesc ( key - > name , psecdesc ) ;
2007-11-06 02:50:47 +03:00
}
return WERR_ACCESS_DENIED ;
}
2008-01-14 20:31:11 +03:00
/**
* Check whether the in - memory version of the subkyes of a
* registry key needs update from disk .
*/
bool reg_subkeys_need_update ( REGISTRY_KEY * key , REGSUBKEY_CTR * subkeys )
{
2008-04-13 02:54:44 +04:00
if ( key - > ops & & key - > ops - > subkeys_need_update )
2008-01-14 20:31:11 +03:00
{
2008-04-13 02:54:44 +04:00
return key - > ops - > subkeys_need_update ( subkeys ) ;
2008-01-14 20:31:11 +03:00
}
return false ;
}
/**
* Check whether the in - memory version of the values of a
* registry key needs update from disk .
*/
bool reg_values_need_update ( REGISTRY_KEY * key , REGVAL_CTR * values )
{
2008-04-13 02:54:44 +04:00
if ( key - > ops & & key - > ops - > values_need_update )
2008-01-14 20:31:11 +03:00
{
2008-04-13 02:54:44 +04:00
return key - > ops - > values_need_update ( values ) ;
2008-01-14 20:31:11 +03:00
}
return false ;
}