From b381fba0892021f164223bae8b0951014a28735e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 29 Jun 2010 16:13:15 +0200 Subject: s3-registry: avoid using registry_value union. Just pull and push data as is. Guenther --- libgpo/gpext/gpext.c | 13 +++--- source3/include/registry.h | 22 +--------- source3/lib/smbconf/smbconf_reg.c | 68 ++++++++++++++++++++++--------- source3/libgpo/gpext/registry.c | 21 ++++------ source3/libgpo/gpext/scripts.c | 8 ++-- source3/libgpo/gpo_reg.c | 78 +++++++++++++++++++++++------------- source3/registry/reg_api.c | 23 ++++------- source3/rpc_server/srv_eventlog_nt.c | 13 ++++-- source3/rpc_server/srv_winreg_nt.c | 50 ++++++++--------------- source3/utils/net_registry.c | 40 ++++++++++++++---- source3/utils/net_registry_util.c | 30 ++++++++++---- source3/utils/net_rpc_registry.c | 53 +++++++++++------------- 12 files changed, 233 insertions(+), 186 deletions(-) diff --git a/libgpo/gpext/gpext.c b/libgpo/gpext/gpext.c index 865a725c7b..9a09337871 100644 --- a/libgpo/gpext/gpext.c +++ b/libgpo/gpext/gpext.c @@ -281,13 +281,16 @@ static NTSTATUS gp_ext_info_add_reg(TALLOC_CTX *mem_ctx, switch (type) { case REG_SZ: case REG_EXPAND_SZ: - data->v.sz.str = talloc_strdup(mem_ctx, data_s); - NT_STATUS_HAVE_NO_MEMORY(data->v.sz.str); - data->v.sz.len = strlen(data_s); + if (!push_reg_sz(mem_ctx, &data->data, data_s)) { + return NT_STATUS_NO_MEMORY; + } break; - case REG_DWORD: - data->v.dword = atoi(data_s); + case REG_DWORD: { + uint32_t v = atoi(data_s); + data->data = data_blob_talloc(mem_ctx, NULL, 4); + SIVAL(data->data.data, 0, v); break; + } default: return NT_STATUS_NOT_SUPPORTED; } diff --git a/source3/include/registry.h b/source3/include/registry.h index 00c27cf021..9e7a1d2d0f 100644 --- a/source3/include/registry.h +++ b/source3/include/registry.h @@ -23,29 +23,9 @@ #ifndef _REGISTRY_H #define _REGISTRY_H -/* - * A REG_SZ string is not necessarily NULL terminated. When retrieving it from - * the net, we guarantee this however. A server might want to push it without - * the terminator though. - */ - -struct registry_string { - size_t len; - char *str; -}; - struct registry_value { enum winreg_Type type; - union { - uint32 dword; - uint64 qword; - struct registry_string sz; - struct { - uint32 num_strings; - char **strings; - } multi_sz; - DATA_BLOB binary; - } v; + DATA_BLOB data; }; /* forward declarations. definitions in reg_objects.c */ diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 4aa3c09def..08d559b3c7 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -208,8 +208,10 @@ static WERROR smbconf_reg_set_value(struct registry_key *key, ZERO_STRUCT(val); val.type = REG_SZ; - val.v.sz.str = CONST_DISCARD(char *, canon_valstr); - val.v.sz.len = strlen(canon_valstr) + 1; + if (!push_reg_sz(talloc_tos(), &val.data, canon_valstr)) { + werr = WERR_NOMEM; + goto done; + } werr = reg_setvalue(key, canon_valname, &val); if (!W_ERROR_IS_OK(werr)) { @@ -231,31 +233,40 @@ static WERROR smbconf_reg_set_multi_sz_value(struct registry_key *key, struct registry_value *value; uint32_t count; TALLOC_CTX *tmp_ctx = talloc_stackframe(); + const char **array; if (strings == NULL) { werr = WERR_INVALID_PARAM; goto done; } - value = TALLOC_ZERO_P(tmp_ctx, struct registry_value); + array = talloc_zero_array(tmp_ctx, const char *, num_strings + 1); + if (array == NULL) { + werr = WERR_NOMEM; + goto done; + } - value->type = REG_MULTI_SZ; - value->v.multi_sz.num_strings = num_strings; - value->v.multi_sz.strings = TALLOC_ARRAY(tmp_ctx, char *, num_strings); - if (value->v.multi_sz.strings == NULL) { + value = TALLOC_ZERO_P(tmp_ctx, struct registry_value); + if (value == NULL) { werr = WERR_NOMEM; goto done; } + + value->type = REG_MULTI_SZ; + for (count = 0; count < num_strings; count++) { - value->v.multi_sz.strings[count] = - talloc_strdup(value->v.multi_sz.strings, - strings[count]); - if (value->v.multi_sz.strings[count] == NULL) { + array[count] = talloc_strdup(value, strings[count]); + if (array[count] == NULL) { werr = WERR_NOMEM; goto done; } } + if (!push_reg_multi_sz(value, &value->data, array)) { + werr = WERR_NOMEM; + goto done; + } + werr = reg_setvalue(key, valname, value); if (!W_ERROR_IS_OK(werr)) { DEBUG(5, ("Error adding value '%s' to key '%s': %s\n", @@ -286,18 +297,30 @@ static char *smbconf_format_registry_value(TALLOC_CTX *mem_ctx, switch (value->type) { case REG_DWORD: - result = talloc_asprintf(mem_ctx, "%d", value->v.dword); + if (value->data.length >= 4) { + uint32_t v = IVAL(value->data.data, 0); + result = talloc_asprintf(mem_ctx, "%d", v); + } break; case REG_SZ: - case REG_EXPAND_SZ: - result = talloc_asprintf(mem_ctx, "%s", value->v.sz.str); + case REG_EXPAND_SZ: { + const char *s; + if (!pull_reg_sz(mem_ctx, &value->data, &s)) { + break; + } + result = talloc_strdup(mem_ctx, s); break; + } case REG_MULTI_SZ: { uint32 j; - for (j = 0; j < value->v.multi_sz.num_strings; j++) { + const char **a = NULL; + if (!pull_reg_multi_sz(mem_ctx, &value->data, &a)) { + break; + } + for (j = 0; a[j] != NULL; j++) { result = talloc_asprintf(mem_ctx, "%s\"%s\" ", result ? result : "" , - value->v.multi_sz.strings[j]); + a[j]); if (result == NULL) { break; } @@ -306,7 +329,7 @@ static char *smbconf_format_registry_value(TALLOC_CTX *mem_ctx, } case REG_BINARY: result = talloc_asprintf(mem_ctx, "binary (%d bytes)", - (int)value->v.binary.length); + (int)value->data.length); break; default: result = talloc_asprintf(mem_ctx, ""); @@ -324,6 +347,7 @@ static WERROR smbconf_reg_get_includes_internal(TALLOC_CTX *mem_ctx, uint32_t count; struct registry_value *value = NULL; char **tmp_includes = NULL; + const char **array = NULL; TALLOC_CTX *tmp_ctx = talloc_stackframe(); if (!smbconf_value_exists(key, INCLUDES_VALNAME)) { @@ -344,12 +368,16 @@ static WERROR smbconf_reg_get_includes_internal(TALLOC_CTX *mem_ctx, goto done; } - for (count = 0; count < value->v.multi_sz.num_strings; count++) - { + if (!pull_reg_multi_sz(tmp_ctx, &value->data, &array)) { + werr = WERR_NOMEM; + goto done; + } + + for (count = 0; array[count] != NULL; count++) { werr = smbconf_add_string_to_array(tmp_ctx, &tmp_includes, count, - value->v.multi_sz.strings[count]); + array[count]); if (!W_ERROR_IS_OK(werr)) { goto done; } diff --git a/source3/libgpo/gpext/registry.c b/source3/libgpo/gpext/registry.c index 57840a4c06..a7e8a5e948 100644 --- a/source3/libgpo/gpext/registry.c +++ b/source3/libgpo/gpext/registry.c @@ -293,23 +293,18 @@ static bool gp_reg_entry_from_file_entry(TALLOC_CTX *mem_ctx, switch (data->type) { case REG_DWORD: - data->v.dword = atoi((char *)file_entry->data); + if (file_entry->size < 4) { + return false; + } + data->data = data_blob_talloc(mem_ctx, NULL, 4); + SIVAL(data->data.data, 0, atoi((char *)file_entry->data)); break; case REG_BINARY: - data->v.binary = data_blob_talloc(mem_ctx, - file_entry->data, - file_entry->size); + case REG_SZ: + data->data.length = file_entry->size; + data->data.data = file_entry->data; break; case REG_NONE: - break; - case REG_SZ: - if (!pull_ucs2_talloc(mem_ctx, &data->v.sz.str, - (const smb_ucs2_t *) - file_entry->data, - &data->v.sz.len)) { - data->v.sz.len = -1; - } - break; case REG_DWORD_BIG_ENDIAN: case REG_EXPAND_SZ: diff --git a/source3/libgpo/gpext/scripts.c b/source3/libgpo/gpext/scripts.c index f03dff4e34..fee1461f01 100644 --- a/source3/libgpo/gpext/scripts.c +++ b/source3/libgpo/gpext/scripts.c @@ -96,11 +96,13 @@ static NTSTATUS generate_gp_registry_entry(TALLOC_CTX *mem_ctx, data->type = data_type; switch (data->type) { case REG_QWORD: - data->v.qword = *(uint64_t *)data_p; + data->data = data_blob_talloc(mem_ctx, NULL, 8); + SBVAL(data->data.data, 0, *(uint64_t *)data_p); break; case REG_SZ: - data->v.sz.str = talloc_strdup(mem_ctx, (char *)data_p); - data->v.sz.len = strlen(data->v.sz.str); + if (!push_reg_sz(mem_ctx, &data->data, (char *)data_p)) { + return NT_STATUS_NO_MEMORY; + } break; default: return NT_STATUS_NOT_SUPPORTED; diff --git a/source3/libgpo/gpo_reg.c b/source3/libgpo/gpo_reg.c index c4970f6018..5b56ecd365 100644 --- a/source3/libgpo/gpo_reg.c +++ b/source3/libgpo/gpo_reg.c @@ -165,15 +165,11 @@ WERROR gp_store_reg_val_sz(TALLOC_CTX *mem_ctx, const char *val) { struct registry_value reg_val; - ZERO_STRUCT(reg_val); - - /* FIXME: hack */ - val = val ? val : " "; reg_val.type = REG_SZ; - reg_val.v.sz.len = strlen(val); - reg_val.v.sz.str = talloc_strdup(mem_ctx, val); - W_ERROR_HAVE_NO_MEMORY(reg_val.v.sz.str); + if (!push_reg_sz(mem_ctx, ®_val.data, val)) { + return WERR_NOMEM; + } return reg_setvalue(key, val_name, ®_val); } @@ -187,10 +183,10 @@ static WERROR gp_store_reg_val_dword(TALLOC_CTX *mem_ctx, uint32_t val) { struct registry_value reg_val; - ZERO_STRUCT(reg_val); reg_val.type = REG_DWORD; - reg_val.v.dword = val; + reg_val.data = data_blob_talloc(mem_ctx, NULL, 4); + SIVAL(reg_val.data.data, 0, val); return reg_setvalue(key, val_name, ®_val); } @@ -213,8 +209,9 @@ WERROR gp_read_reg_val_sz(TALLOC_CTX *mem_ctx, return WERR_INVALID_DATATYPE; } - *val = talloc_strdup(mem_ctx, reg_val->v.sz.str); - W_ERROR_HAVE_NO_MEMORY(*val); + if (!pull_reg_sz(mem_ctx, ®_val->data, val)) { + return WERR_NOMEM; + } return WERR_OK; } @@ -237,7 +234,10 @@ static WERROR gp_read_reg_val_dword(TALLOC_CTX *mem_ctx, return WERR_INVALID_DATATYPE; } - *val = reg_val->v.dword; + if (reg_val->data.length < 4) { + return WERR_INSUFFICIENT_BUFFER; + } + *val = IVAL(reg_val->data.data, 0); return WERR_OK; } @@ -797,34 +797,56 @@ void dump_reg_val(int lvl, const char *direction, direction, key, subkey, type_str)); switch (val->type) { - case REG_DWORD: + case REG_DWORD: { + uint32_t v; + if (val->data.length < 4) { + break; + } + v = IVAL(val->data.data, 0); DEBUG(lvl,("%d (0x%08x)\n", - (int)val->v.dword, val->v.dword)); + (int)v, v)); break; - case REG_QWORD: + } + case REG_QWORD: { + uint64_t v; + if (val->data.length < 8) { + break; + } + v = BVAL(val->data.data, 0); DEBUG(lvl,("%d (0x%016llx)\n", - (int)val->v.qword, - (unsigned long long)val->v.qword)); + (int)v, + (unsigned long long)v)); break; - case REG_SZ: + } + case REG_SZ: { + const char *s; + if (!pull_reg_sz(talloc_tos(), &val->data, &s)) { + break; + } DEBUG(lvl,("%s (length: %d)\n", - val->v.sz.str, - (int)val->v.sz.len)); + s, (int)strlen_m(s))); break; - case REG_MULTI_SZ: - DEBUG(lvl,("(num_strings: %d)\n", - val->v.multi_sz.num_strings)); - for (i=0; i < val->v.multi_sz.num_strings; i++) { - DEBUGADD(lvl,("\t%s\n", - val->v.multi_sz.strings[i])); + } + case REG_MULTI_SZ: { + const char **a; + if (!pull_reg_multi_sz(talloc_tos(), &val->data, &a)) { + break; + } + for (i=0; a[i] != NULL; i++) { + ;; + } + DEBUG(lvl,("(num_strings: %d)\n", i)); + for (i=0; a[i] != NULL; i++) { + DEBUGADD(lvl,("\t%s\n", a[i])); } break; + } case REG_NONE: DEBUG(lvl,("\n")); break; case REG_BINARY: - dump_data(lvl, val->v.binary.data, - val->v.binary.length); + dump_data(lvl, val->data.data, + val->data.length); break; default: DEBUG(lvl,("unsupported type: %d\n", val->type)); diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 65118b9f4c..a3fcff859a 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -357,15 +357,15 @@ WERROR reg_enumvalue(TALLOC_CTX *mem_ctx, struct registry_key *key, } blob = regval_ctr_specific_value(key->values, idx); - err = registry_pull_value(mem_ctx, &val, - regval_type(blob), - regval_data_p(blob), - regval_size(blob), - regval_size(blob)); - if (!W_ERROR_IS_OK(err)) { - return err; + + val = talloc_zero(mem_ctx, struct registry_value); + if (val == NULL) { + return WERR_NOMEM; } + val->type = regval_type(blob); + val->data = data_blob_talloc(mem_ctx, regval_data_p(blob), regval_size(blob)); + if (pname && !(*pname = talloc_strdup( mem_ctx, regval_name(blob)))) { @@ -661,7 +661,6 @@ WERROR reg_setvalue(struct registry_key *key, const char *name, const struct registry_value *val) { WERROR err; - DATA_BLOB value_data; int res; if (!(key->key->access_granted & KEY_SET_VALUE)) { @@ -672,14 +671,8 @@ WERROR reg_setvalue(struct registry_key *key, const char *name, return err; } - err = registry_push_value(key, val, &value_data); - if (!W_ERROR_IS_OK(err)) { - return err; - } - res = regval_ctr_addvalue(key->values, name, val->type, - value_data.data, value_data.length); - TALLOC_FREE(value_data.data); + val->data.data, val->data.length); if (res == 0) { TALLOC_FREE(key->values); diff --git a/source3/rpc_server/srv_eventlog_nt.c b/source3/rpc_server/srv_eventlog_nt.c index 241cbab4f6..19d0514717 100644 --- a/source3/rpc_server/srv_eventlog_nt.c +++ b/source3/rpc_server/srv_eventlog_nt.c @@ -304,8 +304,8 @@ static int elog_size( EVENTLOG_INFO *info ) static bool sync_eventlog_params( EVENTLOG_INFO *info ) { char *path = NULL; - uint32 uiMaxSize; - uint32 uiRetention; + uint32_t uiMaxSize = 0; + uint32_t uiRetention = 0; struct registry_key *key; struct registry_value *value; WERROR wresult; @@ -350,7 +350,10 @@ static bool sync_eventlog_params( EVENTLOG_INFO *info ) win_errstr(wresult))); goto done; } - uiRetention = value->v.dword; + + if (value->data.length >= 4) { + uiRetention = IVAL(value->data.data, 0); + } wresult = reg_queryvalue(key, key, "MaxSize", &value); if (!W_ERROR_IS_OK(wresult)) { @@ -358,7 +361,9 @@ static bool sync_eventlog_params( EVENTLOG_INFO *info ) win_errstr(wresult))); goto done; } - uiMaxSize = value->v.dword; + if (value->data.length >= 4) { + uiMaxSize = IVAL(value->data.data, 0); + } tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_MAXSIZE, uiMaxSize ); tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_RETENTION, uiRetention ); diff --git a/source3/rpc_server/srv_winreg_nt.c b/source3/rpc_server/srv_winreg_nt.c index 1cf0903b51..5cebcf1e15 100644 --- a/source3/rpc_server/srv_winreg_nt.c +++ b/source3/rpc_server/srv_winreg_nt.c @@ -226,7 +226,6 @@ WERROR _winreg_QueryValue(pipes_struct *p, struct winreg_QueryValue *r) uint8_t *outbuf; uint32_t outbuf_size; - DATA_BLOB val_blob; bool free_buf = False; bool free_prs = False; @@ -305,13 +304,8 @@ WERROR _winreg_QueryValue(pipes_struct *p, struct winreg_QueryValue *r) return status; } - status = registry_push_value(p->mem_ctx, val, &val_blob); - if (!W_ERROR_IS_OK(status)) { - return status; - } - - outbuf = val_blob.data; - outbuf_size = val_blob.length; + outbuf = val->data.data; + outbuf_size = val->data.length; *r->out.type = val->type; } @@ -422,7 +416,6 @@ WERROR _winreg_EnumValue(pipes_struct *p, struct winreg_EnumValue *r) struct registry_key *key = find_regkey_by_hnd( p, r->in.handle ); char *valname; struct registry_value *val; - DATA_BLOB value_blob; if ( !key ) return WERR_BADFID; @@ -438,11 +431,6 @@ WERROR _winreg_EnumValue(pipes_struct *p, struct winreg_EnumValue *r) return err; } - err = registry_push_value(p->mem_ctx, val, &value_blob); - if (!W_ERROR_IS_OK(err)) { - return err; - } - if (r->out.name != NULL) { r->out.name->name = valname; } @@ -456,18 +444,18 @@ WERROR _winreg_EnumValue(pipes_struct *p, struct winreg_EnumValue *r) return WERR_INVALID_PARAM; } - if (value_blob.length > *r->out.size) { + if (val->data.length > *r->out.size) { return WERR_MORE_DATA; } - memcpy( r->out.value, value_blob.data, value_blob.length ); + memcpy( r->out.value, val->data.data, val->data.length ); } if (r->out.length != NULL) { - *r->out.length = value_blob.length; + *r->out.length = val->data.length; } if (r->out.size != NULL) { - *r->out.size = value_blob.length; + *r->out.size = val->data.length; } return WERR_OK; @@ -788,7 +776,6 @@ WERROR _winreg_SetValue(pipes_struct *p, struct winreg_SetValue *r) { struct registry_key *key = find_regkey_by_hnd(p, r->in.handle); struct registry_value *val; - WERROR status; if ( !key ) return WERR_BADFID; @@ -796,12 +783,14 @@ WERROR _winreg_SetValue(pipes_struct *p, struct winreg_SetValue *r) DEBUG(8,("_winreg_SetValue: Setting value for [%s:%s]\n", key->key->name, r->in.name.name)); - status = registry_pull_value(p->mem_ctx, &val, r->in.type, r->in.data, - r->in.size, r->in.size); - if (!W_ERROR_IS_OK(status)) { - return status; + val = talloc_zero(p->mem_ctx, struct registry_value); + if (val == NULL) { + return WERR_NOMEM; } + val->type = r->in.type; + val->data = data_blob_talloc(p->mem_ctx, r->in.data, r->in.size); + return reg_setvalue(key, r->in.name.name, val); } @@ -1060,16 +1049,11 @@ WERROR _winreg_QueryMultipleValues2(pipes_struct *p, for (i=0; i < r->in.num_values; i++) { const char *valuename = NULL; - DATA_BLOB blob = data_blob_null; - - if (vals[i].type != REG_NONE) { - err = registry_push_value(p->mem_ctx, &vals[i], &blob); - if (!W_ERROR_IS_OK(err)) { - return err; - } + if (vals[i].data.length > 0) { if (!data_blob_append(p->mem_ctx, &result, - blob.data, blob.length)) { + vals[i].data.data, + vals[i].data.length)) { return WERR_NOMEM; } } @@ -1081,7 +1065,7 @@ WERROR _winreg_QueryMultipleValues2(pipes_struct *p, err = construct_multiple_entry(r->out.values_out, valuename, - blob.length, + vals[i].data.length, offset, vals[i].type, &r->out.values_out[i]); @@ -1089,7 +1073,7 @@ WERROR _winreg_QueryMultipleValues2(pipes_struct *p, return err; } - offset += blob.length; + offset += vals[i].data.length; } *r->out.needed = result.length; diff --git a/source3/utils/net_registry.c b/source3/utils/net_registry.c index 53cce12360..4a6af959dc 100644 --- a/source3/utils/net_registry.c +++ b/source3/utils/net_registry.c @@ -352,16 +352,33 @@ static int net_registry_setvalue(struct net_context *c, int argc, } if (strequal(argv[2], "dword")) { + uint32_t v = strtoul(argv[3], NULL, 10); value.type = REG_DWORD; - value.v.dword = strtoul(argv[3], NULL, 10); + value.data = data_blob_talloc(ctx, NULL, 4); + SIVAL(value.data.data, 0, v); } else if (strequal(argv[2], "sz")) { value.type = REG_SZ; - value.v.sz.len = strlen(argv[3])+1; - value.v.sz.str = CONST_DISCARD(char *, argv[3]); + if (!push_reg_sz(ctx, &value.data, argv[3])) { + goto done; + } } else if (strequal(argv[2], "multi_sz")) { + const char **array; + int count = argc - 3; + int i; value.type = REG_MULTI_SZ; - value.v.multi_sz.num_strings = argc - 3; - value.v.multi_sz.strings = (char **)(argv + 3); + array = talloc_zero_array(ctx, const char *, count + 1); + if (array == NULL) { + goto done; + } + for (i=0; i < count; i++) { + array[i] = talloc_strdup(array, argv[count+i]); + if (array[i] == NULL) { + goto done; + } + } + if (!push_reg_multi_sz(ctx, &value.data, array)) { + goto done; + } } else { d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]); goto done; @@ -401,6 +418,7 @@ static void net_registry_increment_fn(void *private_data) (struct net_registry_increment_state *)private_data; struct registry_value *value; struct registry_key *key = NULL; + uint32_t v; state->werr = open_key(talloc_tos(), state->keyname, REG_KEY_READ|REG_KEY_WRITE, &key); @@ -423,8 +441,16 @@ static void net_registry_increment_fn(void *private_data) goto done; } - value->v.dword += state->increment; - state->newvalue = value->v.dword; + if (value->data.length < 4) { + d_fprintf(stderr, _("value too short for regular DWORD\n")); + goto done; + } + + v = IVAL(value->data.data, 0); + v += state->increment; + state->newvalue = v; + + SIVAL(value->data.data, 0, v); state->werr = reg_setvalue(key, state->valuename, value); if (!W_ERROR_IS_OK(state->werr)) { diff --git a/source3/utils/net_registry_util.c b/source3/utils/net_registry_util.c index a3b84a344f..7cbf238aeb 100644 --- a/source3/utils/net_registry_util.c +++ b/source3/utils/net_registry_util.c @@ -41,30 +41,46 @@ void print_registry_value(const struct registry_value *valvalue, bool raw) str_regtype(valvalue->type)); } switch(valvalue->type) { - case REG_DWORD: + case REG_DWORD: { + uint32_t v = 0; + if (valvalue->data.length >= 4) { + v = IVAL(valvalue->data.data, 0); + } if (!raw) { d_printf(_("Value = ")); } - d_printf("%d\n", valvalue->v.dword); + d_printf("%d\n", v); break; + } case REG_SZ: - case REG_EXPAND_SZ: + case REG_EXPAND_SZ: { + const char *s; + + if (!pull_reg_sz(talloc_tos(), &valvalue->data, &s)) { + break; + } if (!raw) { d_printf(_("Value = \"")); } - d_printf("%s", valvalue->v.sz.str); + d_printf("%s", s); if (!raw) { d_printf("\""); } d_printf("\n"); break; + } case REG_MULTI_SZ: { uint32 j; - for (j = 0; j < valvalue->v.multi_sz.num_strings; j++) { + const char **a; + + if (!pull_reg_multi_sz(talloc_tos(), &valvalue->data, &a)) { + break; + } + for (j = 0; a[j] != NULL; j++) { if (!raw) { d_printf(_("Value[%3.3d] = \""), j); } - d_printf("%s", valvalue->v.multi_sz.strings[j]); + d_printf("%s", a[j]); if (!raw) { d_printf("\""); } @@ -76,7 +92,7 @@ void print_registry_value(const struct registry_value *valvalue, bool raw) if (!raw) { d_printf(_("Value = ")); } - d_printf(_("%d bytes\n"), (int)valvalue->v.binary.length); + d_printf(_("%d bytes\n"), (int)valvalue->data.length); break; default: if (!raw) { diff --git a/source3/utils/net_rpc_registry.c b/source3/utils/net_rpc_registry.c index fb1e14f0d5..9fec13b371 100644 --- a/source3/utils/net_rpc_registry.c +++ b/source3/utils/net_rpc_registry.c @@ -352,12 +352,14 @@ static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx, goto error; } - err = registry_pull_value(values, &values[i], type, data, - data_size, value_length); - if (!W_ERROR_IS_OK(err)) { - status = werror_to_ntstatus(err); + values[i] = talloc_zero(values, struct registry_value); + if (values[i] == NULL) { + status = NT_STATUS_NO_MEMORY; goto error; } + + values[i]->type = type; + values[i]->data = data_blob_talloc(values[i], data, data_size); } *pnum_values = num_values; @@ -394,22 +396,14 @@ static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx, const struct registry_value *value) { struct winreg_String name_string; - DATA_BLOB blob; NTSTATUS result; - WERROR err; - - err = registry_push_value(mem_ctx, value, &blob); - if (!W_ERROR_IS_OK(err)) { - return werror_to_ntstatus(err); - } ZERO_STRUCT(name_string); name_string.name = name; - result = rpccli_winreg_SetValue(pipe_hnd, blob.data, key_hnd, + result = rpccli_winreg_SetValue(pipe_hnd, mem_ctx, key_hnd, name_string, value->type, - blob.data, blob.length, NULL); - TALLOC_FREE(blob.data); + value->data.data, value->data.length, NULL); return result; } @@ -441,13 +435,17 @@ static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c, } if (strequal(argv[2], "dword")) { + uint32_t v = strtoul(argv[3], NULL, 10); value.type = REG_DWORD; - value.v.dword = strtoul(argv[3], NULL, 10); + value.data = data_blob_talloc(mem_ctx, NULL, 4); + SIVAL(value.data.data, 0, v); } else if (strequal(argv[2], "sz")) { value.type = REG_SZ; - value.v.sz.len = strlen(argv[3])+1; - value.v.sz.str = CONST_DISCARD(char *, argv[3]); + if (!push_reg_sz(mem_ctx, &value.data, argv[3])) { + status = NT_STATUS_NO_MEMORY; + goto error; + } } else { d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]); @@ -551,11 +549,9 @@ static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c, { 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(); @@ -573,6 +569,11 @@ static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c, valuename.name = argv[1]; + value = talloc_zero(tmp_ctx, struct registry_value); + if (value == NULL) { + return NT_STATUS_NO_MEMORY; + } + /* * call QueryValue once with data == NULL to get the * needed memory size to be allocated, then allocate @@ -581,7 +582,7 @@ static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c, status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd, &valuename, &type, - data, + NULL, &data_size, &value_length, NULL); @@ -592,13 +593,12 @@ static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c, goto done; } - data = (uint8 *)TALLOC(tmp_ctx, data_size); - value_length = 0; + value->data = data_blob_talloc(tmp_ctx, NULL, data_size); status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd, &valuename, &type, - data, + value->data.data, &data_size, &value_length, NULL); @@ -609,13 +609,6 @@ static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c, 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, raw); done: -- cgit