r26689: registry: Return max_subkeynamelen, max_valnamelen and max_valbufsize in...
authorJelmer Vernooij <jelmer@samba.org>
Mon, 7 Jan 2008 20:11:29 +0000 (14:11 -0600)
committerStefan Metzmacher <metze@samba.org>
Mon, 7 Jan 2008 14:18:07 +0000 (08:18 -0600)
14 files changed:
source/lib/registry/dir.c
source/lib/registry/hive.c
source/lib/registry/hive.h
source/lib/registry/interface.c
source/lib/registry/ldb.c
source/lib/registry/local.c
source/lib/registry/patchfile.c
source/lib/registry/regf.c
source/lib/registry/registry.h
source/lib/registry/rpc.c
source/lib/registry/tests/hive.c
source/lib/registry/tests/registry.c
source/lib/registry/tools/regshell.c
source/rpc_server/winreg/rpc_winreg.c

index 2f00d2fea01b8dc64139f0cb2e9b1a915d462085..a13e3753b7f0bac4010c0f351d6b76efdccd7a83 100644 (file)
@@ -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);
                }
index d7d12076f33250ad0e84bd3c011cff9a4586c17b..bbe510772cc9a714e90b631ef81229f261fc5ce7 100644 (file)
@@ -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,
index 1e05f6b0134e0f29949263066808018bb3ef7155..6d9a69c7c5dfcfac208132917e8d074460bdb7d6 100644 (file)
@@ -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,
index b914fbab305b6e9a01ed660cdce4fb00ded6a51c..a18fd2c28c88fa61fc07cb66d5b941721c0d67fa 100644 (file)
@@ -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);
 }
 
 /**
index c9697ddb4cac1944a36f9bd8a12a55a1ac858edf..1e345ba9f35ff0170204250847910afdc4da0903 100644 (file)
@@ -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;
 }
 
index 35724e7ea6ef210366e78114730cf05c116968e0..fa59f255966c0154fd870f2f0499efd0dc9d86e6 100644 (file)
@@ -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 = {
index 8a417d5935f32d4496b03ed8b43ab746c0cb938e..b6ad7dfb1099c72eed4ccdbcd20f8ee80547e7f4 100644 (file)
@@ -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;
index 9264339a6c8b6cc8c3ae34ce7d208e69d600aece..9b126cc8084fe4d08748c6ce000ee5138dd3e224 100644 (file)
@@ -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;
 }
 
index 8273333b242bf06eb60a530c61caaf825d0f6151..fac9180378340ffc92b347632226a2bc52fae994 100644 (file)
@@ -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,
index 2a6cabc3b803910a3aa845083922277dd8482f19..18b7607713f38f9a217929d5f3575096680be1a4 100644 (file)
@@ -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;
 }
 
index 36eea84d9404b6c78e40aab62321fd296abdff2e..22b4785222567f0b71238e32a4204f12e4930bfb 100644 (file)
@@ -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");
index 2133e72310b81a485054386ceec25caea410c096..75fbe1cbea8bca48d2815d97b84e5387d132ac17 100644 (file)
@@ -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");
index 329d6ab6701fce208cd849d831fae5f73927768e..93f28f3e5a803766541a399ab53c7610f7941892 100644 (file)
@@ -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));
        }
 
index 47c963ad293a17327422df9cf730c2e37b008dda..681e3b918f870afc11f38ce47c81539fbd3ee8c0 100644 (file)
@@ -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;