mirror of
https://github.com/samba-team/samba.git
synced 2025-08-03 04:22:09 +03:00
r26688: Fix listing remote predefined keys and subkeys. This fixes bug 3431.
This commit is contained in:
committed by
Stefan Metzmacher
parent
f08192750e
commit
846876ad32
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
r.in.classname = talloc(mem_ctx, struct winreg_String);
|
||||
ZERO_STRUCT(r.out);
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user