2007-10-05 22:34:25 +00:00
/*
2004-04-04 16:24:08 +00:00
Unix SMB / CIFS implementation .
endpoint server for the winreg pipe
2008-09-13 13:32:39 +02:00
Copyright ( C ) 2004 Jelmer Vernooij , jelmer @ samba . org
Copyright ( C ) 2008 Matthias Dieter Wallnöfer , mwallnoefer @ yahoo . de
2007-10-05 22:34:25 +00:00
2004-04-04 16:24:08 +00: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-10 02:07:03 +00:00
the Free Software Foundation ; either version 3 of the License , or
2004-04-04 16:24:08 +00:00
( at your option ) any later version .
2007-10-05 22:34:25 +00:00
2004-04-04 16:24:08 +00: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-05 22:34:25 +00:00
2004-04-04 16:24:08 +00:00
You should have received a copy of the GNU General Public License
2007-07-10 02:07:03 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2004-04-04 16:24:08 +00:00
*/
# include "includes.h"
2004-11-02 07:42:47 +00:00
# include "rpc_server/dcerpc_server.h"
2005-09-04 14:47:19 +00:00
# include "lib/registry/registry.h"
2004-11-01 10:30:34 +00:00
# include "librpc/gen_ndr/ndr_winreg.h"
2006-03-16 00:23:11 +00:00
# include "librpc/gen_ndr/ndr_security.h"
2010-09-20 14:49:39 +10:00
# include "libcli/security/session.h"
2004-04-04 16:24:08 +00:00
2004-10-28 22:38:27 +00:00
enum handle_types { HTYPE_REGVAL , HTYPE_REGKEY } ;
2007-10-05 22:34:25 +00:00
static NTSTATUS dcerpc_winreg_bind ( struct dcesrv_call_state * dce_call ,
const struct dcesrv_interface * iface )
2004-04-05 20:44:33 +00:00
{
2004-12-10 20:07:04 +00:00
struct registry_context * ctx ;
2006-09-16 16:59:37 +00:00
WERROR err ;
2007-08-26 15:16:40 +00:00
err = reg_open_samba ( dce_call - > context ,
2009-11-18 08:53:22 +01:00
& ctx , dce_call - > event_ctx , dce_call - > conn - > dce_ctx - > lp_ctx ,
dce_call - > conn - > auth_state . session_info ,
2007-10-05 22:34:25 +00:00
NULL ) ;
2004-12-10 20:07:04 +00:00
2007-08-26 15:16:40 +00:00
if ( ! W_ERROR_IS_OK ( err ) ) {
DEBUG ( 0 , ( " Error opening registry: %s \n " , win_errstr ( err ) ) ) ;
2011-04-01 15:58:55 +11:00
return werror_to_ntstatus ( err ) ;
2007-08-26 15:16:40 +00:00
}
2009-02-02 10:01:36 +01:00
dce_call - > context - > private_data = ctx ;
2004-12-10 20:07:04 +00:00
return NT_STATUS_OK ;
2004-04-05 20:44:33 +00:00
}
2004-12-10 20:07:04 +00:00
# define DCESRV_INTERFACE_WINREG_BIND dcerpc_winreg_bind
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_openhive ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx , uint32_t hkey ,
struct policy_handle * * outh )
2004-04-05 20:44:33 +00:00
{
2009-02-02 10:01:36 +01:00
struct registry_context * ctx = dce_call - > context - > private_data ;
2007-10-05 22:34:25 +00:00
struct dcesrv_handle * h ;
2008-09-14 03:51:35 +02:00
WERROR result ;
2004-09-27 16:37:41 +00:00
2007-10-05 22:34:25 +00:00
h = dcesrv_handle_new ( dce_call - > context , HTYPE_REGKEY ) ;
2010-03-22 20:14:51 +01:00
W_ERROR_HAVE_NO_MEMORY ( h ) ;
2004-09-27 16:37:41 +00:00
2008-09-14 03:51:35 +02:00
result = reg_get_predefined_key ( ctx , hkey ,
2007-10-05 22:34:25 +00:00
( struct registry_key * * ) & h - > data ) ;
2008-09-14 03:51:35 +02:00
if ( ! W_ERROR_IS_OK ( result ) ) {
return result ;
2004-10-28 22:38:27 +00:00
}
2007-10-05 22:34:25 +00:00
* outh = & h - > wire_handle ;
2008-09-14 03:51:35 +02:00
return result ;
2004-10-28 22:38:27 +00:00
}
2004-04-05 20:44:33 +00:00
2007-01-17 14:49:36 +00:00
# define func_winreg_OpenHive(k,n) static WERROR dcesrv_winreg_Open ## k (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_Open ## k *r) \
2004-04-08 22:39:47 +00:00
{ \
2007-01-17 14:49:36 +00:00
return dcesrv_winreg_openhive ( dce_call , mem_ctx , n , & r - > out . handle ) ; \
2004-04-08 22:39:47 +00:00
}
2004-12-10 20:07:04 +00:00
func_winreg_OpenHive ( HKCR , HKEY_CLASSES_ROOT )
func_winreg_OpenHive ( HKCU , HKEY_CURRENT_USER )
func_winreg_OpenHive ( HKLM , HKEY_LOCAL_MACHINE )
func_winreg_OpenHive ( HKPD , HKEY_PERFORMANCE_DATA )
func_winreg_OpenHive ( HKU , HKEY_USERS )
func_winreg_OpenHive ( HKCC , HKEY_CURRENT_CONFIG )
func_winreg_OpenHive ( HKDD , HKEY_DYN_DATA )
2004-12-11 17:12:16 +00:00
func_winreg_OpenHive ( HKPT , HKEY_PERFORMANCE_TEXT )
func_winreg_OpenHive ( HKPN , HKEY_PERFORMANCE_NLSTEXT )
2004-04-04 16:24:08 +00:00
2007-10-05 22:34:25 +00:00
/*
winreg_CloseKey
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_CloseKey ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_CloseKey * r )
2004-04-04 16:24:08 +00:00
{
2007-10-05 22:34:25 +00:00
struct dcesrv_handle * h ;
2004-05-04 06:07:52 +00:00
2005-01-10 12:15:26 +00:00
DCESRV_PULL_HANDLE_FAULT ( h , r - > in . handle , HTYPE_REGKEY ) ;
2004-04-05 20:44:33 +00:00
2009-11-18 10:24:09 +01:00
talloc_unlink ( dce_call - > context , h ) ;
2005-08-20 04:40:08 +00:00
ZERO_STRUCTP ( r - > out . handle ) ;
2004-05-04 06:07:52 +00:00
return WERR_OK ;
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_CreateKey
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_CreateKey ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_CreateKey * r )
2004-04-04 16:24:08 +00:00
{
2004-10-28 22:38:27 +00:00
struct dcesrv_handle * h , * newh ;
2005-08-24 08:31:39 +00:00
struct security_descriptor sd ;
2008-09-19 12:29:38 +02:00
struct registry_key * key ;
2008-09-14 03:51:35 +02:00
WERROR result ;
2004-05-04 06:07:52 +00:00
2005-01-10 12:15:26 +00:00
DCESRV_PULL_HANDLE_FAULT ( h , r - > in . handle , HTYPE_REGKEY ) ;
2008-09-19 12:29:38 +02:00
key = h - > data ;
2007-10-05 22:34:25 +00:00
2005-01-10 12:15:26 +00:00
newh = dcesrv_handle_new ( dce_call - > context , HTYPE_REGKEY ) ;
2004-10-28 22:38:27 +00:00
2010-04-22 16:48:01 +10:00
switch ( security_session_user_level ( dce_call - > conn - > auth_state . session_info , NULL ) )
2008-03-20 12:12:10 +11:00
{
case SECURITY_SYSTEM :
case SECURITY_ADMINISTRATOR :
2010-03-21 14:20:41 +01:00
/* we support only non volatile keys */
2010-04-09 13:50:34 +02:00
if ( r - > in . options ! = REG_OPTION_NON_VOLATILE ) {
2010-03-21 14:20:41 +01:00
return WERR_NOT_SUPPORTED ;
}
2008-03-20 12:12:10 +11:00
/* the security descriptor is optional */
if ( r - > in . secdesc ! = NULL ) {
DATA_BLOB sdblob ;
enum ndr_err_code ndr_err ;
sdblob . data = r - > in . secdesc - > sd . data ;
sdblob . length = r - > in . secdesc - > sd . len ;
if ( sdblob . data = = NULL ) {
2015-12-03 15:24:27 +01:00
return WERR_INVALID_PARAMETER ;
2008-03-20 12:12:10 +11:00
}
2010-05-09 17:20:01 +02:00
ndr_err = ndr_pull_struct_blob_all ( & sdblob , mem_ctx , & sd ,
2008-03-20 12:12:10 +11:00
( ndr_pull_flags_fn_t ) ndr_pull_security_descriptor ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
2015-12-03 15:24:27 +01:00
return WERR_INVALID_PARAMETER ;
2008-03-20 12:12:10 +11:00
}
2005-08-24 08:31:39 +00:00
}
2008-03-20 12:12:10 +11:00
2008-09-19 12:29:38 +02:00
result = reg_key_add_name ( newh , key , r - > in . name . name , NULL ,
r - > in . secdesc ? & sd : NULL , ( struct registry_key * * ) & newh - > data ) ;
2010-03-19 20:23:36 +01:00
r - > out . action_taken = talloc ( mem_ctx , enum winreg_CreateAction ) ;
if ( r - > out . action_taken = = NULL ) {
talloc_free ( newh ) ;
2015-12-03 15:24:19 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2010-03-19 20:23:36 +01:00
}
* r - > out . action_taken = REG_ACTION_NONE ;
2008-09-14 03:51:35 +02:00
if ( W_ERROR_IS_OK ( result ) ) {
2008-03-20 12:12:10 +11:00
r - > out . new_handle = & newh - > wire_handle ;
2010-03-19 20:23:36 +01:00
* r - > out . action_taken = REG_CREATED_NEW_KEY ;
2008-03-20 12:12:10 +11:00
} else {
talloc_free ( newh ) ;
2005-08-24 08:31:39 +00:00
}
2010-03-19 20:23:36 +01:00
2008-09-14 03:51:35 +02:00
return result ;
2008-03-20 12:12:10 +11:00
default :
return WERR_ACCESS_DENIED ;
2005-08-24 08:31:39 +00:00
}
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_DeleteKey
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_DeleteKey ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_DeleteKey * r )
2004-04-04 16:24:08 +00:00
{
2004-10-28 22:38:27 +00:00
struct dcesrv_handle * h ;
2008-09-19 12:29:38 +02:00
struct registry_key * key ;
2009-11-18 08:48:30 +01:00
WERROR result ;
2004-05-04 06:07:52 +00:00
2005-01-10 12:15:26 +00:00
DCESRV_PULL_HANDLE_FAULT ( h , r - > in . handle , HTYPE_REGKEY ) ;
2008-09-19 12:29:38 +02:00
key = h - > data ;
2007-10-05 22:34:25 +00:00
2010-04-22 16:48:01 +10:00
switch ( security_session_user_level ( dce_call - > conn - > auth_state . session_info , NULL ) )
2008-03-20 12:12:10 +11:00
{
case SECURITY_SYSTEM :
case SECURITY_ADMINISTRATOR :
2010-03-22 19:18:56 +01:00
result = reg_key_del ( mem_ctx , key , r - > in . key . name ) ;
2009-11-18 08:48:30 +01:00
talloc_unlink ( dce_call - > context , h ) ;
return result ;
2008-03-20 12:12:10 +11:00
default :
return WERR_ACCESS_DENIED ;
}
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_DeleteValue
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_DeleteValue ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_DeleteValue * r )
2004-04-04 16:24:08 +00:00
{
2004-10-28 22:38:27 +00:00
struct dcesrv_handle * h ;
2008-09-19 12:29:38 +02:00
struct registry_key * key ;
2004-10-28 22:38:27 +00:00
2005-01-10 12:15:26 +00:00
DCESRV_PULL_HANDLE_FAULT ( h , r - > in . handle , HTYPE_REGKEY ) ;
2008-09-19 12:29:38 +02:00
key = h - > data ;
2004-10-28 22:38:27 +00:00
2010-04-22 16:48:01 +10:00
switch ( security_session_user_level ( dce_call - > conn - > auth_state . session_info , NULL ) )
2008-03-20 12:12:10 +11:00
{
case SECURITY_SYSTEM :
case SECURITY_ADMINISTRATOR :
2010-03-22 19:18:56 +01:00
return reg_del_value ( mem_ctx , key , r - > in . value . name ) ;
2008-03-20 12:12:10 +11:00
default :
return WERR_ACCESS_DENIED ;
}
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_EnumKey
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_EnumKey ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_EnumKey * r )
2004-04-04 16:24:08 +00:00
{
2004-10-28 22:38:27 +00:00
struct dcesrv_handle * h ;
2008-09-19 12:29:38 +02:00
struct registry_key * key ;
2008-09-13 13:32:39 +02:00
const char * name , * classname ;
2007-08-26 15:16:40 +00:00
NTTIME last_mod ;
2008-09-14 03:51:35 +02:00
WERROR result ;
2004-05-04 06:07:52 +00:00
2005-01-10 12:15:26 +00:00
DCESRV_PULL_HANDLE_FAULT ( h , r - > in . handle , HTYPE_REGKEY ) ;
2008-09-19 12:29:38 +02:00
key = h - > data ;
2004-04-08 22:39:47 +00:00
2008-09-14 03:51:35 +02:00
result = reg_key_get_subkey_by_index ( mem_ctx ,
2008-09-19 12:29:38 +02:00
key , r - > in . enum_index , & name , & classname , & last_mod ) ;
2004-10-28 23:06:12 +00:00
2008-09-09 17:54:08 +02:00
if ( 2 * strlen_m_term ( name ) > r - > in . name - > size ) {
return WERR_MORE_DATA ;
}
2008-09-13 13:32:39 +02:00
if ( name ! = NULL ) {
r - > out . name - > name = name ;
r - > out . name - > length = 2 * strlen_m_term ( name ) ;
} else {
r - > out . name - > name = r - > in . name - > name ;
r - > out . name - > length = r - > in . name - > length ;
}
r - > out . name - > size = r - > in . name - > size ;
r - > out . keyclass = r - > in . keyclass ;
if ( classname ! = NULL ) {
r - > out . keyclass - > name = classname ;
r - > out . keyclass - > length = 2 * strlen_m_term ( classname ) ;
} else {
r - > out . keyclass - > name = r - > in . keyclass - > name ;
r - > out . keyclass - > length = r - > in . keyclass - > length ;
2004-10-28 23:06:12 +00:00
}
2008-09-13 13:32:39 +02:00
r - > out . keyclass - > size = r - > in . keyclass - > size ;
if ( r - > in . last_changed_time ! = NULL )
r - > out . last_changed_time = & last_mod ;
2007-10-05 22:34:25 +00:00
2008-09-14 03:51:35 +02:00
return result ;
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_EnumValue
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_EnumValue ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_EnumValue * r )
2004-04-04 16:24:08 +00:00
{
2004-10-29 13:38:37 +00:00
struct dcesrv_handle * h ;
struct registry_key * key ;
2007-08-26 15:16:40 +00:00
const char * data_name ;
2008-09-15 19:14:31 +02:00
uint32_t data_type ;
2007-08-26 15:16:40 +00:00
DATA_BLOB data ;
2008-09-14 03:51:35 +02:00
WERROR result ;
2004-10-28 22:38:27 +00:00
2005-01-10 12:15:26 +00:00
DCESRV_PULL_HANDLE_FAULT ( h , r - > in . handle , HTYPE_REGKEY ) ;
2004-10-29 13:38:37 +00:00
key = h - > data ;
2008-09-19 12:29:38 +02:00
result = reg_key_get_value_by_index ( mem_ctx , key ,
2008-09-15 19:14:31 +02:00
r - > in . enum_index , & data_name , & data_type , & data ) ;
2008-09-09 17:54:08 +02:00
2004-10-29 13:38:37 +00:00
if ( ! W_ERROR_IS_OK ( result ) ) {
2008-09-09 17:54:08 +02:00
/* if the lookup wasn't successful, send client query back */
data_name = r - > in . name - > name ;
2008-09-15 19:14:31 +02:00
data_type = * r - > in . type ;
2008-09-09 17:54:08 +02:00
data . data = r - > in . value ;
data . length = * r - > in . length ;
2004-10-29 13:38:37 +00:00
}
2005-08-17 01:25:58 +00:00
2008-09-09 17:54:08 +02:00
/* "data_name" is NULL when we query the default attribute */
2008-09-13 13:32:39 +02:00
if ( data_name ! = NULL ) {
2008-09-09 17:54:08 +02:00
r - > out . name - > name = data_name ;
r - > out . name - > length = 2 * strlen_m_term ( data_name ) ;
} else {
r - > out . name - > name = r - > in . name - > name ;
r - > out . name - > length = r - > in . name - > length ;
}
2008-01-07 14:11:29 -06:00
r - > out . name - > size = r - > in . name - > size ;
2005-08-17 01:25:58 +00:00
2010-06-20 21:54:50 +02:00
r - > out . type = talloc ( mem_ctx , enum winreg_Type ) ;
2008-09-15 19:21:38 +02:00
if ( ! r - > out . type ) {
2015-12-03 15:24:19 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2008-09-15 19:21:38 +02:00
}
2010-06-20 21:54:50 +02:00
* r - > out . type = ( enum winreg_Type ) data_type ;
2008-09-15 19:14:31 +02:00
2008-09-15 18:21:45 +02:00
/* check the client has enough room for the value */
if ( r - > in . value ! = NULL & &
r - > in . size ! = NULL & &
data . length > * r - > in . size ) {
return WERR_MORE_DATA ;
}
2008-09-13 13:32:39 +02:00
if ( r - > in . value ! = NULL ) {
2007-08-26 15:16:40 +00:00
r - > out . value = data . data ;
2005-08-17 01:25:58 +00:00
}
2008-09-13 13:32:39 +02:00
if ( r - > in . size ! = NULL ) {
2005-08-17 01:25:58 +00:00
r - > out . size = talloc ( mem_ctx , uint32_t ) ;
2007-08-26 15:16:40 +00:00
* r - > out . size = data . length ;
2005-08-17 01:25:58 +00:00
r - > out . length = r - > out . size ;
}
2007-10-05 22:34:25 +00:00
2008-09-09 17:54:08 +02:00
return result ;
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_FlushKey
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_FlushKey ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_FlushKey * r )
2004-04-04 16:24:08 +00:00
{
2004-10-29 11:44:59 +00:00
struct dcesrv_handle * h ;
2008-09-19 12:29:38 +02:00
struct registry_key * key ;
2004-10-29 11:44:59 +00:00
2005-01-10 12:15:26 +00:00
DCESRV_PULL_HANDLE_FAULT ( h , r - > in . handle , HTYPE_REGKEY ) ;
2008-09-19 12:29:38 +02:00
key = h - > data ;
2004-10-29 11:44:59 +00:00
2010-04-22 16:48:01 +10:00
switch ( security_session_user_level ( dce_call - > conn - > auth_state . session_info , NULL ) )
2008-03-20 12:12:10 +11:00
{
case SECURITY_SYSTEM :
case SECURITY_ADMINISTRATOR :
2008-09-19 12:29:38 +02:00
return reg_key_flush ( key ) ;
2008-03-20 12:12:10 +11:00
default :
return WERR_ACCESS_DENIED ;
}
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_GetKeySecurity
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_GetKeySecurity ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_GetKeySecurity * r )
2004-04-04 16:24:08 +00:00
{
2004-12-13 02:04:34 +00:00
struct dcesrv_handle * h ;
2005-01-10 12:15:26 +00:00
DCESRV_PULL_HANDLE_FAULT ( h , r - > in . handle , HTYPE_REGKEY ) ;
2004-12-13 02:04:34 +00:00
2004-05-04 06:07:52 +00:00
return WERR_NOT_SUPPORTED ;
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_LoadKey
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_LoadKey ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_LoadKey * r )
2004-04-04 16:24:08 +00:00
{
2004-05-04 06:07:52 +00:00
return WERR_NOT_SUPPORTED ;
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_NotifyChangeKeyValue
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_NotifyChangeKeyValue ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_NotifyChangeKeyValue * r )
2004-04-04 16:24:08 +00:00
{
2004-05-04 06:07:52 +00:00
return WERR_NOT_SUPPORTED ;
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_OpenKey
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_OpenKey ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_OpenKey * r )
2004-04-04 16:24:08 +00:00
{
2004-10-28 22:38:27 +00:00
struct dcesrv_handle * h , * newh ;
2008-09-19 12:29:38 +02:00
struct registry_key * key ;
2004-05-04 06:07:52 +00:00
WERROR result ;
2006-09-15 18:34:03 +00:00
DCESRV_PULL_HANDLE_FAULT ( h , r - > in . parent_handle , HTYPE_REGKEY ) ;
2008-09-19 12:29:38 +02:00
key = h - > data ;
2004-04-08 22:39:47 +00:00
2010-04-22 16:48:01 +10:00
switch ( security_session_user_level ( dce_call - > conn - > auth_state . session_info , NULL ) )
2008-03-20 12:12:10 +11:00
{
case SECURITY_SYSTEM :
case SECURITY_ADMINISTRATOR :
case SECURITY_USER :
if ( r - > in . keyname . name & & strcmp ( r - > in . keyname . name , " " ) = = 0 ) {
newh = talloc_reference ( dce_call - > context , h ) ;
result = WERR_OK ;
} else {
newh = dcesrv_handle_new ( dce_call - > context , HTYPE_REGKEY ) ;
2008-09-19 12:29:38 +02:00
result = reg_open_key ( newh , key , r - > in . keyname . name ,
( struct registry_key * * ) & newh - > data ) ;
2008-03-20 12:12:10 +11:00
}
if ( W_ERROR_IS_OK ( result ) ) {
r - > out . handle = & newh - > wire_handle ;
} else {
talloc_free ( newh ) ;
}
return result ;
default :
return WERR_ACCESS_DENIED ;
2004-04-08 22:39:47 +00:00
}
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_QueryInfoKey
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_QueryInfoKey ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_QueryInfoKey * r )
2004-04-04 16:24:08 +00:00
{
2004-10-29 13:38:37 +00:00
struct dcesrv_handle * h ;
2008-09-19 12:29:38 +02:00
struct registry_key * key ;
2007-08-27 22:18:16 +00:00
const char * classname = NULL ;
2008-09-14 03:51:35 +02:00
WERROR result ;
2004-10-29 13:38:37 +00:00
2005-01-10 12:15:26 +00:00
DCESRV_PULL_HANDLE_FAULT ( h , r - > in . handle , HTYPE_REGKEY ) ;
2008-09-19 12:29:38 +02:00
key = h - > data ;
2005-01-10 12:15:26 +00:00
2010-04-22 16:48:01 +10:00
switch ( security_session_user_level ( dce_call - > conn - > auth_state . session_info , NULL ) )
2008-03-20 12:12:10 +11:00
{
case SECURITY_SYSTEM :
case SECURITY_ADMINISTRATOR :
case SECURITY_USER :
2008-09-19 12:29:38 +02:00
result = reg_key_get_info ( mem_ctx , key , & classname ,
r - > out . num_subkeys , r - > out . num_values ,
r - > out . last_changed_time , r - > out . max_subkeylen ,
r - > out . max_valnamelen , r - > out . max_valbufsize ) ;
2008-09-13 13:32:39 +02:00
2010-03-29 20:36:32 +02:00
if ( r - > out . max_subkeylen ! = NULL ) {
/* for UTF16 encoding */
* r - > out . max_subkeylen * = 2 ;
}
if ( r - > out . max_valnamelen ! = NULL ) {
/* for UTF16 encoding */
* r - > out . max_valnamelen * = 2 ;
}
2008-09-13 13:32:39 +02:00
if ( classname ! = NULL ) {
2008-03-20 12:12:10 +11:00
r - > out . classname - > name = classname ;
2008-09-13 13:32:39 +02:00
r - > out . classname - > name_len = 2 * strlen_m_term ( classname ) ;
} else {
r - > out . classname - > name = r - > in . classname - > name ;
r - > out . classname - > name_len = r - > in . classname - > name_len ;
}
r - > out . classname - > name_size = r - > in . classname - > name_size ;
2008-09-09 17:54:08 +02:00
return result ;
2008-03-20 12:12:10 +11:00
default :
return WERR_ACCESS_DENIED ;
}
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_QueryValue
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_QueryValue ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_QueryValue * r )
2004-04-04 16:24:08 +00:00
{
2004-12-13 02:04:34 +00:00
struct dcesrv_handle * h ;
2008-09-19 12:29:38 +02:00
struct registry_key * key ;
2008-09-15 19:14:31 +02:00
uint32_t value_type ;
2007-08-26 15:16:40 +00:00
DATA_BLOB value_data ;
2008-09-14 03:51:35 +02:00
WERROR result ;
2004-12-13 02:04:34 +00:00
2005-01-10 12:15:26 +00:00
DCESRV_PULL_HANDLE_FAULT ( h , r - > in . handle , HTYPE_REGKEY ) ;
2008-09-19 12:29:38 +02:00
key = h - > data ;
2004-12-13 02:04:34 +00:00
2010-04-22 16:48:01 +10:00
switch ( security_session_user_level ( dce_call - > conn - > auth_state . session_info , NULL ) )
2008-03-20 12:12:10 +11:00
{
case SECURITY_SYSTEM :
case SECURITY_ADMINISTRATOR :
case SECURITY_USER :
2010-03-10 19:49:25 +01:00
if ( ( r - > in . type = = NULL ) | | ( r - > in . data_length = = NULL ) | |
( r - > in . data_size = = NULL ) ) {
2015-12-03 15:24:27 +01:00
return WERR_INVALID_PARAMETER ;
2010-03-10 19:49:25 +01:00
}
2008-10-21 14:51:13 +02:00
result = reg_key_get_value_by_name ( mem_ctx , key ,
r - > in . value_name - > name , & value_type , & value_data ) ;
2008-03-20 12:12:10 +11:00
if ( ! W_ERROR_IS_OK ( result ) ) {
2008-09-09 17:54:08 +02:00
/* if the lookup wasn't successful, send client query back */
2010-03-10 19:49:25 +01:00
value_type = * r - > in . type ;
2008-09-09 17:54:08 +02:00
value_data . data = r - > in . data ;
2010-03-10 19:49:25 +01:00
value_data . length = * r - > in . data_length ;
} else {
if ( ( r - > in . data ! = NULL )
& & ( * r - > in . data_size < value_data . length ) ) {
2010-03-11 20:17:48 +01:00
result = WERR_MORE_DATA ;
2010-03-10 09:22:42 +01:00
}
2008-03-20 12:12:10 +11:00
}
2008-09-09 17:54:08 +02:00
2010-06-20 21:54:50 +02:00
r - > out . type = talloc ( mem_ctx , enum winreg_Type ) ;
2008-09-15 19:14:31 +02:00
if ( ! r - > out . type ) {
2015-12-03 15:24:19 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2008-09-15 19:14:31 +02:00
}
2010-06-20 21:54:50 +02:00
* r - > out . type = ( enum winreg_Type ) value_type ;
2008-10-15 17:38:51 +02:00
r - > out . data_length = talloc ( mem_ctx , uint32_t ) ;
if ( ! r - > out . data_length ) {
2015-12-03 15:24:19 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2008-03-20 12:12:10 +11:00
}
2008-10-21 15:47:34 +02:00
* r - > out . data_length = value_data . length ;
2008-10-21 14:51:13 +02:00
r - > out . data_size = talloc ( mem_ctx , uint32_t ) ;
if ( ! r - > out . data_size ) {
2015-12-03 15:24:19 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2008-03-20 12:12:10 +11:00
}
2008-10-21 14:51:13 +02:00
* r - > out . data_size = value_data . length ;
2008-09-09 17:54:08 +02:00
r - > out . data = value_data . data ;
return result ;
2008-03-20 12:12:10 +11:00
default :
return WERR_ACCESS_DENIED ;
2004-12-15 02:27:22 +00:00
}
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_ReplaceKey
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_ReplaceKey ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_ReplaceKey * r )
2004-04-04 16:24:08 +00:00
{
2004-05-04 06:07:52 +00:00
return WERR_NOT_SUPPORTED ;
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_RestoreKey
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_RestoreKey ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_RestoreKey * r )
2004-04-04 16:24:08 +00:00
{
2004-05-04 06:07:52 +00:00
return WERR_NOT_SUPPORTED ;
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_SaveKey
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_SaveKey ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_SaveKey * r )
2004-04-04 16:24:08 +00:00
{
2004-05-04 06:07:52 +00:00
return WERR_NOT_SUPPORTED ;
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_SetKeySecurity
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_SetKeySecurity ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_SetKeySecurity * r )
2004-04-04 16:24:08 +00:00
{
2004-05-04 06:07:52 +00:00
return WERR_NOT_SUPPORTED ;
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_SetValue
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_SetValue ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_SetValue * r )
2004-04-04 16:24:08 +00:00
{
2004-12-15 00:16:54 +00:00
struct dcesrv_handle * h ;
2008-09-19 12:29:38 +02:00
struct registry_key * key ;
2005-09-03 17:17:30 +00:00
DATA_BLOB data ;
2008-09-14 03:51:35 +02:00
WERROR result ;
2004-12-15 00:16:54 +00:00
2005-01-10 12:15:26 +00:00
DCESRV_PULL_HANDLE_FAULT ( h , r - > in . handle , HTYPE_REGKEY ) ;
2008-09-19 12:29:38 +02:00
key = h - > data ;
2004-12-15 00:16:54 +00:00
2010-04-22 16:48:01 +10:00
switch ( security_session_user_level ( dce_call - > conn - > auth_state . session_info , NULL ) )
2008-03-20 12:12:10 +11:00
{
case SECURITY_SYSTEM :
case SECURITY_ADMINISTRATOR :
data . data = r - > in . data ;
data . length = r - > in . size ;
2008-09-19 12:29:38 +02:00
result = reg_val_set ( key , r - > in . name . name , r - > in . type , data ) ;
2008-03-20 12:12:10 +11:00
return result ;
default :
return WERR_ACCESS_DENIED ;
}
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_UnLoadKey
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_UnLoadKey ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_UnLoadKey * r )
2004-04-04 16:24:08 +00:00
{
2004-05-04 06:07:52 +00:00
return WERR_NOT_SUPPORTED ;
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_InitiateSystemShutdown
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_InitiateSystemShutdown ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_InitiateSystemShutdown * r )
2004-04-04 16:24:08 +00:00
{
2004-05-04 06:07:52 +00:00
return WERR_NOT_SUPPORTED ;
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_AbortSystemShutdown
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_AbortSystemShutdown ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_AbortSystemShutdown * r )
2004-04-04 16:24:08 +00:00
{
2004-05-04 06:07:52 +00:00
return WERR_NOT_SUPPORTED ;
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_GetVersion
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_GetVersion ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_GetVersion * r )
2004-04-04 16:24:08 +00:00
{
2005-08-18 11:16:32 +00:00
struct dcesrv_handle * h ;
DCESRV_PULL_HANDLE_FAULT ( h , r - > in . handle , HTYPE_REGKEY ) ;
2006-09-15 20:36:38 +00:00
r - > out . version = talloc ( mem_ctx , uint32_t ) ;
2006-09-24 02:05:37 +00:00
W_ERROR_HAVE_NO_MEMORY ( r - > out . version ) ;
2006-09-15 20:36:38 +00:00
2006-09-15 18:34:03 +00:00
* r - > out . version = 5 ;
2006-09-15 20:36:38 +00:00
2004-10-29 13:38:37 +00:00
return WERR_OK ;
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_QueryMultipleValues
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_QueryMultipleValues ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_QueryMultipleValues * r )
2004-04-04 16:24:08 +00:00
{
2004-05-04 06:07:52 +00:00
return WERR_NOT_SUPPORTED ;
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_InitiateSystemShutdownEx
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_InitiateSystemShutdownEx ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_InitiateSystemShutdownEx * r )
2004-04-04 16:24:08 +00:00
{
2004-05-04 06:07:52 +00:00
return WERR_NOT_SUPPORTED ;
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_SaveKeyEx
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_SaveKeyEx ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_SaveKeyEx * r )
2004-04-04 16:24:08 +00:00
{
2004-05-04 06:07:52 +00:00
return WERR_NOT_SUPPORTED ;
2004-04-04 16:24:08 +00:00
}
2007-10-05 22:34:25 +00:00
/*
winreg_QueryMultipleValues2
2004-04-04 16:24:08 +00:00
*/
2007-10-05 22:34:25 +00:00
static WERROR dcesrv_winreg_QueryMultipleValues2 ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_QueryMultipleValues2 * r )
2004-04-04 16:24:08 +00:00
{
2004-05-04 06:07:52 +00:00
return WERR_NOT_SUPPORTED ;
2004-04-04 16:24:08 +00:00
}
2010-04-09 00:11:57 +02:00
/*
winreg_DeleteKeyEx
*/
static WERROR dcesrv_winreg_DeleteKeyEx ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct winreg_DeleteKeyEx * r )
{
return WERR_NOT_SUPPORTED ;
}
2004-04-04 16:24:08 +00:00
/* include the generated boilerplate */
# include "librpc/gen_ndr/ndr_winreg_s.c"