From 5bf62260505d1e8dfddcb3acef69ef0217841a3f Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Fri, 12 Sep 2008 20:26:13 +0200 Subject: Registry client: Various cleanups and charset conversions This patch contains various changes to the "rpc.c" file to clean it up and introduces the right string charset conversions (UNIX <-> UTF16). --- source4/lib/registry/rpc.c | 191 +++++++++++++++++++++++++++++---------------- 1 file changed, 125 insertions(+), 66 deletions(-) (limited to 'source4/lib/registry/rpc.c') diff --git a/source4/lib/registry/rpc.c b/source4/lib/registry/rpc.c index 18b7607713..3fdba02852 100644 --- a/source4/lib/registry/rpc.c +++ b/source4/lib/registry/rpc.c @@ -19,6 +19,7 @@ #include "includes.h" #include "registry.h" #include "librpc/gen_ndr/ndr_winreg_c.h" +#include "param/param.h" struct rpc_key { struct registry_key key; @@ -43,26 +44,82 @@ static struct registry_operations reg_backend_rpc; * This is the RPC backend for the registry library. */ -static void init_winreg_String(struct winreg_String *name, const char *s) +/* + * Converts a SAMBA (UNIX) string into a WINREG (UTF16) string + */ +static void chars_to_winreg_String(TALLOC_CTX *mem_ctx, struct winreg_String + *winregStr, const char *str) { - name->name = s; + winregStr->name = NULL; + winregStr->name_len = 0; + if (str != NULL) + winregStr->name_len = convert_string_talloc(mem_ctx, + lp_iconv_convenience(global_loadparm), CH_UNIX, + CH_UTF16, (void *) str, strlen(str), + (void **) &winregStr->name); + winregStr->name_size = winregStr->name_len; } +/* + * Converts a WINREG (UTF16) string into a SAMBA (UNIX) string + */ +static void winreg_String_to_chars(TALLOC_CTX *mem_ctx, const char **str, + struct winreg_String *winregStr) +{ + *str = NULL; + if (winregStr->name != NULL) + convert_string_talloc(mem_ctx, + lp_iconv_convenience(global_loadparm), CH_UTF16, + CH_UNIX, (void *) winregStr->name, winregStr->name_len, + (void **) str); +} + +/* + * Converts a SAMBA (UNIX) string into a WINREG (UTF16) string buffer + */ +static void chars_to_winreg_StringBuf(TALLOC_CTX *mem_ctx, struct winreg_StringBuf + *winregStrBuf, const char *str, uint16_t size) +{ + winregStrBuf->name = NULL; + winregStrBuf->length = 0; + if (str != NULL) + winregStrBuf->length = convert_string_talloc(mem_ctx, + lp_iconv_convenience(global_loadparm), CH_UNIX, + CH_UTF16, (void *) str, strlen(str), + (void **) &winregStrBuf->name); + winregStrBuf->size = size; +} + +/* + * Converts a WINREG (UTF16) string buffer into a SAMBA (UNIX) string + */ +static void winreg_StringBuf_to_chars(TALLOC_CTX *mem_ctx, const char **str, + struct winreg_StringBuf *winregStrBuf) +{ + *str = NULL; + if (winregStrBuf->name != NULL) + convert_string_talloc(mem_ctx, + lp_iconv_convenience(global_loadparm), CH_UTF16, + CH_UNIX, (void *) winregStrBuf->name, + winregStrBuf->length, (void **) str); +} #define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *hnd) \ { \ struct winreg_Open ## u r; \ NTSTATUS status; \ - \ +\ + ZERO_STRUCT(r); \ r.in.system_name = NULL; \ r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; \ r.out.handle = hnd;\ - \ +\ 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);\ - }\ +\ + if (!NT_STATUS_IS_OK(status)) { \ + DEBUG(1, ("OpenHive failed - %s\n", nt_errstr(status))); \ + return ntstatus_to_werror(status); \ + } \ \ return r.out.result;\ } @@ -133,9 +190,9 @@ static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) /* Then, open the handle using the hive */ - memset(&r, 0, sizeof(struct winreg_OpenKey)); + ZERO_STRUCT(r); r.in.handle = &(((struct rpc_key_data *)k->hive->root->backend_data)->pol); - init_winreg_String(&r.in.keyname, k->path); + chars_to_winreg_String(mem_ctx, &r.in.keyname, k->path); r.in.unknown = 0x00000000; r.in.access_mask = 0x02000000; r.out.handle = &mykeydata->pol; @@ -166,14 +223,15 @@ static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, /* Then, open the handle using the hive */ ZERO_STRUCT(r); r.in.parent_handle = &parentkeydata->pol; - init_winreg_String(&r.in.keyname, name); + chars_to_winreg_String(mem_ctx, &r.in.keyname, name); r.in.unknown = 0x00000000; r.in.access_mask = 0x02000000; r.out.handle = &mykeydata->pol; 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))); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("OpenKey failed - %s\n", nt_errstr(status))); return ntstatus_to_werror(status); } @@ -188,47 +246,45 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, DATA_BLOB *data) { struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key); - WERROR error; struct winreg_EnumValue r; - uint32_t in_type = 0; - NTSTATUS status; struct winreg_StringBuf name; - uint32_t zero = 0; - - ZERO_STRUCT(r); + uint8_t value; + uint32_t zero = 0, zero2 = 0; + WERROR error; + NTSTATUS status; if (mykeydata->num_values == -1) { error = rpc_query_key(parent); if(!W_ERROR_IS_OK(error)) return error; } - name.length = 0; - name.size = mykeydata->max_valnamelen * 2; - name.name = NULL; + chars_to_winreg_StringBuf(mem_ctx, &name, "", 1024); + ZERO_STRUCT(r); r.in.handle = &mykeydata->pol; r.in.enum_index = n; r.in.name = &name; - r.in.type = &in_type; - r.in.value = talloc_zero_array(mem_ctx, uint8_t, 0); - r.in.length = &zero; + r.in.type = type; + r.in.value = &value; r.in.size = &mykeydata->max_valdatalen; + r.in.length = &zero; r.out.name = &name; r.out.type = type; + r.out.value = &value; + r.out.size = &zero2; + r.out.length = &zero; status = dcerpc_winreg_EnumValue(mykeydata->pipe, mem_ctx, &r); - if(NT_STATUS_IS_ERR(status)) { - DEBUG(0, ("Error in EnumValue: %s\n", nt_errstr(status))); - return WERR_GENERAL_FAILURE; - } - if(NT_STATUS_IS_OK(status) && - W_ERROR_IS_OK(r.out.result) && r.out.length) { - *value_name = talloc_strdup(mem_ctx, r.out.name->name); - *data = data_blob_talloc(mem_ctx, r.out.value, *r.out.length); - return WERR_OK; + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("EnumValue failed - %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); } + winreg_StringBuf_to_chars(mem_ctx, value_name, r.out.name); + *type = *(r.out.type); + *data = data_blob_talloc(mem_ctx, r.out.value, *r.out.length); + return r.out.result; } @@ -241,34 +297,33 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, { struct winreg_EnumKey r; struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key); - NTSTATUS status; struct winreg_StringBuf namebuf, classbuf; NTTIME change_time = 0; + NTSTATUS status; - ZERO_STRUCT(r); - - namebuf.length = 0; - namebuf.size = 1024; - namebuf.name = NULL; - classbuf.length = 0; - classbuf.size = 0; - classbuf.name = NULL; + chars_to_winreg_StringBuf(mem_ctx, &namebuf, "", 1024); + chars_to_winreg_StringBuf(mem_ctx, &classbuf, NULL, 0); + ZERO_STRUCT(r); r.in.handle = &mykeydata->pol; r.in.enum_index = n; r.in.name = &namebuf; r.in.keyclass = &classbuf; r.in.last_changed_time = &change_time; - r.out.name = &namebuf; + r.out.keyclass = &classbuf; + r.out.last_changed_time = &change_time; 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); - if (keyclass != NULL) - *keyclass = talloc_strdup(mem_ctx, r.out.keyclass->name); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("EnumKey failed - %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); } + winreg_StringBuf_to_chars(mem_ctx, name, r.out.name); + winreg_StringBuf_to_chars(mem_ctx, keyclass, r.out.keyclass); + return r.out.result; } @@ -278,19 +333,22 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, struct security_descriptor *sec, struct registry_key **key) { - NTSTATUS status; struct winreg_CreateKey r; struct rpc_key *parentkd = talloc_get_type(parent, struct rpc_key); struct rpc_key *rpck = talloc(mem_ctx, struct rpc_key); + + NTSTATUS status; - init_winreg_String(&r.in.name, name); - init_winreg_String(&r.in.keyclass, NULL); - + ZERO_STRUCT(r); r.in.handle = &parentkd->pol; - r.out.new_handle = &rpck->pol; + chars_to_winreg_String(mem_ctx, &r.in.name, name); + chars_to_winreg_String(mem_ctx, &r.in.keyclass, NULL); r.in.options = 0; r.in.access_mask = SEC_STD_ALL; r.in.secdesc = NULL; + r.in.action_taken = NULL; + r.out.new_handle = &rpck->pol; + r.out.action_taken = NULL; status = dcerpc_winreg_CreateKey(parentkd->pipe, mem_ctx, &r); @@ -300,26 +358,25 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, return ntstatus_to_werror(status); } - if (W_ERROR_IS_OK(r.out.result)) { - rpck->pipe = talloc_reference(rpck, parentkd->pipe); - *key = (struct registry_key *)rpck; - } + rpck->pipe = talloc_reference(rpck, parentkd->pipe); + *key = (struct registry_key *)rpck; return r.out.result; } static WERROR rpc_query_key(const struct registry_key *k) { - NTSTATUS status; 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 secdescsize; NTTIME last_changed_time; + NTSTATUS status; - ZERO_STRUCT(r.out); - + ZERO_STRUCT(r); + r.in.handle = &mykeydata->pol; + chars_to_winreg_String(mem_ctx, r.in.classname, NULL); r.out.num_subkeys = &mykeydata->num_subkeys; r.out.max_subkeylen = &mykeydata->max_subkeynamelen; r.out.max_valnamelen = &mykeydata->max_valnamelen; @@ -330,10 +387,9 @@ static WERROR rpc_query_key(const struct registry_key *k) 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; status = dcerpc_winreg_QueryInfoKey(mykeydata->pipe, mem_ctx, &r); + talloc_free(mem_ctx); if (!NT_STATUS_IS_OK(status)) { @@ -341,9 +397,6 @@ static WERROR rpc_query_key(const struct registry_key *k) return ntstatus_to_werror(status); } - if (W_ERROR_IS_OK(r.out.result)) { - } - return r.out.result; } @@ -354,13 +407,19 @@ static WERROR rpc_del_key(struct registry_key *parent, const char *name) struct winreg_DeleteKey r; TALLOC_CTX *mem_ctx = talloc_init("del_key"); + ZERO_STRUCT(r); r.in.handle = &mykeydata->pol; - init_winreg_String(&r.in.key, name); + chars_to_winreg_String(mem_ctx, &r.in.key, name); status = dcerpc_winreg_DeleteKey(mykeydata->pipe, mem_ctx, &r); talloc_free(mem_ctx); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("DeleteKey failed - %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); + } + return r.out.result; } -- cgit