2009-12-04 13:29:08 +01:00
/*
2002-01-30 06:08:46 +00:00
* Unix SMB / CIFS implementation .
2001-02-25 02:14:49 +00:00
* RPC Pipe client / server routines
2009-12-04 13:29:08 +01:00
*
2006-09-27 16:05:25 +00:00
* Copyright ( C ) Gerald Carter 2002 - 2006.
2001-02-25 02:14:49 +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-09 19:25:36 +00:00
* the Free Software Foundation ; either version 3 of the License , or
2001-02-25 02:14:49 +00:00
* ( at your option ) any later version .
2009-12-04 13:29:08 +01:00
*
2001-02-25 02:14:49 +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 .
2009-12-04 13:29:08 +01:00
*
2001-02-25 02:14:49 +00:00
* You should have received a copy of the GNU General Public License
2007-07-10 05:23:25 +00:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2001-02-25 02:14:49 +00:00
*/
/* Implementation of registry functions. */
# include "includes.h"
2011-05-02 13:21:53 +02:00
# include "ntdomain.h"
2021-10-04 13:40:02 +02:00
# include "librpc/rpc/dcesrv_core.h"
2019-05-28 16:12:51 +02:00
# include "librpc/gen_ndr/ndr_winreg.h"
# include "librpc/gen_ndr/ndr_winreg_scompat.h"
2009-10-02 00:17:06 +02:00
# include "registry.h"
2010-09-21 08:11:18 +02:00
# include "registry/reg_api.h"
2010-05-24 22:59:04 +02:00
# include "registry/reg_perfcount.h"
2010-08-20 12:15:13 +02:00
# include "rpc_misc.h"
2011-03-24 12:08:15 +01:00
# include "auth.h"
2011-03-25 11:56:52 +01:00
# include "lib/privileges.h"
2011-05-30 13:23:56 +10:00
# include "libcli/security/secdesc.h"
2001-02-25 02:14:49 +00:00
2002-07-15 10:35:28 +00:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_RPC_SRV
2020-04-28 21:59:46 +03:00
enum handle_types { HTYPE_REGVAL , HTYPE_REGKEY } ;
2002-08-17 15:34:15 +00:00
/******************************************************************
2008-02-18 17:48:19 +01:00
Find a registry key handle and return a struct registry_key *
2002-08-17 15:34:15 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-15 10:35:28 +00:00
2010-07-28 10:20:10 +02:00
static struct registry_key * find_regkey_by_hnd ( struct pipes_struct * p ,
2020-05-06 13:56:46 +02:00
struct policy_handle * hnd ,
enum handle_types type )
2002-07-15 10:35:28 +00:00
{
2006-12-01 20:01:09 +00:00
struct registry_key * regkey = NULL ;
2020-05-18 12:04:33 +02:00
NTSTATUS status ;
2002-07-15 10:35:28 +00:00
2020-05-18 12:04:33 +02:00
regkey = find_policy_by_hnd ( p ,
hnd ,
type ,
struct registry_key ,
& status ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2023-08-07 16:50:04 +12:00
DEBUG ( 2 , ( " find_regkey_index_by_hnd: Registry Key not found: %s \n " ,
nt_errstr ( status ) ) ) ;
2002-08-17 15:34:15 +00:00
return NULL ;
2002-07-15 10:35:28 +00:00
}
2002-08-17 15:34:15 +00:00
return regkey ;
2002-07-15 10:35:28 +00:00
}
2002-08-17 15:34:15 +00:00
/*******************************************************************
2009-12-04 13:29:08 +01:00
Function for open a new registry handle and creating a handle
2002-08-17 15:34:15 +00:00
Note that P should be valid & hnd should already have space
2009-12-04 13:29:08 +01:00
When we open a key , we store the full path to the key as
2002-08-17 15:34:15 +00:00
HK [ LM | U ] \ < key > \ < key > \ . . .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-12-04 13:29:08 +01:00
2010-07-28 10:20:10 +02:00
static WERROR open_registry_key ( struct pipes_struct * p ,
struct policy_handle * hnd ,
struct registry_key * parent ,
const char * subkeyname ,
uint32_t access_desired )
2002-07-15 10:35:28 +00:00
{
2021-10-04 13:40:02 +02:00
struct dcesrv_call_state * dce_call = p - > dce_call ;
struct auth_session_info * session_info =
dcesrv_call_session_info ( dce_call ) ;
2006-12-01 20:01:09 +00:00
WERROR result = WERR_OK ;
struct registry_key * key ;
2003-01-19 05:04:03 +00:00
2006-12-01 20:01:09 +00:00
if ( parent = = NULL ) {
2009-01-07 18:44:52 +01:00
result = reg_openhive ( p - > mem_ctx , subkeyname , access_desired ,
2021-10-04 13:40:02 +02:00
session_info - > security_token , & key ) ;
2006-12-01 20:01:09 +00:00
}
else {
2009-01-07 18:44:52 +01:00
result = reg_openkey ( p - > mem_ctx , parent , subkeyname ,
access_desired , & key ) ;
2006-11-23 19:21:11 +00:00
}
if ( ! W_ERROR_IS_OK ( result ) ) {
2005-09-30 17:13:37 +00:00
return result ;
2006-11-23 19:21:11 +00:00
}
2009-12-04 13:29:08 +01:00
2020-04-28 21:59:46 +03:00
if ( ! create_policy_hnd ( p , hnd , HTYPE_REGKEY , key ) ) {
2015-12-03 15:24:11 +01:00
return WERR_FILE_NOT_FOUND ;
2006-11-23 19:21:11 +00:00
}
2009-12-04 13:29:08 +01:00
2007-06-12 12:01:52 +00:00
return WERR_OK ;
2002-07-15 10:35:28 +00:00
}
/*******************************************************************
2009-12-04 13:29:08 +01:00
Function for open a new registry handle and creating a handle
2002-07-15 10:35:28 +00:00
Note that P should be valid & hnd should already have space
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
static bool close_registry_key ( struct pipes_struct * p ,
2020-05-06 13:56:46 +02:00
struct policy_handle * hnd ,
enum handle_types type )
2002-07-15 10:35:28 +00:00
{
2020-05-06 13:56:46 +02:00
struct registry_key * regkey = find_regkey_by_hnd ( p , hnd , type ) ;
2009-12-04 13:29:08 +01:00
2002-07-15 10:35:28 +00:00
if ( ! regkey ) {
2006-12-01 20:01:09 +00:00
DEBUG ( 2 , ( " close_registry_key: Invalid handle (%s:%u:%u) \n " ,
OUR_HANDLE ( hnd ) ) ) ;
2002-07-15 10:35:28 +00:00
return False ;
}
2009-12-04 13:29:08 +01:00
2002-07-15 10:35:28 +00:00
close_policy_hnd ( p , hnd ) ;
2009-12-04 13:29:08 +01:00
2002-07-15 10:35:28 +00:00
return True ;
}
/********************************************************************
2009-12-04 13:33:49 +01:00
_winreg_CloseKey
2001-02-25 02:14:49 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_CloseKey ( struct pipes_struct * p ,
struct winreg_CloseKey * r )
2001-02-25 02:14:49 +00:00
{
2020-05-06 13:56:46 +02:00
bool ok ;
2001-02-25 02:14:49 +00:00
/* close the policy handle */
2005-06-16 20:45:55 +00:00
2020-05-06 13:56:46 +02:00
ok = close_registry_key ( p , r - > in . handle , HTYPE_REGKEY ) ;
if ( ! ok ) {
2015-12-03 15:24:13 +01:00
return WERR_INVALID_HANDLE ;
2020-05-06 13:56:46 +02:00
}
2001-02-25 02:14:49 +00:00
2007-01-18 10:18:59 +00:00
ZERO_STRUCTP ( r - > out . handle ) ;
2006-12-03 16:18:31 +00:00
2005-01-10 20:33:41 +00:00
return WERR_OK ;
2001-02-25 02:14:49 +00:00
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_OpenHKLM
2001-02-25 02:14:49 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_OpenHKLM ( struct pipes_struct * p ,
struct winreg_OpenHKLM * r )
2002-07-15 10:35:28 +00:00
{
2007-01-18 10:18:59 +00:00
return open_registry_key ( p , r - > out . handle , NULL , KEY_HKLM , r - > in . access_mask ) ;
2005-09-30 17:13:37 +00:00
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_OpenHKPD
2005-09-30 17:13:37 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_OpenHKPD ( struct pipes_struct * p ,
struct winreg_OpenHKPD * r )
2005-09-30 17:13:37 +00:00
{
2007-01-18 10:18:59 +00:00
return open_registry_key ( p , r - > out . handle , NULL , KEY_HKPD , r - > in . access_mask ) ;
2002-08-17 15:34:15 +00:00
}
2002-07-15 10:35:28 +00:00
2002-08-17 15:34:15 +00:00
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_OpenHKPT
2002-08-17 15:34:15 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_OpenHKPT ( struct pipes_struct * p ,
struct winreg_OpenHKPT * r )
2002-08-17 15:34:15 +00:00
{
2007-01-18 10:18:59 +00:00
return open_registry_key ( p , r - > out . handle , NULL , KEY_HKPT , r - > in . access_mask ) ;
2005-09-30 17:13:37 +00:00
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_OpenHKCR
2005-09-30 17:13:37 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_OpenHKCR ( struct pipes_struct * p ,
struct winreg_OpenHKCR * r )
2005-09-30 17:13:37 +00:00
{
2007-01-18 10:18:59 +00:00
return open_registry_key ( p , r - > out . handle , NULL , KEY_HKCR , r - > in . access_mask ) ;
2002-07-15 10:35:28 +00:00
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_OpenHKU
2002-07-15 10:35:28 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_OpenHKU ( struct pipes_struct * p ,
struct winreg_OpenHKU * r )
2001-02-25 02:14:49 +00:00
{
2007-01-18 10:18:59 +00:00
return open_registry_key ( p , r - > out . handle , NULL , KEY_HKU , r - > in . access_mask ) ;
2006-09-21 17:51:06 +00:00
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_OpenHKCU
2006-09-21 17:51:06 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_OpenHKCU ( struct pipes_struct * p ,
struct winreg_OpenHKCU * r )
2006-09-21 17:51:06 +00:00
{
2007-01-18 10:18:59 +00:00
return open_registry_key ( p , r - > out . handle , NULL , KEY_HKCU , r - > in . access_mask ) ;
2006-09-21 17:51:06 +00:00
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_OpenHKCC
2006-09-21 17:51:06 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_OpenHKCC ( struct pipes_struct * p ,
struct winreg_OpenHKCC * r )
2006-09-21 17:51:06 +00:00
{
2007-01-18 10:18:59 +00:00
return open_registry_key ( p , r - > out . handle , NULL , KEY_HKCC , r - > in . access_mask ) ;
2006-09-21 17:51:06 +00:00
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_OpenHKDD
2006-09-21 17:51:06 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_OpenHKDD ( struct pipes_struct * p ,
struct winreg_OpenHKDD * r )
2006-09-21 17:51:06 +00:00
{
2007-01-18 10:18:59 +00:00
return open_registry_key ( p , r - > out . handle , NULL , KEY_HKDD , r - > in . access_mask ) ;
2006-09-21 17:51:06 +00:00
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_OpenHKPN
2006-09-21 17:51:06 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_OpenHKPN ( struct pipes_struct * p ,
struct winreg_OpenHKPN * r )
2006-09-21 17:51:06 +00:00
{
2007-01-18 10:18:59 +00:00
return open_registry_key ( p , r - > out . handle , NULL , KEY_HKPN , r - > in . access_mask ) ;
2001-02-25 02:14:49 +00:00
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_OpenKey
2001-02-25 02:14:49 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_OpenKey ( struct pipes_struct * p ,
struct winreg_OpenKey * r )
2001-02-25 02:14:49 +00:00
{
2020-05-06 13:56:46 +02:00
struct registry_key * parent = find_regkey_by_hnd ( p ,
r - > in . parent_handle ,
HTYPE_REGKEY ) ;
2001-02-25 02:14:49 +00:00
2005-06-17 15:35:31 +00:00
if ( ! parent )
2015-12-03 15:24:13 +01:00
return WERR_INVALID_HANDLE ;
2005-06-24 22:34:40 +00:00
2007-01-18 10:18:59 +00:00
return open_registry_key ( p , r - > out . handle , parent , r - > in . keyname . name , r - > in . access_mask ) ;
2001-02-25 02:14:49 +00:00
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_QueryValue
2001-02-25 02:14:49 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_QueryValue ( struct pipes_struct * p ,
struct winreg_QueryValue * r )
2001-02-25 02:14:49 +00:00
{
2015-12-03 15:24:11 +01:00
WERROR status = WERR_FILE_NOT_FOUND ;
2020-05-06 13:56:46 +02:00
struct registry_key * regkey = find_regkey_by_hnd ( p ,
r - > in . handle ,
HTYPE_REGKEY ) ;
2006-11-23 16:19:06 +00:00
prs_struct prs_hkpd ;
2010-08-12 14:24:01 -07:00
uint8_t * outbuf = NULL ;
uint32_t outbuf_size = 0 ;
2006-11-23 16:19:06 +00:00
2007-10-18 17:40:25 -07:00
bool free_buf = False ;
bool free_prs = False ;
2001-02-25 02:14:49 +00:00
2006-12-01 20:01:09 +00:00
if ( ! regkey )
2015-12-03 15:24:13 +01:00
return WERR_INVALID_HANDLE ;
2006-09-21 17:51:06 +00:00
2010-03-11 20:48:24 +01:00
if ( r - > in . value_name - > name = = NULL ) {
2015-12-03 15:24:25 +01:00
return WERR_INVALID_PARAMETER ;
2010-03-11 20:48:24 +01:00
}
2010-03-11 12:21:08 +01:00
if ( ( r - > out . data_length = = NULL ) | | ( r - > out . type = = NULL ) | | ( r - > out . data_size = = NULL ) ) {
2015-12-03 15:24:25 +01:00
return WERR_INVALID_PARAMETER ;
2008-06-13 15:30:08 +02:00
}
2010-03-10 14:17:23 +01:00
DEBUG ( 7 , ( " _winreg_QueryValue: policy key name = [%s] \n " , regkey - > key - > name ) ) ;
DEBUG ( 7 , ( " _winreg_QueryValue: policy key type = [%08x] \n " , regkey - > key - > type ) ) ;
2009-12-04 13:29:08 +01:00
2005-09-30 17:13:37 +00:00
/* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
2009-12-04 13:29:08 +01:00
if ( regkey - > key - > type = = REG_KEY_HKPD )
2005-09-30 17:13:37 +00:00
{
2008-03-25 10:11:47 +01:00
if ( strequal ( r - > in . value_name - > name , " Global " ) ) {
2008-03-14 14:26:28 -08:00
if ( ! prs_init ( & prs_hkpd , * r - > in . data_size , p - > mem_ctx , MARSHALL ) )
2015-12-03 15:24:15 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2006-11-23 16:19:06 +00:00
status = reg_perfcount_get_hkpd (
2007-01-18 10:18:59 +00:00
& prs_hkpd , * r - > in . data_size , & outbuf_size , NULL ) ;
2006-11-23 16:19:06 +00:00
outbuf = ( uint8_t * ) prs_hkpd . data_p ;
free_prs = True ;
2005-09-30 17:13:37 +00:00
}
2008-03-25 10:11:47 +01:00
else if ( strequal ( r - > in . value_name - > name , " Counter 009 " ) ) {
2006-11-23 16:19:06 +00:00
outbuf_size = reg_perfcount_get_counter_names (
reg_perfcount_get_base_index ( ) ,
2006-11-27 08:05:42 +00:00
( char * * ) ( void * ) & outbuf ) ;
2006-11-23 16:19:06 +00:00
free_buf = True ;
2005-09-30 17:13:37 +00:00
}
2008-03-25 10:11:47 +01:00
else if ( strequal ( r - > in . value_name - > name , " Explain 009 " ) ) {
2006-11-23 16:19:06 +00:00
outbuf_size = reg_perfcount_get_counter_help (
reg_perfcount_get_base_index ( ) ,
2006-11-27 08:05:42 +00:00
( char * * ) ( void * ) & outbuf ) ;
2006-11-23 16:19:06 +00:00
free_buf = True ;
2005-09-30 17:13:37 +00:00
}
2008-03-25 10:11:47 +01:00
else if ( isdigit ( r - > in . value_name - > name [ 0 ] ) ) {
2006-11-23 16:19:06 +00:00
/* we probably have a request for a specific object
* here */
2008-03-14 14:26:28 -08:00
if ( ! prs_init ( & prs_hkpd , * r - > in . data_size , p - > mem_ctx , MARSHALL ) )
2015-12-03 15:24:15 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2006-11-23 16:19:06 +00:00
status = reg_perfcount_get_hkpd (
2007-01-18 10:18:59 +00:00
& prs_hkpd , * r - > in . data_size , & outbuf_size ,
2008-03-25 10:11:47 +01:00
r - > in . value_name - > name ) ;
2006-11-23 16:19:06 +00:00
outbuf = ( uint8_t * ) prs_hkpd . data_p ;
free_prs = True ;
2005-09-30 17:13:37 +00:00
}
2006-11-23 16:19:06 +00:00
else {
DEBUG ( 3 , ( " Unsupported key name [%s] for HKPD. \n " ,
2008-03-25 10:11:47 +01:00
r - > in . value_name - > name ) ) ;
2015-12-03 15:24:11 +01:00
return WERR_FILE_NOT_FOUND ;
2005-09-30 17:13:37 +00:00
}
2006-11-23 16:19:06 +00:00
2007-01-18 10:18:59 +00:00
* r - > out . type = REG_BINARY ;
2005-09-30 17:13:37 +00:00
}
2006-11-23 16:19:06 +00:00
else {
2006-12-01 20:01:09 +00:00
struct registry_value * val ;
2006-11-23 16:19:06 +00:00
2008-03-25 10:11:47 +01:00
status = reg_queryvalue ( p - > mem_ctx , regkey , r - > in . value_name - > name ,
2006-12-01 20:01:09 +00:00
& val ) ;
if ( ! W_ERROR_IS_OK ( status ) ) {
2010-03-10 14:17:23 +01:00
DEBUG ( 10 , ( " _winreg_QueryValue: reg_queryvalue failed with: %s \n " ,
win_errstr ( status ) ) ) ;
2007-01-18 10:18:59 +00:00
if ( r - > out . data_size ) {
* r - > out . data_size = 0 ;
2006-11-23 22:58:50 +00:00
}
2008-10-15 21:42:59 +02:00
if ( r - > out . data_length ) {
* r - > out . data_length = 0 ;
2006-11-23 22:58:50 +00:00
}
2006-12-01 20:01:09 +00:00
return status ;
2006-09-21 17:51:06 +00:00
}
2006-09-26 22:03:52 +00:00
2010-06-29 16:13:15 +02:00
outbuf = val - > data . data ;
outbuf_size = val - > data . length ;
2007-01-18 10:18:59 +00:00
* r - > out . type = val - > type ;
2006-11-23 16:19:06 +00:00
}
2015-12-03 15:24:11 +01:00
status = WERR_FILE_NOT_FOUND ;
2006-11-23 16:19:06 +00:00
2010-03-11 12:21:08 +01:00
if ( * r - > in . data_size < outbuf_size ) {
* r - > out . data_size = outbuf_size ;
status = r - > in . data ? WERR_MORE_DATA : WERR_OK ;
2006-11-23 16:19:06 +00:00
} else {
2010-03-11 12:21:08 +01:00
* r - > out . data_length = outbuf_size ;
* r - > out . data_size = outbuf_size ;
2010-04-16 11:04:27 +02:00
if ( r - > out . data ) {
memcpy ( r - > out . data , outbuf , outbuf_size ) ;
}
2006-11-23 16:19:06 +00:00
status = WERR_OK ;
2006-09-21 17:51:06 +00:00
}
2006-11-23 16:19:06 +00:00
if ( free_prs ) prs_mem_free ( & prs_hkpd ) ;
if ( free_buf ) SAFE_FREE ( outbuf ) ;
2001-02-25 02:14:49 +00:00
2002-07-15 10:35:28 +00:00
return status ;
}
/*****************************************************************************
2009-12-04 13:33:49 +01:00
_winreg_QueryInfoKey
2002-07-15 10:35:28 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 17:51:06 +00:00
2010-07-28 10:20:10 +02:00
WERROR _winreg_QueryInfoKey ( struct pipes_struct * p ,
struct winreg_QueryInfoKey * r )
2002-07-15 10:35:28 +00:00
{
2005-01-10 20:33:41 +00:00
WERROR status = WERR_OK ;
2020-05-06 13:56:46 +02:00
struct registry_key * regkey = find_regkey_by_hnd ( p ,
r - > in . handle ,
HTYPE_REGKEY ) ;
2009-12-04 13:29:08 +01:00
2002-07-15 10:35:28 +00:00
if ( ! regkey )
2015-12-03 15:24:13 +01:00
return WERR_INVALID_HANDLE ;
2006-12-01 20:01:09 +00:00
2007-01-18 10:18:59 +00:00
r - > out . classname - > name = NULL ;
2006-12-01 20:01:09 +00:00
2007-01-18 10:18:59 +00:00
status = reg_queryinfokey ( regkey , r - > out . num_subkeys , r - > out . max_subkeylen ,
r - > out . max_classlen , r - > out . num_values , r - > out . max_valnamelen ,
r - > out . max_valbufsize , r - > out . secdescsize ,
r - > out . last_changed_time ) ;
2006-12-01 20:01:09 +00:00
if ( ! W_ERROR_IS_OK ( status ) ) {
return status ;
2005-06-30 20:16:16 +00:00
}
2002-08-17 15:34:15 +00:00
2006-12-01 20:01:09 +00:00
/*
* These calculations account for the registry buffers being
* UTF - 16. They are inexact at best , but so far they worked .
*/
2007-01-18 10:18:59 +00:00
* r - > out . max_subkeylen * = 2 ;
2002-07-15 10:35:28 +00:00
2007-01-18 10:18:59 +00:00
* r - > out . max_valnamelen + = 1 ;
* r - > out . max_valnamelen * = 2 ;
2009-12-04 13:29:08 +01:00
2006-12-01 20:01:09 +00:00
return WERR_OK ;
2002-07-15 10:35:28 +00:00
}
/*****************************************************************************
2009-12-04 13:33:49 +01:00
_winreg_GetVersion
2002-07-15 10:35:28 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-12-04 13:29:08 +01:00
2010-07-28 10:20:10 +02:00
WERROR _winreg_GetVersion ( struct pipes_struct * p ,
struct winreg_GetVersion * r )
2002-07-15 10:35:28 +00:00
{
2020-05-06 13:56:46 +02:00
struct registry_key * regkey = find_regkey_by_hnd ( p ,
r - > in . handle ,
HTYPE_REGKEY ) ;
2009-12-04 13:29:08 +01:00
2002-07-15 10:35:28 +00:00
if ( ! regkey )
2015-12-03 15:24:13 +01:00
return WERR_INVALID_HANDLE ;
2009-12-04 13:29:08 +01:00
2008-01-17 11:22:01 +01:00
return reg_getversion ( r - > out . version ) ;
2002-07-15 10:35:28 +00:00
}
2001-02-25 02:14:49 +00:00
2002-07-15 10:35:28 +00:00
/*****************************************************************************
2009-12-04 13:33:49 +01:00
_winreg_EnumKey
2002-07-15 10:35:28 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-12-04 13:29:08 +01:00
2010-07-28 10:20:10 +02:00
WERROR _winreg_EnumKey ( struct pipes_struct * p ,
struct winreg_EnumKey * r )
2002-07-15 10:35:28 +00:00
{
2010-08-13 10:47:08 -07:00
WERROR err = WERR_OK ;
2020-05-06 13:56:46 +02:00
struct registry_key * key = find_regkey_by_hnd ( p ,
r - > in . handle ,
HTYPE_REGKEY ) ;
2013-06-11 19:27:17 +02:00
char * name ;
2009-12-04 13:29:08 +01:00
2006-12-01 20:01:09 +00:00
if ( ! key )
2015-12-03 15:24:13 +01:00
return WERR_INVALID_HANDLE ;
2002-07-15 10:35:28 +00:00
2007-01-18 10:18:59 +00:00
if ( ! r - > in . name | | ! r - > in . keyclass )
2015-12-03 15:24:25 +01:00
return WERR_INVALID_PARAMETER ;
2006-09-21 17:51:06 +00:00
2010-03-11 19:25:57 +01:00
DEBUG ( 8 , ( " _winreg_EnumKey: enumerating key [%s] \n " , key - > key - > name ) ) ;
2006-11-27 07:41:59 +00:00
2013-06-11 19:27:17 +02:00
err = reg_enumkey ( p - > mem_ctx , key , r - > in . enum_index , & name ,
2007-01-18 10:18:59 +00:00
r - > out . last_changed_time ) ;
2006-12-01 20:01:09 +00:00
if ( ! W_ERROR_IS_OK ( err ) ) {
return err ;
2006-09-21 18:54:25 +00:00
}
2013-06-11 19:27:17 +02:00
r - > out . name - > name = name ;
2007-01-18 10:18:59 +00:00
r - > out . keyclass - > name = " " ;
2006-12-01 20:01:09 +00:00
return WERR_OK ;
2002-08-17 15:34:15 +00:00
}
/*****************************************************************************
2009-12-04 13:33:49 +01:00
_winreg_EnumValue
2002-08-17 15:34:15 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-21 17:51:06 +00:00
2010-07-28 10:20:10 +02:00
WERROR _winreg_EnumValue ( struct pipes_struct * p ,
struct winreg_EnumValue * r )
2002-08-17 15:34:15 +00:00
{
2010-08-13 10:47:08 -07:00
WERROR err = WERR_OK ;
2020-05-06 13:56:46 +02:00
struct registry_key * key = find_regkey_by_hnd ( p ,
r - > in . handle ,
HTYPE_REGKEY ) ;
2010-08-13 10:47:08 -07:00
char * valname = NULL ;
struct registry_value * val = NULL ;
2009-12-04 13:29:08 +01:00
2006-12-01 20:01:09 +00:00
if ( ! key )
2015-12-03 15:24:13 +01:00
return WERR_INVALID_HANDLE ;
2002-08-17 15:34:15 +00:00
2007-01-18 10:18:59 +00:00
if ( ! r - > in . name )
2015-12-03 15:24:25 +01:00
return WERR_INVALID_PARAMETER ;
2006-11-23 22:58:50 +00:00
DEBUG ( 8 , ( " _winreg_EnumValue: enumerating values for key [%s] \n " ,
2006-12-01 20:01:09 +00:00
key - > key - > name ) ) ;
2002-08-17 15:34:15 +00:00
2007-01-18 10:18:59 +00:00
err = reg_enumvalue ( p - > mem_ctx , key , r - > in . enum_index , & valname , & val ) ;
2006-12-01 20:01:09 +00:00
if ( ! W_ERROR_IS_OK ( err ) ) {
return err ;
2002-08-17 15:34:15 +00:00
}
2005-10-14 21:09:56 +00:00
2007-01-18 10:18:59 +00:00
if ( r - > out . name ! = NULL ) {
r - > out . name - > name = valname ;
2006-09-21 17:51:06 +00:00
}
2007-01-18 10:18:59 +00:00
if ( r - > out . type ! = NULL ) {
* r - > out . type = val - > type ;
2006-10-15 16:06:10 +00:00
}
2006-09-21 17:51:06 +00:00
2007-02-20 13:43:41 +00:00
if ( r - > out . value ! = NULL ) {
2007-02-16 14:50:57 +00:00
if ( ( r - > out . size = = NULL ) | | ( r - > out . length = = NULL ) ) {
2015-12-03 15:24:25 +01:00
return WERR_INVALID_PARAMETER ;
2006-10-15 16:06:10 +00:00
}
2010-06-29 16:13:15 +02:00
if ( val - > data . length > * r - > out . size ) {
2023-11-15 17:13:20 +01:00
* r - > out . size = val - > data . length ;
2006-11-23 22:58:50 +00:00
return WERR_MORE_DATA ;
2006-10-15 16:06:10 +00:00
}
2010-06-29 16:13:15 +02:00
memcpy ( r - > out . value , val - > data . data , val - > data . length ) ;
2006-09-21 17:51:06 +00:00
}
2007-02-16 14:50:57 +00:00
if ( r - > out . length ! = NULL ) {
2010-06-29 16:13:15 +02:00
* r - > out . length = val - > data . length ;
2006-10-15 16:06:10 +00:00
}
2007-02-16 14:50:57 +00:00
if ( r - > out . size ! = NULL ) {
2010-06-29 16:13:15 +02:00
* r - > out . size = val - > data . length ;
2006-10-15 16:06:10 +00:00
}
2006-09-26 22:03:52 +00:00
2006-11-23 22:58:50 +00:00
return WERR_OK ;
2001-02-25 02:14:49 +00:00
}
2001-08-23 23:25:34 +00:00
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_InitiateSystemShutdown
2001-08-23 23:25:34 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_InitiateSystemShutdown ( struct pipes_struct * p ,
struct winreg_InitiateSystemShutdown * r )
2001-08-23 23:25:34 +00:00
{
2007-01-18 10:18:59 +00:00
struct winreg_InitiateSystemShutdownEx s ;
s . in . hostname = r - > in . hostname ;
s . in . message = r - > in . message ;
s . in . timeout = r - > in . timeout ;
s . in . force_apps = r - > in . force_apps ;
2008-10-15 16:25:06 +02:00
s . in . do_reboot = r - > in . do_reboot ;
2007-01-18 10:18:59 +00:00
s . in . reason = 0 ;
2006-09-21 17:51:06 +00:00
2009-12-04 13:29:08 +01:00
/* thunk down to _winreg_InitiateSystemShutdownEx()
2006-09-21 17:51:06 +00:00
( just returns a status ) */
2009-12-04 13:29:08 +01:00
2007-01-18 10:18:59 +00:00
return _winreg_InitiateSystemShutdownEx ( p , & s ) ;
2005-03-23 23:26:33 +00:00
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_InitiateSystemShutdownEx
2005-03-23 23:26:33 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define SHUTDOWN_R_STRING "-r"
# define SHUTDOWN_F_STRING "-f"
2010-07-28 10:20:10 +02:00
WERROR _winreg_InitiateSystemShutdownEx ( struct pipes_struct * p ,
struct winreg_InitiateSystemShutdownEx * r )
2005-03-23 23:26:33 +00:00
{
2021-10-04 13:40:02 +02:00
struct dcesrv_call_state * dce_call = p - > dce_call ;
struct auth_session_info * session_info =
dcesrv_call_session_info ( dce_call ) ;
2019-11-05 12:07:21 +01:00
const struct loadparm_substitution * lp_sub =
loadparm_s3_global_substitution ( ) ;
2007-11-27 11:22:58 -08:00
char * shutdown_script = NULL ;
char * chkmsg = NULL ;
2006-09-21 17:51:06 +00:00
fstring str_timeout ;
fstring str_reason ;
2008-07-03 12:21:33 -07:00
fstring do_reboot ;
2001-08-23 23:25:34 +00:00
fstring f ;
2010-08-13 10:47:08 -07:00
int ret = - 1 ;
bool can_shutdown = false ;
2005-05-23 16:25:31 +00:00
2019-11-05 12:07:21 +01:00
shutdown_script = lp_shutdown_script ( p - > mem_ctx , lp_sub ) ;
2007-11-27 11:22:58 -08:00
if ( ! shutdown_script ) {
2015-12-03 15:24:15 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2007-11-27 11:22:58 -08:00
}
if ( ! * shutdown_script ) {
2005-03-23 23:26:33 +00:00
return WERR_ACCESS_DENIED ;
2007-11-27 11:22:58 -08:00
}
2005-03-23 23:26:33 +00:00
/* pull the message string and perform necessary sanity checks on it */
2008-10-15 16:13:02 +02:00
if ( r - > in . message & & r - > in . message - > string ) {
2020-01-17 19:30:36 +01:00
chkmsg = talloc_alpha_strcpy ( p - > mem_ctx ,
r - > in . message - > string ,
NULL ) ;
if ( chkmsg = = NULL ) {
2015-12-03 15:24:15 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2006-09-21 17:51:06 +00:00
}
2007-11-27 11:22:58 -08:00
}
2007-01-18 10:18:59 +00:00
fstr_sprintf ( str_timeout , " %d " , r - > in . timeout ) ;
2008-10-15 16:25:06 +02:00
fstr_sprintf ( do_reboot , r - > in . do_reboot ? SHUTDOWN_R_STRING : " " ) ;
2007-01-18 10:18:59 +00:00
fstr_sprintf ( f , r - > in . force_apps ? SHUTDOWN_F_STRING : " " ) ;
fstr_sprintf ( str_reason , " %d " , r - > in . reason ) ;
2001-08-23 23:25:34 +00:00
2007-11-27 11:22:58 -08:00
shutdown_script = talloc_all_string_sub ( p - > mem_ctx ,
shutdown_script , " %z " , chkmsg ? chkmsg : " " ) ;
if ( ! shutdown_script ) {
2015-12-03 15:24:15 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2007-11-27 11:22:58 -08:00
}
shutdown_script = talloc_all_string_sub ( p - > mem_ctx ,
shutdown_script , " %t " , str_timeout ) ;
if ( ! shutdown_script ) {
2015-12-03 15:24:15 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2007-11-27 11:22:58 -08:00
}
shutdown_script = talloc_all_string_sub ( p - > mem_ctx ,
2008-07-03 12:21:33 -07:00
shutdown_script , " %r " , do_reboot ) ;
2007-11-27 11:22:58 -08:00
if ( ! shutdown_script ) {
2015-12-03 15:24:15 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2007-11-27 11:22:58 -08:00
}
shutdown_script = talloc_all_string_sub ( p - > mem_ctx ,
shutdown_script , " %f " , f ) ;
if ( ! shutdown_script ) {
2015-12-03 15:24:15 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2007-11-27 11:22:58 -08:00
}
shutdown_script = talloc_all_string_sub ( p - > mem_ctx ,
shutdown_script , " %x " , str_reason ) ;
if ( ! shutdown_script ) {
2015-12-03 15:24:15 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2007-11-27 11:22:58 -08:00
}
2005-05-23 16:25:31 +00:00
2021-10-04 13:40:02 +02:00
can_shutdown = security_token_has_privilege (
session_info - > security_token , SEC_PRIV_REMOTE_SHUTDOWN ) ;
2007-11-27 11:22:58 -08:00
2005-03-23 23:26:33 +00:00
/* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
Take the error return from the script and provide it as the Windows return code . */
2007-11-27 11:22:58 -08:00
2005-04-05 17:49:16 +00:00
/********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
2007-11-27 11:22:58 -08:00
if ( can_shutdown )
2005-04-05 17:49:16 +00:00
become_root ( ) ;
2005-03-23 23:26:33 +00:00
2016-10-12 09:55:15 -06:00
ret = smbrun ( shutdown_script , NULL , NULL ) ;
2007-11-27 11:22:58 -08:00
2005-04-05 17:49:16 +00:00
if ( can_shutdown )
unbecome_root ( ) ;
/********** END SeRemoteShutdownPrivilege BLOCK **********/
2007-11-27 11:22:58 -08:00
2005-03-23 23:26:33 +00:00
DEBUG ( 3 , ( " _reg_shutdown_ex: Running the command `%s' gave %d \n " ,
shutdown_script , ret ) ) ;
2001-08-23 23:25:34 +00:00
2005-03-23 23:26:33 +00:00
return ( ret = = 0 ) ? WERR_OK : WERR_ACCESS_DENIED ;
2001-08-23 23:25:34 +00:00
}
2001-08-24 07:51:59 +00:00
2002-07-15 10:35:28 +00:00
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_AbortSystemShutdown
2002-07-15 10:35:28 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_AbortSystemShutdown ( struct pipes_struct * p ,
struct winreg_AbortSystemShutdown * r )
2001-08-24 07:51:59 +00:00
{
2021-10-04 13:40:02 +02:00
struct dcesrv_call_state * dce_call = p - > dce_call ;
struct auth_session_info * session_info =
dcesrv_call_session_info ( dce_call ) ;
2019-10-31 16:56:47 +01:00
const char * abort_shutdown_script = NULL ;
const struct loadparm_substitution * lp_sub =
loadparm_s3_global_substitution ( ) ;
2010-08-13 10:47:08 -07:00
int ret = - 1 ;
bool can_shutdown = false ;
2001-08-24 07:51:59 +00:00
2019-10-31 16:56:47 +01:00
abort_shutdown_script = lp_abort_shutdown_script ( talloc_tos ( ) , lp_sub ) ;
2007-11-27 11:22:58 -08:00
if ( ! * abort_shutdown_script )
2005-03-23 23:26:33 +00:00
return WERR_ACCESS_DENIED ;
2007-11-27 11:22:58 -08:00
2021-10-04 13:40:02 +02:00
can_shutdown = security_token_has_privilege (
session_info - > security_token , SEC_PRIV_REMOTE_SHUTDOWN ) ;
2007-11-27 11:22:58 -08:00
2005-04-05 17:49:16 +00:00
/********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
2007-11-27 11:22:58 -08:00
2005-04-05 17:49:16 +00:00
if ( can_shutdown )
become_root ( ) ;
2007-11-15 14:19:52 -08:00
2016-10-12 09:55:15 -06:00
ret = smbrun ( abort_shutdown_script , NULL , NULL ) ;
2007-11-15 14:19:52 -08:00
2005-04-05 17:49:16 +00:00
if ( can_shutdown )
unbecome_root ( ) ;
2007-11-15 14:19:52 -08:00
2005-04-05 17:49:16 +00:00
/********** END SeRemoteShutdownPrivilege BLOCK **********/
2010-03-11 19:25:57 +01:00
DEBUG ( 3 , ( " _winreg_AbortSystemShutdown: Running the command `%s' gave %d \n " ,
2005-03-23 23:26:33 +00:00
abort_shutdown_script , ret ) ) ;
2001-08-24 07:51:59 +00:00
2005-03-23 23:26:33 +00:00
return ( ret = = 0 ) ? WERR_OK : WERR_ACCESS_DENIED ;
2001-08-24 07:51:59 +00:00
}
2002-07-15 10:35:28 +00:00
2002-08-17 15:34:15 +00:00
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_RestoreKey
2005-04-05 17:49:16 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_RestoreKey ( struct pipes_struct * p ,
struct winreg_RestoreKey * r )
2005-04-05 17:49:16 +00:00
{
2020-05-06 13:56:46 +02:00
struct registry_key * regkey = find_regkey_by_hnd ( p ,
r - > in . handle ,
HTYPE_REGKEY ) ;
2007-11-27 11:22:58 -08:00
2019-03-21 14:51:30 -07:00
if ( ! regkey ) {
2015-12-03 15:24:13 +01:00
return WERR_INVALID_HANDLE ;
2007-11-27 11:22:58 -08:00
}
2019-03-21 14:51:30 -07:00
return WERR_BAD_PATHNAME ;
2005-04-05 17:49:16 +00:00
}
2009-12-04 13:33:49 +01:00
/*******************************************************************
_winreg_SaveKey
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_SaveKey ( struct pipes_struct * p ,
struct winreg_SaveKey * r )
2002-08-17 15:34:15 +00:00
{
2020-05-06 13:56:46 +02:00
struct registry_key * regkey = find_regkey_by_hnd ( p ,
r - > in . handle ,
HTYPE_REGKEY ) ;
2007-11-27 11:22:58 -08:00
2019-03-21 14:51:30 -07:00
if ( ! regkey ) {
2015-12-03 15:24:13 +01:00
return WERR_INVALID_HANDLE ;
2007-11-27 11:22:58 -08:00
}
2019-03-21 14:51:30 -07:00
return WERR_BAD_PATHNAME ;
2006-09-21 17:51:06 +00:00
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_SaveKeyEx
2006-09-21 17:51:06 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_SaveKeyEx ( struct pipes_struct * p ,
struct winreg_SaveKeyEx * r )
2006-09-21 17:51:06 +00:00
{
2006-09-27 16:05:25 +00:00
/* fill in your code here if you think this call should
do anything */
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-21 17:51:06 +00:00
return WERR_NOT_SUPPORTED ;
2002-08-17 15:34:15 +00:00
}
2005-06-16 20:04:16 +00:00
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_CreateKey
2005-06-16 20:04:16 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_CreateKey ( struct pipes_struct * p ,
struct winreg_CreateKey * r )
2005-06-16 20:04:16 +00:00
{
2020-05-06 13:56:46 +02:00
struct registry_key * parent = find_regkey_by_hnd ( p ,
r - > in . handle ,
HTYPE_REGKEY ) ;
2010-08-13 10:47:08 -07:00
struct registry_key * new_key = NULL ;
WERROR result = WERR_OK ;
2005-06-17 15:35:31 +00:00
if ( ! parent )
2015-12-03 15:24:13 +01:00
return WERR_INVALID_HANDLE ;
2006-09-21 17:51:06 +00:00
2008-03-28 15:39:52 +01:00
DEBUG ( 10 , ( " _winreg_CreateKey called with parent key '%s' and "
" subkey name '%s' \n " , parent - > key - > name , r - > in . name . name ) ) ;
2007-01-18 10:18:59 +00:00
result = reg_createkey ( NULL , parent , r - > in . name . name , r - > in . access_mask ,
& new_key , r - > out . action_taken ) ;
2006-12-01 20:01:09 +00:00
if ( ! W_ERROR_IS_OK ( result ) ) {
return result ;
2005-08-29 14:55:40 +00:00
}
2020-04-28 21:59:46 +03:00
if ( ! create_policy_hnd ( p , r - > out . new_handle , HTYPE_REGKEY , new_key ) ) {
2006-12-01 20:01:09 +00:00
TALLOC_FREE ( new_key ) ;
2015-12-03 15:24:11 +01:00
return WERR_FILE_NOT_FOUND ;
2006-09-26 22:39:40 +00:00
}
2005-06-17 15:35:31 +00:00
2006-12-01 20:01:09 +00:00
return WERR_OK ;
2005-06-16 20:04:16 +00:00
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_SetValue
2005-06-16 20:04:16 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_SetValue ( struct pipes_struct * p ,
struct winreg_SetValue * r )
2005-06-16 20:04:16 +00:00
{
2020-05-06 13:56:46 +02:00
struct registry_key * key = find_regkey_by_hnd ( p ,
r - > in . handle ,
HTYPE_REGKEY ) ;
2010-08-13 10:47:08 -07:00
struct registry_value * val = NULL ;
2005-06-17 15:35:31 +00:00
2006-12-01 20:01:09 +00:00
if ( ! key )
2015-12-03 15:24:13 +01:00
return WERR_INVALID_HANDLE ;
2006-11-23 22:58:50 +00:00
2010-03-11 19:25:57 +01:00
DEBUG ( 8 , ( " _winreg_SetValue: Setting value for [%s:%s] \n " ,
2007-01-18 10:18:59 +00:00
key - > key - > name , r - > in . name . name ) ) ;
2006-11-23 22:58:50 +00:00
2010-06-29 16:13:15 +02:00
val = talloc_zero ( p - > mem_ctx , struct registry_value ) ;
if ( val = = NULL ) {
2015-12-03 15:24:15 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2006-12-01 20:01:09 +00:00
}
2006-11-23 22:58:50 +00:00
2010-06-29 16:13:15 +02:00
val - > type = r - > in . type ;
val - > data = data_blob_talloc ( p - > mem_ctx , r - > in . data , r - > in . size ) ;
2007-01-18 10:18:59 +00:00
return reg_setvalue ( key , r - > in . name . name , val ) ;
2005-06-16 20:04:16 +00:00
}
2002-07-15 10:35:28 +00:00
2005-06-16 20:59:39 +00:00
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_DeleteKey
2005-06-16 20:59:39 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_DeleteKey ( struct pipes_struct * p ,
struct winreg_DeleteKey * r )
2005-06-16 20:59:39 +00:00
{
2020-05-06 13:56:46 +02:00
struct registry_key * parent = find_regkey_by_hnd ( p ,
r - > in . handle ,
HTYPE_REGKEY ) ;
2005-06-17 15:35:31 +00:00
if ( ! parent )
2015-12-03 15:24:13 +01:00
return WERR_INVALID_HANDLE ;
2005-09-30 17:13:37 +00:00
2007-01-18 10:18:59 +00:00
return reg_deletekey ( parent , r - > in . key . name ) ;
2005-06-16 20:59:39 +00:00
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_DeleteValue
2005-06-16 20:59:39 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_DeleteValue ( struct pipes_struct * p ,
struct winreg_DeleteValue * r )
2005-06-16 20:59:39 +00:00
{
2020-05-06 13:56:46 +02:00
struct registry_key * key = find_regkey_by_hnd ( p ,
r - > in . handle ,
HTYPE_REGKEY ) ;
2009-12-04 13:29:08 +01:00
2006-12-01 20:01:09 +00:00
if ( ! key )
2015-12-03 15:24:13 +01:00
return WERR_INVALID_HANDLE ;
2006-11-23 22:58:50 +00:00
2007-01-18 10:18:59 +00:00
return reg_deletevalue ( key , r - > in . value . name ) ;
2005-06-16 20:59:39 +00:00
}
2005-06-24 22:34:40 +00:00
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_GetKeySecurity
2005-06-24 22:34:40 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_GetKeySecurity ( struct pipes_struct * p ,
struct winreg_GetKeySecurity * r )
2005-06-24 22:34:40 +00:00
{
2020-05-06 13:56:46 +02:00
struct registry_key * key = find_regkey_by_hnd ( p ,
r - > in . handle ,
HTYPE_REGKEY ) ;
2010-08-13 10:47:08 -07:00
WERROR err = WERR_OK ;
struct security_descriptor * secdesc = NULL ;
2015-05-14 18:08:27 -07:00
uint8_t * data = NULL ;
2010-08-13 10:47:08 -07:00
size_t len = 0 ;
2005-06-24 22:34:40 +00:00
if ( ! key )
2015-12-03 15:24:13 +01:00
return WERR_INVALID_HANDLE ;
2009-12-04 13:29:08 +01:00
2005-06-24 22:34:40 +00:00
/* access checks first */
2009-12-04 13:29:08 +01:00
2010-06-03 10:36:05 +02:00
if ( ! ( key - > key - > access_granted & SEC_STD_READ_CONTROL ) )
2005-06-24 22:34:40 +00:00
return WERR_ACCESS_DENIED ;
2006-11-30 07:38:40 +00:00
2008-01-17 11:06:32 +01:00
err = reg_getkeysecurity ( p - > mem_ctx , key , & secdesc ) ;
2006-11-30 07:38:40 +00:00
if ( ! W_ERROR_IS_OK ( err ) ) {
return err ;
}
err = ntstatus_to_werror ( marshall_sec_desc ( p - > mem_ctx , secdesc ,
& data , & len ) ) ;
if ( ! W_ERROR_IS_OK ( err ) ) {
return err ;
}
2007-01-18 10:18:59 +00:00
if ( len > r - > out . sd - > size ) {
r - > out . sd - > size = len ;
2006-11-30 07:38:40 +00:00
return WERR_INSUFFICIENT_BUFFER ;
}
2007-01-18 10:18:59 +00:00
r - > out . sd - > size = len ;
r - > out . sd - > len = len ;
r - > out . sd - > data = data ;
2009-12-04 13:29:08 +01:00
2006-11-30 07:38:40 +00:00
return WERR_OK ;
2005-06-24 22:34:40 +00:00
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_SetKeySecurity
2005-06-24 22:34:40 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_SetKeySecurity ( struct pipes_struct * p ,
struct winreg_SetKeySecurity * r )
2005-06-24 22:34:40 +00:00
{
2020-05-06 13:56:46 +02:00
struct registry_key * key = find_regkey_by_hnd ( p ,
r - > in . handle ,
HTYPE_REGKEY ) ;
2010-08-13 10:47:08 -07:00
struct security_descriptor * secdesc = NULL ;
WERROR err = WERR_OK ;
2005-06-24 22:34:40 +00:00
if ( ! key )
2015-12-03 15:24:13 +01:00
return WERR_INVALID_HANDLE ;
2009-12-04 13:29:08 +01:00
2005-06-24 22:34:40 +00:00
/* access checks first */
2009-12-04 13:29:08 +01:00
2010-06-03 10:36:05 +02:00
if ( ! ( key - > key - > access_granted & SEC_STD_WRITE_DAC ) )
2005-06-24 22:34:40 +00:00
return WERR_ACCESS_DENIED ;
2006-11-30 07:38:40 +00:00
2007-01-18 10:18:59 +00:00
err = ntstatus_to_werror ( unmarshall_sec_desc ( p - > mem_ctx , r - > in . sd - > data ,
r - > in . sd - > len , & secdesc ) ) ;
2006-11-30 07:38:40 +00:00
if ( ! W_ERROR_IS_OK ( err ) ) {
return err ;
}
2008-01-17 11:06:32 +01:00
return reg_setkeysecurity ( key , secdesc ) ;
2005-06-24 22:34:40 +00:00
}
2006-09-21 17:51:06 +00:00
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_FlushKey
2006-09-21 17:51:06 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_FlushKey ( struct pipes_struct * p ,
struct winreg_FlushKey * r )
2006-09-21 17:51:06 +00:00
{
2009-12-04 13:29:08 +01:00
/* I'm just replying OK because there's not a lot
2006-09-21 17:51:06 +00:00
here I see to do i - - jerry */
2009-12-04 13:29:08 +01:00
2006-09-21 17:51:06 +00:00
return WERR_OK ;
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_UnLoadKey
2006-09-21 17:51:06 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_UnLoadKey ( struct pipes_struct * p ,
struct winreg_UnLoadKey * r )
2006-09-21 17:51:06 +00:00
{
/* fill in your code here if you think this call should
do anything */
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-21 17:51:06 +00:00
return WERR_NOT_SUPPORTED ;
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_ReplaceKey
2006-09-21 17:51:06 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_ReplaceKey ( struct pipes_struct * p ,
struct winreg_ReplaceKey * r )
2006-09-21 17:51:06 +00:00
{
/* fill in your code here if you think this call should
do anything */
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-21 17:51:06 +00:00
return WERR_NOT_SUPPORTED ;
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_LoadKey
2006-09-21 17:51:06 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_LoadKey ( struct pipes_struct * p ,
struct winreg_LoadKey * r )
2006-09-21 17:51:06 +00:00
{
/* fill in your code here if you think this call should
do anything */
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2006-09-21 17:51:06 +00:00
return WERR_NOT_SUPPORTED ;
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_NotifyChangeKeyValue
2006-09-21 17:51:06 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_NotifyChangeKeyValue ( struct pipes_struct * p ,
struct winreg_NotifyChangeKeyValue * r )
2006-09-21 17:51:06 +00:00
{
return WERR_NOT_SUPPORTED ;
}
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_QueryMultipleValues
2006-09-21 17:51:06 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_QueryMultipleValues ( struct pipes_struct * p ,
2010-06-30 16:31:46 +02:00
struct winreg_QueryMultipleValues * r )
{
struct winreg_QueryMultipleValues2 r2 ;
2010-08-13 10:47:08 -07:00
uint32_t needed = 0 ;
2010-06-30 16:31:46 +02:00
r2 . in . key_handle = r - > in . key_handle ;
r2 . in . values_in = r - > in . values_in ;
r2 . in . num_values = r - > in . num_values ;
r2 . in . offered = r - > in . buffer_size ;
r2 . in . buffer = r - > in . buffer ;
r2 . out . values_out = r - > out . values_out ;
r2 . out . needed = & needed ;
r2 . out . buffer = r - > out . buffer ;
return _winreg_QueryMultipleValues2 ( p , & r2 ) ;
2006-09-21 17:51:06 +00:00
}
2010-06-30 02:03:27 +02:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static WERROR construct_multiple_entry ( TALLOC_CTX * mem_ctx ,
const char * valuename ,
uint32_t value_length ,
uint32_t offset ,
enum winreg_Type type ,
struct QueryMultipleValue * r )
{
r - > ve_valuename = talloc_zero ( mem_ctx , struct winreg_ValNameBuf ) ;
if ( r - > ve_valuename = = NULL ) {
2015-12-03 15:24:15 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2010-06-30 02:03:27 +02:00
}
r - > ve_valuename - > name = talloc_strdup ( r - > ve_valuename , valuename ? valuename : " " ) ;
if ( r - > ve_valuename - > name = = NULL ) {
2015-12-03 15:24:15 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2010-06-30 02:03:27 +02:00
}
r - > ve_valuename - > size = strlen_m_term ( r - > ve_valuename - > name ) * 2 ;
r - > ve_valuelen = value_length ;
r - > ve_valueptr = offset ;
r - > ve_type = type ;
return WERR_OK ;
}
2006-09-21 17:51:06 +00:00
/*******************************************************************
2009-12-04 13:33:49 +01:00
_winreg_QueryMultipleValues2
2006-09-21 17:51:06 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_QueryMultipleValues2 ( struct pipes_struct * p ,
2010-06-30 02:03:27 +02:00
struct winreg_QueryMultipleValues2 * r )
2006-09-21 17:51:06 +00:00
{
2020-05-06 13:56:46 +02:00
struct registry_key * regkey = find_regkey_by_hnd ( p ,
r - > in . key_handle ,
HTYPE_REGKEY ) ;
2010-06-30 02:03:27 +02:00
struct registry_value * vals = NULL ;
const char * * names = NULL ;
uint32_t offset = 0 , num_vals = 0 ;
2010-08-13 10:47:08 -07:00
DATA_BLOB result = data_blob_null ;
2021-03-27 16:42:29 +01:00
uint32_t i = 0 ;
2010-08-13 10:47:08 -07:00
WERROR err = WERR_OK ;
2006-09-21 17:51:06 +00:00
2010-06-30 02:03:27 +02:00
if ( ! regkey ) {
2015-12-03 15:24:13 +01:00
return WERR_INVALID_HANDLE ;
2010-06-30 02:03:27 +02:00
}
names = talloc_zero_array ( p - > mem_ctx , const char * , r - > in . num_values ) ;
if ( names = = NULL ) {
2015-12-03 15:24:15 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2010-06-30 02:03:27 +02:00
}
for ( i = 0 ; i < r - > in . num_values ; i + + ) {
if ( r - > in . values_in [ i ] . ve_valuename & &
r - > in . values_in [ i ] . ve_valuename - > name ) {
names [ i ] = talloc_strdup ( names ,
r - > in . values_in [ i ] . ve_valuename - > name ) ;
if ( names [ i ] = = NULL ) {
2015-12-03 15:24:15 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2010-06-30 02:03:27 +02:00
}
}
}
err = reg_querymultiplevalues ( p - > mem_ctx , regkey ,
r - > in . num_values , names ,
& num_vals , & vals ) ;
if ( ! W_ERROR_IS_OK ( err ) ) {
return err ;
}
result = data_blob_talloc ( p - > mem_ctx , NULL , 0 ) ;
for ( i = 0 ; i < r - > in . num_values ; i + + ) {
const char * valuename = NULL ;
2010-06-29 16:13:15 +02:00
if ( vals [ i ] . data . length > 0 ) {
2010-06-30 02:03:27 +02:00
if ( ! data_blob_append ( p - > mem_ctx , & result ,
2010-06-29 16:13:15 +02:00
vals [ i ] . data . data ,
vals [ i ] . data . length ) ) {
2015-12-03 15:24:15 +01:00
return WERR_NOT_ENOUGH_MEMORY ;
2010-06-30 02:03:27 +02:00
}
}
if ( r - > in . values_in [ i ] . ve_valuename & &
r - > in . values_in [ i ] . ve_valuename - > name ) {
valuename = r - > in . values_in [ i ] . ve_valuename - > name ;
}
err = construct_multiple_entry ( r - > out . values_out ,
valuename ,
2010-06-29 16:13:15 +02:00
vals [ i ] . data . length ,
2010-06-30 02:03:27 +02:00
offset ,
vals [ i ] . type ,
& r - > out . values_out [ i ] ) ;
if ( ! W_ERROR_IS_OK ( err ) ) {
return err ;
}
2010-06-29 16:13:15 +02:00
offset + = vals [ i ] . data . length ;
2010-06-30 02:03:27 +02:00
}
* r - > out . needed = result . length ;
if ( r - > in . num_values ! = num_vals ) {
2015-12-03 15:24:11 +01:00
return WERR_FILE_NOT_FOUND ;
2010-06-30 02:03:27 +02:00
}
if ( * r - > in . offered > = * r - > out . needed ) {
if ( r - > out . buffer ) {
memcpy ( r - > out . buffer , result . data , MIN ( result . length , * r - > in . offered ) ) ;
}
return WERR_OK ;
} else {
return WERR_MORE_DATA ;
}
2006-09-21 17:51:06 +00:00
}
2010-04-09 00:11:41 +02:00
/*******************************************************************
_winreg_DeleteKeyEx
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-28 10:20:10 +02:00
WERROR _winreg_DeleteKeyEx ( struct pipes_struct * p ,
struct winreg_DeleteKeyEx * r )
2010-04-09 00:11:41 +02:00
{
/* fill in your code here if you think this call should
do anything */
2012-06-27 15:21:11 +02:00
p - > fault_state = DCERPC_FAULT_OP_RNG_ERROR ;
2010-04-09 00:11:41 +02:00
return WERR_NOT_SUPPORTED ;
}
2019-02-22 18:30:45 +01:00
/* include the generated boilerplate */
# include "librpc/gen_ndr/ndr_winreg_scompat.c"