From 7f8276b06d5000d12c0d64167853a033b924af32 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 7 Jan 2008 14:11:25 -0600 Subject: r26688: Fix listing remote predefined keys and subkeys. This fixes bug 3431. (This used to be commit 846876ad32dc86fe7c367db084e76c670c61b389) --- source4/lib/registry/local.c | 4 +- source4/lib/registry/registry.h | 1 - source4/lib/registry/rpc.c | 89 ++++++++++++++++++++++++------------- source4/lib/registry/tools/common.c | 6 +-- 4 files changed, 64 insertions(+), 36 deletions(-) (limited to 'source4') diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index 14b42797ba..35724e7ea6 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -30,7 +30,7 @@ struct reg_key_path { }; struct registry_local { - struct registry_context registry; + const struct registry_operations *ops; struct mountpoint { struct reg_key_path path; @@ -299,7 +299,7 @@ WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx, W_ERROR_HAVE_NO_MEMORY(ret); - ret->registry.ops = &local_ops; + ret->ops = &local_ops; ret->session_info = session_info; ret->credentials = credentials; diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 7999719909..8273333b24 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -80,7 +80,6 @@ typedef void (*reg_key_notification_function) (void); typedef void (*reg_value_notification_function) (void); struct cli_credentials; -struct registry_context; struct registry_operations { const char *name; diff --git a/source4/lib/registry/rpc.c b/source4/lib/registry/rpc.c index 7f800b786e..2a6cabc3b8 100644 --- a/source4/lib/registry/rpc.c +++ b/source4/lib/registry/rpc.c @@ -96,9 +96,10 @@ static WERROR rpc_get_predefined_key(struct registry_context *ctx, struct registry_key **k) { int n; - struct rpc_registry_context *rctx = talloc_get_type(ctx, - struct rpc_registry_context); struct rpc_key *mykeydata; + struct rpc_registry_context *rctx = talloc_get_type(ctx, struct rpc_registry_context); + + *k = NULL; for(n = 0; known_hives[n].hkey; n++) { if(known_hives[n].hkey == hkey_type) @@ -110,11 +111,13 @@ static WERROR rpc_get_predefined_key(struct registry_context *ctx, return WERR_NO_MORE_ITEMS; } - mykeydata = talloc(ctx, struct rpc_key); - mykeydata->pipe = rctx->pipe; + mykeydata = talloc_zero(ctx, struct rpc_key); + mykeydata->key.context = ctx; + mykeydata->pipe = talloc_reference(mykeydata, rctx->pipe); mykeydata->num_values = -1; mykeydata->num_subkeys = -1; - return known_hives[n].open(mykeydata->pipe, *k, &(mykeydata->pol)); + *k = (struct registry_key *)mykeydata; + return known_hives[n].open(mykeydata->pipe, mykeydata, &(mykeydata->pol)); } #if 0 @@ -146,21 +149,32 @@ static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const char *name, struct registry_key **key) { - struct rpc_key *mykeydata = talloc_get_type(h, struct rpc_key), - *newkeydata; + struct rpc_key *parentkeydata = talloc_get_type(h, struct rpc_key), + *mykeydata; struct winreg_OpenKey r; + NTSTATUS status; mykeydata = talloc(mem_ctx, struct rpc_key); + mykeydata->key.context = parentkeydata->key.context; + mykeydata->pipe = talloc_reference(mykeydata, parentkeydata->pipe); + mykeydata->num_values = -1; + mykeydata->num_subkeys = -1; + *key = (struct registry_key *)mykeydata; + /* Then, open the handle using the hive */ - memset(&r, 0, sizeof(struct winreg_OpenKey)); - r.in.parent_handle = &mykeydata->pol; + ZERO_STRUCT(r); + r.in.parent_handle = &parentkeydata->pol; init_winreg_String(&r.in.keyname, name); r.in.unknown = 0x00000000; r.in.access_mask = 0x02000000; - r.out.handle = &newkeydata->pol; + r.out.handle = &mykeydata->pol; - dcerpc_winreg_OpenKey(mykeydata->pipe, mem_ctx, &r); + status = dcerpc_winreg_OpenKey(mykeydata->pipe, mem_ctx, &r); + if (NT_STATUS_IS_ERR(status)) { + DEBUG(0,("Error executing openkey: %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); + } return r.out.result; } @@ -175,29 +189,29 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key); WERROR error; struct winreg_EnumValue r; - uint32_t len1, zero = 0; + uint32_t in_type = 0; NTSTATUS status; struct winreg_StringBuf name; - uint8_t u8; + uint32_t zero = 0; + + ZERO_STRUCT(r); if (mykeydata->num_values == -1) { error = rpc_query_key(parent); if(!W_ERROR_IS_OK(error)) return error; } - len1 = mykeydata->max_valdatalen; - name.length = 0; - name.size = mykeydata->max_valnamelen * 2; - name.name = ""; + name.size = mykeydata->max_valnamelen * 2+1; + name.name = NULL; r.in.handle = &mykeydata->pol; r.in.enum_index = n; r.in.name = &name; - r.in.type = type; - r.in.value = &u8; + r.in.type = &in_type; + r.in.value = talloc_zero_array(mem_ctx, uint8_t, 0); r.in.length = &zero; - r.in.size = &len1; + r.in.size = &mykeydata->max_valdatalen; r.out.name = &name; status = dcerpc_winreg_EnumValue(mykeydata->pipe, mem_ctx, &r); @@ -229,6 +243,8 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct winreg_StringBuf namebuf, classbuf; NTTIME change_time = 0; + ZERO_STRUCT(r); + namebuf.length = 0; namebuf.size = 1024; namebuf.name = NULL; @@ -241,13 +257,14 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, r.in.name = &namebuf; r.in.keyclass = &classbuf; r.in.last_changed_time = &change_time; + r.out.name = &namebuf; status = dcerpc_winreg_EnumKey(mykeydata->pipe, mem_ctx, &r); if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { *name = talloc_strdup(mem_ctx, r.out.name->name); - *keyclass = talloc_strdup(mem_ctx, r.out.keyclass->name); - *last_changed_time = *r.out.last_changed_time; + if (keyclass != NULL) + *keyclass = talloc_strdup(mem_ctx, r.out.keyclass->name); } return r.out.result; @@ -295,8 +312,23 @@ static WERROR rpc_query_key(const struct registry_key *k) struct winreg_QueryInfoKey r; struct rpc_key *mykeydata = talloc_get_type(k, struct rpc_key); TALLOC_CTX *mem_ctx = talloc_init("query_key"); + uint32_t max_subkeysize; + uint32_t num_values; + uint32_t secdescsize; + NTTIME last_changed_time; + + ZERO_STRUCT(r.out); - r.in.classname = talloc(mem_ctx, struct winreg_String); + r.out.num_subkeys = &mykeydata->num_subkeys; + r.out.max_subkeylen = &mykeydata->num_values; + r.out.max_valnamelen = &mykeydata->max_valnamelen; + r.out.max_valbufsize = &mykeydata->max_valdatalen; + r.out.max_subkeysize = &max_subkeysize; + r.out.num_values = &num_values; + r.out.secdescsize = &secdescsize; + r.out.last_changed_time = &last_changed_time; + + r.out.classname = r.in.classname = talloc_zero(mem_ctx, struct winreg_String); init_winreg_String(r.in.classname, NULL); r.in.handle = &mykeydata->pol; @@ -309,10 +341,6 @@ static WERROR rpc_query_key(const struct registry_key *k) } if (W_ERROR_IS_OK(r.out.result)) { - mykeydata->num_subkeys = *r.out.num_subkeys; - mykeydata->num_values = *r.out.num_values; - mykeydata->max_valnamelen = *r.out.max_valnamelen; - mykeydata->max_valdatalen = *r.out.max_valbufsize; } return r.out.result; @@ -364,6 +392,7 @@ static WERROR rpc_get_info(TALLOC_CTX *mem_ctx, const struct registry_key *key, static struct registry_operations reg_backend_rpc = { .name = "rpc", .open_key = rpc_open_key, + .get_predefined_key = rpc_get_predefined_key, .enum_key = rpc_get_subkey_by_index, .enum_value = rpc_get_value_by_index, .create_key = rpc_add_key, @@ -388,10 +417,10 @@ _PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, /* Default to local smbd if no connection is specified */ if (!location) { - location = talloc_strdup(ctx, "ncalrpc:"); + location = talloc_strdup(rctx, "ncalrpc:"); } - status = dcerpc_pipe_connect(*ctx /* TALLOC_CTX */, + status = dcerpc_pipe_connect(rctx /* TALLOC_CTX */, &p, location, &ndr_table_winreg, credentials, ev, lp_ctx); @@ -400,7 +429,7 @@ _PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, if(NT_STATUS_IS_ERR(status)) { DEBUG(1, ("Unable to open '%s': %s\n", location, nt_errstr(status))); - talloc_free(*ctx); + talloc_free(rctx); *ctx = NULL; return ntstatus_to_werror(status); } diff --git a/source4/lib/registry/tools/common.c b/source4/lib/registry/tools/common.c index 29e96475e6..cec0f8b906 100644 --- a/source4/lib/registry/tools/common.c +++ b/source4/lib/registry/tools/common.c @@ -27,7 +27,7 @@ struct registry_context *reg_common_open_remote(const char *remote, struct loadparm_context *lp_ctx, struct cli_credentials *creds) { - struct registry_context *h; + struct registry_context *h = NULL; WERROR error; error = reg_open_remote(&h, NULL, creds, lp_ctx, remote, NULL); @@ -46,7 +46,7 @@ struct registry_key *reg_common_open_file(const char *path, struct cli_credentials *creds) { struct hive_key *hive_root; - struct registry_context *h; + struct registry_context *h = NULL; WERROR error; error = reg_open_hive(NULL, path, NULL, creds, lp_ctx, &hive_root); @@ -70,7 +70,7 @@ struct registry_key *reg_common_open_file(const char *path, struct registry_context *reg_common_open_local(struct cli_credentials *creds, struct loadparm_context *lp_ctx) { WERROR error; - struct registry_context *h; + struct registry_context *h = NULL; error = reg_open_samba(NULL, &h, lp_ctx, NULL, creds); -- cgit