Just pull and push data as is.
Guenther
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;
}
#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 */
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)) {
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",
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;
}
}
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, "<unprintable>");
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)) {
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;
}
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:
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;
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);
}
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);
}
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;
}
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;
}
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));
}
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)))) {
const struct registry_value *val)
{
WERROR err;
- DATA_BLOB value_data;
int res;
if (!(key->key->access_granted & KEY_SET_VALUE)) {
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);
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;
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)) {
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 );
uint8_t *outbuf;
uint32_t outbuf_size;
- DATA_BLOB val_blob;
bool free_buf = False;
bool free_prs = False;
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;
}
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;
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;
}
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;
{
struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
struct registry_value *val;
- WERROR status;
if ( !key )
return WERR_BADFID;
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);
}
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;
}
}
err = construct_multiple_entry(r->out.values_out,
valuename,
- blob.length,
+ vals[i].data.length,
offset,
vals[i].type,
&r->out.values_out[i]);
return err;
}
- offset += blob.length;
+ offset += vals[i].data.length;
}
*r->out.needed = result.length;
}
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;
(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);
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)) {
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("\"");
}
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) {
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;
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;
}
}
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]);
{
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();
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
status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
&valuename,
&type,
- data,
+ NULL,
&data_size,
&value_length,
NULL);
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);
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: