From 22855c7aae940cc4082c231a470f612b8fc6fa0d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 5 Apr 2005 17:49:16 +0000 Subject: [PATCH] r6218: * fix a segv in EnumPrinters():rpc_buffer_alloc when the caller does not provide an RPC_BUFFER in the request * add initial (but wire untested) support for RegRestoreKey() --- source/include/rpc_reg.h | 30 ++++++------ source/rpc_parse/parse_buffer.c | 5 ++ source/rpc_parse/parse_reg.c | 48 +++++++++++++++++++ source/rpc_server/srv_reg.c | 30 ++++++++++-- source/rpc_server/srv_reg_nt.c | 82 +++++++++++++++++++++------------ 5 files changed, 149 insertions(+), 46 deletions(-) diff --git a/source/include/rpc_reg.h b/source/include/rpc_reg.h index 9f97d49715..51f8ff8d96 100644 --- a/source/include/rpc_reg.h +++ b/source/include/rpc_reg.h @@ -25,19 +25,8 @@ #ifndef _RPC_REG_H /* _RPC_REG_H */ #define _RPC_REG_H +/* RPC opnum */ -/* winreg pipe defines - NOT IMPLEMENTED !! -#define _REG_UNK_01 0x01 -#define _REG_UNK_0D 0x0d -#define _REG_UNK_0E 0x0e -#define _REG_UNK_12 0x12 -#define _REG_UNK_13 0x13 -#define _REG_UNK_17 0x17 - -*/ - -/* Implemented */ #define REG_OPEN_HKCR 0x00 #define REG_OPEN_HKLM 0x02 #define REG_OPEN_HKPD 0x03 @@ -53,6 +42,7 @@ #define REG_OPEN_ENTRY 0x0f #define REG_QUERY_KEY 0x10 #define REG_INFO 0x11 +#define REG_RESTORE_KEY 0x13 #define REG_SAVE_KEY 0x14 #define REG_SET_KEY_SEC 0x15 #define REG_CREATE_VALUE 0x16 @@ -331,7 +321,20 @@ typedef struct { typedef struct { POLICY_HND pol; UNISTR4 filename; - uint32 unknown; /* 0x0000 0000 */ + uint32 flags; +} REG_Q_RESTORE_KEY; + +typedef struct { + WERROR status; /* return status */ +} REG_R_RESTORE_KEY; + + +/***********************************************/ + +typedef struct { + POLICY_HND pol; + UNISTR4 filename; + uint32 unknown; /* I'm pretty sure this is a pointer to a SEC_DESC as per MSDN */ } REG_Q_SAVE_KEY; @@ -340,7 +343,6 @@ typedef struct { } REG_R_SAVE_KEY; - /***********************************************/ typedef struct { diff --git a/source/rpc_parse/parse_buffer.c b/source/rpc_parse/parse_buffer.c index ea72df8db4..a48d5cfa98 100644 --- a/source/rpc_parse/parse_buffer.c +++ b/source/rpc_parse/parse_buffer.c @@ -134,6 +134,11 @@ BOOL rpcbuf_alloc_size(RPC_BUFFER *buffer, uint32 buffer_size) uint32 extra_space; uint32 old_offset; + /* if we don't need anything. don't do anything */ + + if ( buffer_size == 0x0 ) + return True; + ps= &buffer->prs; /* damn, I'm doing the reverse operation of prs_grow() :) */ diff --git a/source/rpc_parse/parse_reg.c b/source/rpc_parse/parse_reg.c index fabffd2b6d..09e19bf701 100644 --- a/source/rpc_parse/parse_reg.c +++ b/source/rpc_parse/parse_reg.c @@ -568,6 +568,54 @@ BOOL reg_io_r_getversion(const char *desc, REG_R_GETVERSION *r_u, prs_struct *p } +/******************************************************************* +reads or writes a structure. +********************************************************************/ + +BOOL reg_io_q_restore_key(const char *desc, REG_Q_RESTORE_KEY *q_u, prs_struct *ps, int depth) +{ + if ( !q_u ) + return False; + + prs_debug(ps, depth, desc, "reg_io_q_restore_key"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_pol_hnd("", &q_u->pol, ps, depth)) + return False; + + if(!prs_unistr4("filename", ps, depth, &q_u->filename)) + return False; + + if(!prs_uint32("flags", ps, depth, &q_u->flags)) + return False; + + return True; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ + +BOOL reg_io_r_restore_key(const char *desc, REG_R_RESTORE_KEY *r_u, prs_struct *ps, int depth) +{ + if ( !r_u ) + return False; + + prs_debug(ps, depth, desc, "reg_io_r_restore_key"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_werror("status" , ps, depth, &r_u->status)) + return False; + + return True; +} + /******************************************************************* reads or writes a structure. ********************************************************************/ diff --git a/source/rpc_server/srv_reg.c b/source/rpc_server/srv_reg.c index b2b3920e9e..a90650c536 100644 --- a/source/rpc_server/srv_reg.c +++ b/source/rpc_server/srv_reg.c @@ -369,8 +369,31 @@ static BOOL api_reg_enum_value(pipes_struct *p) } /******************************************************************* - api_reg_save_key - ********************************************************************/ + ******************************************************************/ + +static BOOL api_reg_restore_key(pipes_struct *p) +{ + REG_Q_RESTORE_KEY q_u; + REG_R_RESTORE_KEY r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!reg_io_q_restore_key("", &q_u, data, 0)) + return False; + + r_u.status = _reg_restore_key(p, &q_u, &r_u); + + if(!reg_io_r_restore_key("", &r_u, rdata, 0)) + return False; + + return True; +} + +/******************************************************************* + ******************************************************************/ static BOOL api_reg_save_key(pipes_struct *p) { @@ -412,7 +435,8 @@ static struct api_struct api_reg_cmds[] = { "REG_SHUTDOWN_EX" , REG_SHUTDOWN_EX , api_reg_shutdown_ex }, { "REG_ABORT_SHUTDOWN" , REG_ABORT_SHUTDOWN , api_reg_abort_shutdown }, { "REG_GETVERSION" , REG_GETVERSION , api_reg_getversion }, - { "REG_SAVE_KEY" , REG_SAVE_KEY , api_reg_save_key } + { "REG_SAVE_KEY" , REG_SAVE_KEY , api_reg_save_key }, + { "REG_RESTORE_KEY" , REG_RESTORE_KEY , api_reg_restore_key } }; void reg_get_pipe_fns( struct api_struct **fns, int *n_fns ) diff --git a/source/rpc_server/srv_reg_nt.c b/source/rpc_server/srv_reg_nt.c index f0d831cc6a..ad7aaa4469 100644 --- a/source/rpc_server/srv_reg_nt.c +++ b/source/rpc_server/srv_reg_nt.c @@ -561,8 +561,7 @@ WERROR _reg_enum_value(pipes_struct *p, REG_Q_ENUM_VALUE *q_u, REG_R_ENUM_VALUE DEBUG(8,("_reg_enum_key: enumerating values for key [%s]\n", regkey->name)); - if ( !fetch_reg_values_specific( regkey, &val, q_u->val_index ) ) - { + if ( !fetch_reg_values_specific( regkey, &val, q_u->val_index ) ) { status = WERR_NO_MORE_ITEMS; goto done; } @@ -587,10 +586,6 @@ done: reg_shutdwon ********************************************************************/ -#define SHUTDOWN_R_STRING "-r" -#define SHUTDOWN_F_STRING "-f" - - WERROR _reg_shutdown(pipes_struct *p, REG_Q_SHUTDOWN *q_u, REG_R_SHUTDOWN *r_u) { REG_Q_SHUTDOWN_EX q_u_ex; @@ -630,7 +625,6 @@ WERROR _reg_shutdown_ex(pipes_struct *p, REG_Q_SHUTDOWN_EX *q_u, REG_R_SHUTDOWN_ int ret; BOOL can_shutdown; - pstrcpy(shutdown_script, lp_shutdown_script()); if ( !*shutdown_script ) @@ -659,25 +653,24 @@ WERROR _reg_shutdown_ex(pipes_struct *p, REG_Q_SHUTDOWN_EX *q_u, REG_R_SHUTDOWN_ can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown ); - /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/ - /* 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. */ - if ( can_shutdown ) { - DEBUG(3,("_reg_shutdown_ex: Privilege Check is OK for shutdown \n")); - become_root(); - } + /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/ + + if ( can_shutdown ) + become_root(); ret = smbrun( shutdown_script, NULL ); + if ( can_shutdown ) + unbecome_root(); + + /********** END SeRemoteShutdownPrivilege BLOCK **********/ + DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n", shutdown_script, ret)); - if ( can_shutdown ) - unbecome_root(); - - /********** END SeRemoteShutdownPrivilege BLOCK **********/ return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED; } @@ -702,26 +695,53 @@ WERROR _reg_abort_shutdown(pipes_struct *p, REG_Q_ABORT_SHUTDOWN *q_u, REG_R_ABO can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown ); - /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/ + /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/ - if ( can_shutdown ) - become_root(); + if ( can_shutdown ) + become_root(); ret = smbrun( abort_shutdown_script, NULL ); + if ( can_shutdown ) + unbecome_root(); + + /********** END SeRemoteShutdownPrivilege BLOCK **********/ + DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n", abort_shutdown_script, ret)); - if ( can_shutdown ) - unbecome_root(); - - /********** END SeRemoteShutdownPrivilege BLOCK **********/ return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED; } /******************************************************************* - REG_SAVE_KEY (0x14) + ********************************************************************/ + +WERROR _reg_restore_key(pipes_struct *p, REG_Q_RESTORE_KEY *q_u, REG_R_RESTORE_KEY *r_u) +{ + REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol ); + + DEBUG(5,("_reg_restore_key: Enter\n")); + + /* + * basically this is a no op function which just verifies + * that the client gave us a valid registry key handle + */ + + if ( !regkey ) + return WERR_BADFID; + + DEBUG(8,("_reg_restore_key: verifying backup of key [%s]\n", regkey->name)); + +#if 0 + validate_reg_filemame( filename ); + return restore_registry_key( regkey, filename ); +#endif + + return WERR_OK; +} + +/******************************************************************* ********************************************************************/ WERROR _reg_save_key(pipes_struct *p, REG_Q_SAVE_KEY *q_u, REG_R_SAVE_KEY *r_u) @@ -731,15 +751,19 @@ WERROR _reg_save_key(pipes_struct *p, REG_Q_SAVE_KEY *q_u, REG_R_SAVE_KEY *r_u) DEBUG(5,("_reg_save_key: Enter\n")); /* - * basically this is a no op function which just gverifies + * basically this is a no op function which just verifies * that the client gave us a valid registry key handle */ if ( !regkey ) - return WERR_BADFID; /* This will be reported as an RPC fault anyway. */ + return WERR_BADFID; - DEBUG(8,("_reg_save_key: berifying backup of key [%s]\n", regkey->name)); - + DEBUG(8,("_reg_save_key: verifying backup of key [%s]\n", regkey->name)); + +#if 0 + validate_reg_filemame( filename ); + return backup_registry_key( regkey, filename ); +#endif return WERR_OK; } -- 2.34.1