summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-04-05 17:49:16 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:56:29 -0500
commitb4c720412978c0a49e11846c7cfe553d055cca1f (patch)
tree116877fbe698b0a9babb1faacab28d1b83bc1225 /source3
parent78355805efb1e8e3ef9a5073841275ffa80da77a (diff)
downloadsamba-b4c720412978c0a49e11846c7cfe553d055cca1f.tar.gz
samba-b4c720412978c0a49e11846c7cfe553d055cca1f.tar.bz2
samba-b4c720412978c0a49e11846c7cfe553d055cca1f.zip
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() (This used to be commit 22855c7aae940cc4082c231a470f612b8fc6fa0d)
Diffstat (limited to 'source3')
-rw-r--r--source3/include/rpc_reg.h30
-rw-r--r--source3/rpc_parse/parse_buffer.c5
-rw-r--r--source3/rpc_parse/parse_reg.c48
-rw-r--r--source3/rpc_server/srv_reg.c30
-rw-r--r--source3/rpc_server/srv_reg_nt.c82
5 files changed, 149 insertions, 46 deletions
diff --git a/source3/include/rpc_reg.h b/source3/include/rpc_reg.h
index 9f97d49715..51f8ff8d96 100644
--- a/source3/include/rpc_reg.h
+++ b/source3/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/source3/rpc_parse/parse_buffer.c b/source3/rpc_parse/parse_buffer.c
index ea72df8db4..a48d5cfa98 100644
--- a/source3/rpc_parse/parse_buffer.c
+++ b/source3/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/source3/rpc_parse/parse_reg.c b/source3/rpc_parse/parse_reg.c
index fabffd2b6d..09e19bf701 100644
--- a/source3/rpc_parse/parse_reg.c
+++ b/source3/rpc_parse/parse_reg.c
@@ -572,6 +572,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.
+********************************************************************/
+
BOOL reg_io_q_save_key(const char *desc, REG_Q_SAVE_KEY *q_u, prs_struct *ps, int depth)
{
if ( !q_u )
diff --git a/source3/rpc_server/srv_reg.c b/source3/rpc_server/srv_reg.c
index b2b3920e9e..a90650c536 100644
--- a/source3/rpc_server/srv_reg.c
+++ b/source3/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/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c
index f0d831cc6a..ad7aaa4469 100644
--- a/source3/rpc_server/srv_reg_nt.c
+++ b/source3/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;
}