s3-registry: avoid using registry_value union.
authorGünther Deschner <gd@samba.org>
Tue, 29 Jun 2010 14:13:15 +0000 (16:13 +0200)
committerGünther Deschner <gd@samba.org>
Fri, 2 Jul 2010 08:50:21 +0000 (10:50 +0200)
Just pull and push data as is.

Guenther

12 files changed:
libgpo/gpext/gpext.c
source3/include/registry.h
source3/lib/smbconf/smbconf_reg.c
source3/libgpo/gpext/registry.c
source3/libgpo/gpext/scripts.c
source3/libgpo/gpo_reg.c
source3/registry/reg_api.c
source3/rpc_server/srv_eventlog_nt.c
source3/rpc_server/srv_winreg_nt.c
source3/utils/net_registry.c
source3/utils/net_registry_util.c
source3/utils/net_rpc_registry.c

index 865a725..9a09337 100644 (file)
@@ -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;
        }
index 00c27cf..9e7a1d2 100644 (file)
 #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 */
index 4aa3c09..08d559b 100644 (file)
@@ -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, "<unprintable>");
@@ -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;
                }
index 57840a4..a7e8a5e 100644 (file)
@@ -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:
index f03dff4..fee1461 100644 (file)
@@ -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;
index c4970f6..5b56ecd 100644 (file)
@@ -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, &reg_val.data, val)) {
+               return WERR_NOMEM;
+       }
 
        return reg_setvalue(key, val_name, &reg_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, &reg_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, &reg_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));
index 65118b9..a3fcff8 100644 (file)
@@ -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);
index 241cbab..19d0514 100644 (file)
@@ -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 );
index 1cf0903..5cebcf1 100644 (file)
@@ -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;
index 53cce12..4a6af95 100644 (file)
@@ -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)) {
index a3b84a3..7cbf238 100644 (file)
@@ -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) {
index fb1e14f..9fec13b 100644 (file)
@@ -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: