diff options
-rw-r--r-- | source4/lib/registry/dir.c | 32 | ||||
-rw-r--r-- | source4/lib/registry/hive.c | 9 | ||||
-rw-r--r-- | source4/lib/registry/hive.h | 10 | ||||
-rw-r--r-- | source4/lib/registry/interface.c | 9 | ||||
-rw-r--r-- | source4/lib/registry/ldb.c | 52 | ||||
-rw-r--r-- | source4/lib/registry/local.c | 8 | ||||
-rw-r--r-- | source4/lib/registry/patchfile.c | 11 | ||||
-rw-r--r-- | source4/lib/registry/regf.c | 11 | ||||
-rw-r--r-- | source4/lib/registry/registry.h | 10 | ||||
-rw-r--r-- | source4/lib/registry/rpc.c | 23 | ||||
-rw-r--r-- | source4/lib/registry/tests/hive.c | 4 | ||||
-rw-r--r-- | source4/lib/registry/tests/registry.c | 4 | ||||
-rw-r--r-- | source4/lib/registry/tools/regshell.c | 32 | ||||
-rw-r--r-- | source4/rpc_server/winreg/rpc_winreg.c | 6 |
14 files changed, 175 insertions, 46 deletions
diff --git a/source4/lib/registry/dir.c b/source4/lib/registry/dir.c index 2f00d2fea0..a13e3753b7 100644 --- a/source4/lib/registry/dir.c +++ b/source4/lib/registry/dir.c @@ -184,7 +184,10 @@ static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key, const char **classname, uint32_t *num_subkeys, uint32_t *num_values, - NTTIME *lastmod) + NTTIME *lastmod, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize) { DIR *d; const struct dir_key *dk = talloc_get_type(key, struct dir_key); @@ -206,6 +209,15 @@ static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key, if (num_values != NULL) *num_values = 0; + if (max_subkeynamelen != NULL) + *max_subkeynamelen = 0; + + if (max_valnamelen != NULL) + *max_valnamelen = 0; + + if (max_valbufsize != NULL) + *max_valbufsize = 0; + while((e = readdir(d))) { if(!ISDOT(e->d_name) && !ISDOTDOT(e->d_name)) { char *path = talloc_asprintf(ctx, "%s/%s", @@ -217,11 +229,21 @@ static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key, continue; } - if (S_ISDIR(st.st_mode) && num_subkeys != NULL) - (*num_subkeys)++; + if (S_ISDIR(st.st_mode)) { + if (num_subkeys != NULL) + (*num_subkeys)++; + if (max_subkeynamelen != NULL) + *max_subkeynamelen = MAX(*max_subkeynamelen, strlen(e->d_name)); + } - if (!S_ISDIR(st.st_mode) && num_values != NULL) - (*num_values)++; + if (!S_ISDIR(st.st_mode)) { + if (num_values != NULL) + (*num_values)++; + if (max_valnamelen != NULL) + *max_valnamelen = MAX(*max_valnamelen, strlen(e->d_name)); + if (max_valbufsize != NULL) + *max_valbufsize = MAX(*max_valbufsize, st.st_size); + } talloc_free(path); } diff --git a/source4/lib/registry/hive.c b/source4/lib/registry/hive.c index d7d12076f3..bbe510772c 100644 --- a/source4/lib/registry/hive.c +++ b/source4/lib/registry/hive.c @@ -66,10 +66,15 @@ _PUBLIC_ WERROR hive_key_get_info(TALLOC_CTX *mem_ctx, const struct hive_key *key, const char **classname, uint32_t *num_subkeys, uint32_t *num_values, - NTTIME *last_change_time) + NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize) { return key->ops->get_key_info(mem_ctx, key, classname, num_subkeys, - num_values, last_change_time); + num_values, last_change_time, + max_subkeynamelen, + max_valnamelen, max_valbufsize); } _PUBLIC_ WERROR hive_key_add_name(TALLOC_CTX *ctx, diff --git a/source4/lib/registry/hive.h b/source4/lib/registry/hive.h index 1e05f6b013..6d9a69c7c5 100644 --- a/source4/lib/registry/hive.h +++ b/source4/lib/registry/hive.h @@ -135,7 +135,10 @@ struct hive_operations { const char **classname, uint32_t *num_subkeys, uint32_t *num_values, - NTTIME *last_change_time); + NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize); }; struct cli_credentials; @@ -148,8 +151,9 @@ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, struct hive_key **root); WERROR hive_key_get_info(TALLOC_CTX *mem_ctx, const struct hive_key *key, const char **classname, uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_change_time); + uint32_t *num_values, NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, uint32_t *max_valbufsize); WERROR hive_key_add_name(TALLOC_CTX *ctx, const struct hive_key *parent_key, const char *name, const char *classname, struct security_descriptor *desc, diff --git a/source4/lib/registry/interface.c b/source4/lib/registry/interface.c index b914fbab30..a18fd2c28c 100644 --- a/source4/lib/registry/interface.c +++ b/source4/lib/registry/interface.c @@ -128,7 +128,10 @@ _PUBLIC_ WERROR reg_key_get_info(TALLOC_CTX *mem_ctx, const char **classname, uint32_t *num_subkeys, uint32_t *num_values, - NTTIME *last_change_time) + NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize) { if (key == NULL) return WERR_INVALID_PARAM; @@ -138,7 +141,9 @@ _PUBLIC_ WERROR reg_key_get_info(TALLOC_CTX *mem_ctx, return key->context->ops->get_key_info(mem_ctx, key, classname, num_subkeys, - num_values, last_change_time); + num_values, last_change_time, + max_subkeynamelen, + max_valnamelen, max_valbufsize); } /** diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index c9697ddb4c..1e345ba9f3 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -41,16 +41,19 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, DATA_BLOB *data) { const struct ldb_val *val; + uint32_t value_type; + if (name != NULL) *name = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(msg, "value", NULL)); + value_type = ldb_msg_find_attr_as_uint(msg, "type", 0); if (type != NULL) - *type = ldb_msg_find_attr_as_uint(msg, "type", 0); + *type = value_type; val = ldb_msg_find_ldb_val(msg, "data"); - switch (*type) + switch (value_type) { case REG_SZ: case REG_EXPAND_SZ: @@ -483,7 +486,10 @@ static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, const char **classname, uint32_t *num_subkeys, uint32_t *num_values, - NTTIME *last_change_time) + NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize) { struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data); @@ -504,6 +510,46 @@ static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, if (last_change_time != NULL) *last_change_time = 0; + if (max_subkeynamelen != NULL) { + int i; + struct ldb_message_element *el; + W_ERROR_NOT_OK_RETURN(cache_subkeys(kd)); + + *max_subkeynamelen = 0; + + for (i = 0; i < kd->subkey_count; i++) { + el = ldb_msg_find_element(kd->subkeys[i], "key"); + *max_subkeynamelen = MAX(*max_subkeynamelen, el->values[0].length); + } + } + + if (max_valnamelen != NULL || max_valbufsize != NULL) { + int i; + struct ldb_message_element *el; + W_ERROR_NOT_OK_RETURN(cache_values(kd)); + + if (max_valbufsize != NULL) + *max_valbufsize = 0; + + if (max_valnamelen != NULL) + *max_valnamelen = 0; + + for (i = 0; i < kd->value_count; i++) { + if (max_valnamelen != NULL) { + el = ldb_msg_find_element(kd->values[i], "value"); + *max_valnamelen = MAX(*max_valnamelen, el->values[0].length); + } + + if (max_valbufsize != NULL) { + DATA_BLOB data; + reg_ldb_unpack_value(mem_ctx, kd->values[i], NULL, + NULL, &data); + *max_valbufsize = MAX(*max_valbufsize, data.length); + talloc_free(data.data); + } + } + } + return WERR_OK; } diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index 35724e7ea6..fa59f25596 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -266,13 +266,17 @@ static WERROR local_get_key_info(TALLOC_CTX *mem_ctx, const char **classname, uint32_t *num_subkeys, uint32_t *num_values, - NTTIME *last_change_time) + NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize) { const struct local_key *local = (const struct local_key *)key; return hive_key_get_info(mem_ctx, local->hive_key, classname, num_subkeys, num_values, - last_change_time); + last_change_time, max_subkeynamelen, + max_valnamelen, max_valbufsize); } const static struct registry_operations local_ops = { diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index 8a417d5935..b6ad7dfb10 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -54,7 +54,7 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, if (oldkey != NULL) { error = reg_key_get_info(mem_ctx, oldkey, NULL, &old_num_subkeys, &old_num_values, - NULL); + NULL, NULL, NULL, NULL); if (!W_ERROR_IS_OK(error)) { DEBUG(0, ("Error occured while getting key info: %s\n", win_errstr(error))); @@ -102,7 +102,7 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, if (newkey != NULL) { error = reg_key_get_info(mem_ctx, newkey, NULL, &new_num_subkeys, &new_num_values, - NULL); + NULL, NULL, NULL, NULL); if (!W_ERROR_IS_OK(error)) { DEBUG(0, ("Error occured while getting key info: %s\n", win_errstr(error))); @@ -412,11 +412,8 @@ static WERROR reg_diff_apply_del_all_values(void *_ctx, const char *key_name) return error; } - W_ERROR_NOT_OK_RETURN(reg_key_get_info(ctx, key, - NULL, - NULL, - &num_values, - NULL)); + W_ERROR_NOT_OK_RETURN(reg_key_get_info(ctx, key, NULL, + NULL, &num_values, NULL, NULL, NULL, NULL)); for (i = 0; i < num_values; i++) { const char *name; diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 9264339a6c..9b126cc808 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -428,7 +428,10 @@ static WERROR regf_get_info(TALLOC_CTX *mem_ctx, const char **classname, uint32_t *num_subkeys, uint32_t *num_values, - NTTIME *last_mod_time) + NTTIME *last_mod_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize) { const struct regf_key_data *private_data = (const struct regf_key_data *)key; @@ -452,6 +455,12 @@ static WERROR regf_get_info(TALLOC_CTX *mem_ctx, /* TODO: Last mod time */ + /* TODO: max valnamelen */ + + /* TODO: max valbufsize */ + + /* TODO: max subkeynamelen */ + return WERR_OK; } diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 8273333b24..fac9180378 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -89,7 +89,10 @@ struct registry_operations { const char **classname, uint32_t *numsubkeys, uint32_t *numvalues, - NTTIME *last_change_time); + NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize); WERROR (*flush_key) (struct registry_key *key); @@ -211,7 +214,10 @@ WERROR reg_key_get_info(TALLOC_CTX *mem_ctx, const char **class_name, uint32_t *num_subkeys, uint32_t *num_values, - NTTIME *last_change_time); + NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize); WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *key, int idx, diff --git a/source4/lib/registry/rpc.c b/source4/lib/registry/rpc.c index 2a6cabc3b8..18b7607713 100644 --- a/source4/lib/registry/rpc.c +++ b/source4/lib/registry/rpc.c @@ -29,6 +29,7 @@ struct rpc_key { uint32_t num_subkeys; uint32_t max_valnamelen; uint32_t max_valdatalen; + uint32_t max_subkeynamelen; }; struct rpc_registry_context { @@ -202,7 +203,7 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, } name.length = 0; - name.size = mykeydata->max_valnamelen * 2+1; + name.size = mykeydata->max_valnamelen * 2; name.name = NULL; r.in.handle = &mykeydata->pol; @@ -213,6 +214,7 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, r.in.length = &zero; r.in.size = &mykeydata->max_valdatalen; r.out.name = &name; + r.out.type = type; status = dcerpc_winreg_EnumValue(mykeydata->pipe, mem_ctx, &r); if(NT_STATUS_IS_ERR(status)) { @@ -313,18 +315,17 @@ static WERROR rpc_query_key(const struct registry_key *k) 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 num_values; uint32_t secdescsize; NTTIME last_changed_time; ZERO_STRUCT(r.out); r.out.num_subkeys = &mykeydata->num_subkeys; - r.out.max_subkeylen = &mykeydata->num_values; + r.out.max_subkeylen = &mykeydata->max_subkeynamelen; r.out.max_valnamelen = &mykeydata->max_valnamelen; r.out.max_valbufsize = &mykeydata->max_valdatalen; r.out.max_subkeysize = &max_subkeysize; - r.out.num_values = &num_values; + r.out.num_values = &mykeydata->num_values; r.out.secdescsize = &secdescsize; r.out.last_changed_time = &last_changed_time; @@ -367,7 +368,10 @@ static WERROR rpc_get_info(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char **classname, uint32_t *numsubkeys, uint32_t *numvalue, - NTTIME *last_changed_time) + NTTIME *last_changed_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize) { struct rpc_key *mykeydata = talloc_get_type(key, struct rpc_key); WERROR error; @@ -386,6 +390,15 @@ static WERROR rpc_get_info(TALLOC_CTX *mem_ctx, const struct registry_key *key, if (numsubkeys != NULL) *numsubkeys = mykeydata->num_subkeys; + if (max_valnamelen != NULL) + *max_valnamelen = mykeydata->max_valnamelen; + + if (max_valbufsize != NULL) + *max_valbufsize = mykeydata->max_valdatalen; + + if (max_subkeynamelen != NULL) + *max_subkeynamelen = mykeydata->max_subkeynamelen; + return WERR_OK; } diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index 36eea84d94..22b4785222 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -47,7 +47,7 @@ static bool test_keyinfo_root(struct torture_context *tctx, /* This is a new backend. There should be no subkeys and no * values */ error = hive_key_get_info(tctx, root, NULL, &num_subkeys, &num_values, - NULL); + NULL, NULL, NULL, NULL); torture_assert_werr_ok(tctx, error, "reg_key_num_subkeys()"); torture_assert_int_equal(tctx, num_subkeys, 0, @@ -80,7 +80,7 @@ static bool test_keyinfo_nums(struct torture_context *tctx, void *test_data) /* This is a new backend. There should be no subkeys and no * values */ error = hive_key_get_info(tctx, root, NULL, &num_subkeys, &num_values, - NULL); + NULL, NULL, NULL, NULL); torture_assert_werr_ok(tctx, error, "reg_key_num_subkeys()"); torture_assert_int_equal(tctx, num_subkeys, 1, "subkey count"); diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 2133e72310..75fbe1cbea 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -265,7 +265,7 @@ static bool test_query_key(struct torture_context *tctx, void *_data) error = reg_key_get_info(tctx, subkey, &classname, &num_subkeys, &num_values, - &last_changed_time); + &last_changed_time, NULL, NULL, NULL); torture_assert_werr_ok(tctx, error, "get info key"); torture_assert(tctx, classname == NULL, "classname"); @@ -295,7 +295,7 @@ static bool test_query_key_nums(struct torture_context *tctx, void *_data) torture_assert_werr_ok(tctx, error, "set value"); error = reg_key_get_info(tctx, subkey1, NULL, &num_subkeys, - &num_values, NULL); + &num_values, NULL, NULL, NULL, NULL); torture_assert_werr_ok(tctx, error, "get info key"); torture_assert_int_equal(tctx, num_subkeys, 1, "num subkeys"); diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 329d6ab670..93f28f3e5a 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -53,11 +53,16 @@ static WERROR cmd_info(struct regshell_context *ctx, int argc, char **argv) struct security_descriptor *sec_desc = NULL; time_t last_mod; WERROR error; - const char *classname; + const char *classname = NULL; NTTIME last_change; - - error = reg_key_get_info(ctx, ctx->current, &classname, NULL, NULL, - &last_change); + uint32_t max_subkeynamelen; + uint32_t max_valnamelen; + uint32_t max_valbufsize; + uint32_t num_subkeys; + uint32_t num_values; + + error = reg_key_get_info(ctx, ctx->current, &classname, &num_subkeys, &num_values, + &last_change, &max_subkeynamelen, &max_valnamelen, &max_valbufsize); if (!W_ERROR_IS_OK(error)) { printf("Error getting key info: %s\n", win_errstr(error)); return error; @@ -67,9 +72,21 @@ static WERROR cmd_info(struct regshell_context *ctx, int argc, char **argv) printf("Name: %s\n", strchr(ctx->path, '\\')?strrchr(ctx->path, '\\')+1: ctx->path); printf("Full path: %s\n", ctx->path); - printf("Key Class: %s\n", classname); + if (classname != NULL) + printf("Key Class: %s\n", classname); last_mod = nt_time_to_unix(last_change); printf("Time Last Modified: %s\n", ctime(&last_mod)); + printf("Number of subkeys: %d\n", num_subkeys); + printf("Number of values: %d\n", num_values); + + if (max_valnamelen > 0) + printf("Maximum value name length: %d\n", max_valnamelen); + + if (max_valbufsize > 0) + printf("Maximum value data length: %d\n", max_valbufsize); + + if (max_subkeynamelen > 0) + printf("Maximum sub key name length: %d\n", max_subkeynamelen); error = reg_get_sec_desc(ctx, ctx->current, &sec_desc); if (!W_ERROR_IS_OK(error)) { @@ -188,10 +205,9 @@ static WERROR cmd_ls(struct regshell_context *ctx, int argc, char **argv) { int i; WERROR error; - struct registry_value *value; uint32_t data_type; DATA_BLOB data; - const char *name; + const char *name = NULL; for (i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(ctx, ctx->current, @@ -213,7 +229,7 @@ static WERROR cmd_ls(struct regshell_context *ctx, int argc, char **argv) &name, &data_type, &data)); i++) { - printf("V \"%s\" %s %s\n", value->name, str_regtype(data_type), + printf("V \"%s\" %s %s\n", name, str_regtype(data_type), reg_val_data_string(ctx, data_type, data)); } diff --git a/source4/rpc_server/winreg/rpc_winreg.c b/source4/rpc_server/winreg/rpc_winreg.c index 47c963ad29..681e3b918f 100644 --- a/source4/rpc_server/winreg/rpc_winreg.c +++ b/source4/rpc_server/winreg/rpc_winreg.c @@ -262,7 +262,7 @@ static WERROR dcesrv_winreg_EnumValue(struct dcesrv_call_state *dce_call, r->out.name->name = data_name; r->out.name->length = 2*strlen_m_term(data_name); - r->out.name->size = 2*strlen_m_term(data_name); + r->out.name->size = r->in.name->size; if (r->in.value) { r->out.value = data.data; @@ -379,7 +379,9 @@ static WERROR dcesrv_winreg_QueryInfoKey(struct dcesrv_call_state *dce_call, k = h->data; ret = reg_key_get_info(mem_ctx, k, &classname, r->out.num_subkeys, - r->out.num_values, r->out.last_changed_time); + r->out.num_values, r->out.last_changed_time, + r->out.max_subkeylen, r->out.max_valnamelen, + r->out.max_valbufsize); if (r->out.classname != NULL) r->out.classname->name = classname; |