summaryrefslogtreecommitdiff
path: root/source4/lib/registry/reg_backend_rpc
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/registry/reg_backend_rpc')
-rw-r--r--source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c198
1 files changed, 91 insertions, 107 deletions
diff --git a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c
index 0d8d935a4a..1c887fc411 100644
--- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c
+++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c
@@ -18,7 +18,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "includes.h"
-#include "lib/registry/common/registry.h"
/**
* This is the RPC backend for the registry library.
@@ -37,7 +36,7 @@ static void init_winreg_String(struct winreg_String *name, const char *s)
}
-#define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, REG_KEY *h, struct policy_handle *hnd) \
+#define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *hnd) \
{ \
struct winreg_Open ## u r; \
struct winreg_OpenUnknown unknown; \
@@ -49,7 +48,7 @@ static void init_winreg_String(struct winreg_String *name, const char *s)
r.in.access_required = SEC_RIGHTS_MAXIMUM_ALLOWED; \
r.out.handle = hnd;\
\
- status = dcerpc_winreg_Open ## u(p, h->mem_ctx, &r); \
+ status = dcerpc_winreg_Open ## u(p, mem_ctx, &r); \
if (NT_STATUS_IS_ERR(status)) {\
DEBUG(0,("Error executing open\n"));\
return ntstatus_to_werror(status);\
@@ -74,7 +73,7 @@ struct rpc_key_data {
struct {
const char *name;
- WERROR (*open) (struct dcerpc_pipe *p, REG_KEY *k, struct policy_handle *h);
+ WERROR (*open) (struct dcerpc_pipe *p, TALLOC_CTX *, struct policy_handle *h);
} known_hives[] = {
{ "HKEY_LOCAL_MACHINE", open_HKLM },
{ "HKEY_CURRENT_USER", open_HKCU },
@@ -84,122 +83,124 @@ struct {
{ NULL, NULL }
};
-static WERROR rpc_query_key(REG_KEY *k);
+static WERROR rpc_query_key(struct registry_key *k);
-static WERROR rpc_open_registry(REG_HANDLE *h, const char *location, const char *credentials)
+WERROR rpc_list_hives (TALLOC_CTX *mem_ctx, const char *location, const char *credentials, char ***hives)
+{
+ int i = 0;
+ *hives = talloc_p(mem_ctx, char *);
+ for(i = 0; known_hives[i].name; i++) {
+ *hives = talloc_realloc_p(*hives, char *, i+2);
+ (*hives)[i] = talloc_strdup(mem_ctx, known_hives[i].name);
+ }
+ (*hives)[i] = NULL;
+ return WERR_OK;
+}
+
+static WERROR rpc_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **k)
{
NTSTATUS status;
char *user, *pass;
+ struct rpc_key_data *mykeydata;
+ struct dcerpc_pipe *p;
+ int n;
- if(!credentials || !location) return WERR_INVALID_PARAM;
+ if(!h->credentials || !h->location) return WERR_INVALID_PARAM;
- user = talloc_strdup(h->mem_ctx, credentials);
+ user = talloc_strdup(mem_ctx, h->credentials);
pass = strchr(user, '%');
- *pass = '\0'; pass++;
+ if(pass)
+ {
+ *pass = '\0'; pass++;
+ } else {
+ pass = "";
+ }
- status = dcerpc_pipe_connect((struct dcerpc_pipe **)&h->backend_data, h->location,
+ status = dcerpc_pipe_connect(&p, h->location,
DCERPC_WINREG_UUID,
DCERPC_WINREG_VERSION,
lp_workgroup(),
user, pass);
-
- return ntstatus_to_werror(status);
-}
-static WERROR rpc_get_hive(REG_HANDLE *h, int n, REG_KEY **k)
-{
- struct rpc_key_data *mykeydata;
- WERROR error;
+ h->backend_data = p;
+
+ if(NT_STATUS_IS_ERR(status)) return ntstatus_to_werror(status);
+
+ for(n = 0; known_hives[n].name; n++)
+ {
+ if(!strcmp(known_hives[n].name, h->backend_hivename)) break;
+ }
+
if(!known_hives[n].name) return WERR_NO_MORE_ITEMS;
- *k = reg_key_new_abs(known_hives[n].name, h, NULL);
- (*k)->backend_data = mykeydata = talloc_p((*k)->mem_ctx, struct rpc_key_data);
+
+ *k = talloc_p(mem_ctx, struct registry_key);
+ (*k)->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data);
mykeydata->num_values = -1;
mykeydata->num_subkeys = -1;
- error = known_hives[n].open((struct dcerpc_pipe *)h->backend_data, *k, &mykeydata->pol);
- return error;
+ return known_hives[n].open((struct dcerpc_pipe *)h->backend_data, *k, &(mykeydata->pol));
}
-static WERROR rpc_close_registry(REG_HANDLE *h)
+static WERROR rpc_close_registry(struct registry_hive *h)
{
dcerpc_pipe_close((struct dcerpc_pipe *)h->backend_data);
return WERR_OK;
}
-static WERROR rpc_key_put_rpc_data(REG_KEY *k, struct rpc_key_data **data)
+static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k)
{
struct winreg_OpenKey r;
- WERROR error;
- REG_KEY *hivekey;
struct rpc_key_data *mykeydata;
- if(k->backend_data) {
- *data = k->backend_data;
- return WERR_OK;
- }
-
- k->backend_data = mykeydata = talloc_p(k->mem_ctx, struct rpc_key_data);
- *data = mykeydata;
+ k->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data);
mykeydata->num_values = -1;
mykeydata->num_subkeys = -1;
/* Then, open the handle using the hive */
memset(&r, 0, sizeof(struct winreg_OpenKey));
- error = rpc_get_hive(k->handle, k->hive, &hivekey);
- if(!W_ERROR_IS_OK(error))return error;
- r.in.handle = &(((struct rpc_key_data *)hivekey->backend_data)->pol);
- init_winreg_String(&r.in.keyname, reg_key_get_path(k));
+ r.in.handle = &(((struct rpc_key_data *)k->hive->root->backend_data)->pol);
+ init_winreg_String(&r.in.keyname, k->path);
r.in.unknown = 0x00000000;
r.in.access_mask = 0x02000000;
r.out.handle = &mykeydata->pol;
- dcerpc_winreg_OpenKey((struct dcerpc_pipe *)k->handle->backend_data, k->mem_ctx, &r);
+ dcerpc_winreg_OpenKey((struct dcerpc_pipe *)k->hive->backend_data, mem_ctx, &r);
return r.out.result;
}
-static WERROR rpc_open_key(REG_HANDLE *h, int hive, const char *name, REG_KEY **key)
+static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **key)
{
struct rpc_key_data *mykeydata;
struct winreg_OpenKey r;
- REG_KEY *hivekey;
- WERROR error;
-
- *key = reg_key_new_abs(name, h, NULL);
- (*key)->backend_data = mykeydata = talloc_p((*key)->mem_ctx, struct rpc_key_data);
+ *key = talloc_p(mem_ctx, struct registry_key);
+ (*key)->name = talloc_strdup(mem_ctx, name);
+
+ (*key)->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data);
mykeydata->num_values = -1;
mykeydata->num_subkeys = -1;
/* Then, open the handle using the hive */
memset(&r, 0, sizeof(struct winreg_OpenKey));
- error = rpc_get_hive(h, hive, &hivekey);
- if(!W_ERROR_IS_OK(error))return error;
- r.in.handle = &(((struct rpc_key_data *)hivekey->backend_data)->pol);
+ r.in.handle = &(((struct rpc_key_data *)h->root->backend_data)->pol);
init_winreg_String(&r.in.keyname, name);
r.in.unknown = 0x00000000;
r.in.access_mask = 0x02000000;
r.out.handle = &mykeydata->pol;
- dcerpc_winreg_OpenKey((struct dcerpc_pipe *)(*key)->handle->backend_data, (*key)->mem_ctx, &r);
+ dcerpc_winreg_OpenKey((struct dcerpc_pipe *)(h->backend_data), mem_ctx, &r);
return r.out.result;
}
-static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value)
+static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_value **value)
{
- struct winreg_EnumValue r;
- struct winreg_Uint8buf vb;
- struct winreg_EnumValueName vn;
- NTSTATUS status;
- struct rpc_key_data *mykeydata;
- uint32_t type = 0x0, requested_len = 0, returned_len = 0;
+ struct rpc_key_data *mykeydata = parent->backend_data;
+ uint32_t requested_len = 0;
WERROR error;
- error = rpc_key_put_rpc_data(parent, &mykeydata);
- if(!W_ERROR_IS_OK(error)) return error;
-
if(mykeydata->num_values == -1) {
error = rpc_query_key(parent);
if(!W_ERROR_IS_OK(error)) return error;
@@ -207,6 +208,7 @@ static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value)
requested_len = mykeydata->max_valdatalen;
+#if 0 /* EnumValue is not working yet ... */
r.in.handle = &mykeydata->pol;
r.in.enum_index = n;
r.in.type = r.out.type = &type;
@@ -225,7 +227,7 @@ static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value)
vb.max_len = mykeydata->max_valdatalen;
vb.offset = 0x0;
vb.len = 0x0;
- vb.buffer = talloc_array_p(parent->mem_ctx, uint8, mykeydata->max_valdatalen);
+ vb.buffer = talloc_array_p(mem_ctx, uint8, mykeydata->max_valdatalen);
r.in.value = r.out.value = &vb;
status = dcerpc_winreg_EnumValue((struct dcerpc_pipe *)parent->handle->backend_data, parent->mem_ctx, &r);
@@ -242,23 +244,20 @@ static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value)
exit(1);
return WERR_OK;
}
+#endif
- return r.out.result;
+ return WERR_NOT_SUPPORTED;
}
-static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey)
+static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_key **subkey)
{
struct winreg_EnumKey r;
struct winreg_EnumKeyNameRequest keyname;
struct winreg_String classname;
struct winreg_Time tm;
struct rpc_key_data *mykeydata = parent->backend_data;
- WERROR error;
NTSTATUS status;
- error = rpc_key_put_rpc_data(parent, &mykeydata);
- if(!W_ERROR_IS_OK(error)) return error;
-
r.in.handle = &mykeydata->pol;
keyname.unknown = 0x0000020a;
init_winreg_String(&keyname.key_name, NULL);
@@ -271,40 +270,33 @@ static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey)
r.in.enum_index = n;
r.in.unknown = r.out.unknown = 0x0414;
r.in.key_name_len = r.out.key_name_len = 0;
- status = dcerpc_winreg_EnumKey((struct dcerpc_pipe *)parent->handle->backend_data, parent->mem_ctx, &r);
+ status = dcerpc_winreg_EnumKey((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r);
if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
- *subkey = reg_key_new_rel(r.out.out_name->name, parent, NULL);
+ if(parent->hive->root == parent)
+ return rpc_open_key(mem_ctx, parent->hive, talloc_strdup(mem_ctx, r.out.out_name->name), subkey);
+ return rpc_open_key(mem_ctx, parent->hive, talloc_asprintf(mem_ctx, "%s\\%s", parent->path, r.out.out_name->name), subkey);
}
return r.out.result;
}
-static WERROR rpc_add_key(REG_KEY *parent, const char *name, uint32_t access_mask, SEC_DESC *sec, REG_KEY **key)
+static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, uint32_t access_mask, SEC_DESC *sec, struct registry_key **key)
{
- struct rpc_key_data *mykeydata;
- WERROR error;
-
- error = rpc_key_put_rpc_data(parent, &mykeydata);
- if(!W_ERROR_IS_OK(error)) return error;
-
- /* FIXME */
return WERR_NOT_SUPPORTED;
}
-static WERROR rpc_query_key(REG_KEY *k)
+static WERROR rpc_query_key(struct registry_key *k)
{
NTSTATUS status;
- WERROR error;
struct winreg_QueryInfoKey r;
- struct rpc_key_data *mykeydata;
-
- error = rpc_key_put_rpc_data(k, &mykeydata);
- if(!W_ERROR_IS_OK(error)) return error;
+ struct rpc_key_data *mykeydata = k->backend_data;
+ TALLOC_CTX *mem_ctx = talloc_init("query_key");
init_winreg_String(&r.in.class, NULL);
r.in.handle = &mykeydata->pol;
- status = dcerpc_winreg_QueryInfoKey((struct dcerpc_pipe *)k->handle->backend_data, k->mem_ctx, &r);
+ status = dcerpc_winreg_QueryInfoKey((struct dcerpc_pipe *)(k->hive->backend_data), mem_ctx, &r);
+ talloc_destroy(mem_ctx);
if (!NT_STATUS_IS_OK(status)) {
printf("QueryInfoKey failed - %s\n", nt_errstr(status));
@@ -321,40 +313,37 @@ static WERROR rpc_query_key(REG_KEY *k)
return r.out.result;
}
-static WERROR rpc_del_key(REG_KEY *k)
+static WERROR rpc_del_key(struct registry_key *k)
{
NTSTATUS status;
struct rpc_key_data *mykeydata = k->backend_data;
struct winreg_DeleteKey r;
- REG_KEY *parent;
+ struct registry_key *parent;
WERROR error;
+ TALLOC_CTX *mem_ctx = talloc_init("del_key");
- error = reg_key_get_parent(k, &parent);
- if(!W_ERROR_IS_OK(error)) return error;
+ error = reg_key_get_parent(mem_ctx, k, &parent);
+ if(!W_ERROR_IS_OK(error)) {
+ talloc_destroy(mem_ctx);
+ return error;
+ }
+
+ mykeydata = parent->backend_data;
- error = rpc_key_put_rpc_data(parent, &mykeydata);
- if(!W_ERROR_IS_OK(error)) return error;
-
r.in.handle = &mykeydata->pol;
init_winreg_String(&r.in.key, k->name);
- status = dcerpc_winreg_DeleteKey((struct dcerpc_pipe *)k->handle->backend_data, k->mem_ctx, &r);
+ status = dcerpc_winreg_DeleteKey((struct dcerpc_pipe *)k->hive->backend_data, mem_ctx, &r);
- return r.out.result;
-}
+ talloc_destroy(mem_ctx);
-static void rpc_close_key(REG_KEY *k)
-{
- reg_key_free(k);
+ return r.out.result;
}
-static WERROR rpc_num_values(REG_KEY *key, int *count) {
+static WERROR rpc_num_values(struct registry_key *key, int *count) {
struct rpc_key_data *mykeydata = key->backend_data;
WERROR error;
- error = rpc_key_put_rpc_data(key, &mykeydata);
- if(!W_ERROR_IS_OK(error)) return error;
-
if(mykeydata->num_values == -1) {
error = rpc_query_key(key);
if(!W_ERROR_IS_OK(error)) return error;
@@ -364,13 +353,10 @@ static WERROR rpc_num_values(REG_KEY *key, int *count) {
return WERR_OK;
}
-static WERROR rpc_num_subkeys(REG_KEY *key, int *count) {
+static WERROR rpc_num_subkeys(struct registry_key *key, int *count) {
struct rpc_key_data *mykeydata = key->backend_data;
WERROR error;
- error = rpc_key_put_rpc_data(key, &mykeydata);
- if(!W_ERROR_IS_OK(error)) return error;
-
if(mykeydata->num_subkeys == -1) {
error = rpc_query_key(key);
if(!W_ERROR_IS_OK(error)) return error;
@@ -380,19 +366,17 @@ static WERROR rpc_num_subkeys(REG_KEY *key, int *count) {
return WERR_OK;
}
-static struct registry_ops reg_backend_rpc = {
+static struct registry_operations reg_backend_rpc = {
.name = "rpc",
- .open_registry = rpc_open_registry,
- .close_registry = rpc_close_registry,
- .get_hive = rpc_get_hive,
+ .open_hive = rpc_open_hive,
.open_key = rpc_open_key,
.get_subkey_by_index = rpc_get_subkey_by_index,
.get_value_by_index = rpc_get_value_by_index,
.add_key = rpc_add_key,
.del_key = rpc_del_key,
- .free_key_backend_data = rpc_close_key,
.num_subkeys = rpc_num_subkeys,
.num_values = rpc_num_values,
+ .list_available_hives = rpc_list_hives,
};
NTSTATUS registry_rpc_init(void)