summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/utils/net_rpc_registry.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/source3/utils/net_rpc_registry.c b/source3/utils/net_rpc_registry.c
index 564d79e9f9..42370089e5 100644
--- a/source3/utils/net_rpc_registry.c
+++ b/source3/utils/net_rpc_registry.c
@@ -488,6 +488,104 @@ static int rpc_registry_deletevalue( int argc, const char **argv )
rpc_registry_deletevalue_internal, argc, argv );
}
+static NTSTATUS rpc_registry_getvalue_internal(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
+{
+ struct policy_handle hive_hnd, key_hnd;
+ NTSTATUS status;
+ WERROR werr;
+ struct winreg_String valuename;
+ struct registry_value *value = NULL;
+ enum winreg_Type type = REG_NONE;
+ uint8_t *data = NULL;
+ uint32_t data_size = 0;
+ uint32_t value_length = 0;
+ TALLOC_CTX *tmp_ctx = talloc_stackframe();
+
+ ZERO_STRUCT(valuename);
+
+ status = registry_openkey(tmp_ctx, pipe_hnd, argv[0],
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &hive_hnd, &key_hnd);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "registry_openkey failed: %s\n",
+ nt_errstr(status));
+ return status;
+ }
+
+ valuename.name = argv[1];
+
+ /*
+ * call QueryValue once with data == NULL to get the
+ * needed memory size to be allocated, then allocate
+ * data buffer and call again.
+ */
+ status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
+ &valuename,
+ &type,
+ data,
+ &data_size,
+ &value_length,
+ NULL);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "registry_queryvalue failed: %s\n",
+ nt_errstr(status));
+ goto done;
+ }
+
+ data = (uint8 *)TALLOC(tmp_ctx, data_size);
+ value_length = 0;
+
+ status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
+ &valuename,
+ &type,
+ data,
+ &data_size,
+ &value_length,
+ NULL);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "registry_queryvalue failed: %s\n",
+ nt_errstr(status));
+ goto done;
+ }
+
+ werr = registry_pull_value(tmp_ctx, &value, type, data,
+ data_size, value_length);
+ if (!W_ERROR_IS_OK(werr)) {
+ status = werror_to_ntstatus(werr);
+ goto done;
+ }
+
+ print_registry_value(value);
+
+done:
+ rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &key_hnd, NULL);
+ rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &hive_hnd, NULL);
+
+ TALLOC_FREE(tmp_ctx);
+
+ return status;
+}
+
+static int rpc_registry_getvalue(int argc, const char **argv)
+{
+ if (argc != 2) {
+ d_fprintf(stderr, "usage: net rpc registry deletevalue <key> "
+ "<valuename>\n");
+ return -1;
+ }
+
+ return run_rpc_command(NULL, PI_WINREG, 0,
+ rpc_registry_getvalue_internal, argc, argv);
+}
+
static NTSTATUS rpc_registry_createkey_internal(const DOM_SID *domain_sid,
const char *domain_name,
struct cli_state *cli,
@@ -1069,6 +1167,8 @@ int net_rpc_registry(int argc, const char **argv)
"Create a new registry key" },
{ "deletekey", rpc_registry_deletekey,
"Delete a registry key" },
+ { "getvalue", rpc_registry_getvalue,
+ "Print a registry value" },
{ "setvalue", rpc_registry_setvalue,
"Set a new registry value" },
{ "deletevalue", rpc_registry_deletevalue,