From df952e95cd1cbbfb62b4620e9452993aaef44ad3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 29 Oct 2004 13:38:37 +0000 Subject: [PATCH] r3369: More registry updates We now pass the RPC-WINREG torture test. Also, constructions like the following work now: regtree <-> smbd <-> NTUSER.DAT --- source/include/registry.h | 4 +- source/lib/registry/common/reg_interface.c | 76 +++++++++++++++++++++- source/rpc_server/winreg/rpc_winreg.c | 64 +++++++++++++++++- 3 files changed, 137 insertions(+), 7 deletions(-) diff --git a/source/include/registry.h b/source/include/registry.h index 3aea70ecc1b..a099ae1e0f7 100644 --- a/source/include/registry.h +++ b/source/include/registry.h @@ -73,7 +73,7 @@ struct registry_key { struct registry_value { char *name; - int data_type; + unsigned int data_type; int data_len; void *data_blk; /* Might want a separate block */ struct registry_hive *hive; @@ -104,6 +104,7 @@ struct registry_operations { /* Implement this one */ WERROR (*open_hive) (TALLOC_CTX *, struct registry_hive *, struct registry_key **); + WERROR (*close_hive) (struct registry_hive *); /* Or this one */ WERROR (*open_key) (TALLOC_CTX *, struct registry_hive *, const char *name, struct registry_key **); @@ -131,6 +132,7 @@ struct registry_operations { /* Key management */ WERROR (*add_key)(TALLOC_CTX *, struct registry_key *, const char *name, uint32_t access_mask, SEC_DESC *, struct registry_key **); WERROR (*del_key)(struct registry_key *); + WERROR (*flush_key) (struct registry_key *); /* Value management */ WERROR (*set_value)(struct registry_key *, const char *name, int type, void *data, int len); diff --git a/source/lib/registry/common/reg_interface.c b/source/lib/registry/common/reg_interface.c index 044dc9a0ad1..09267a63708 100644 --- a/source/lib/registry/common/reg_interface.c +++ b/source/lib/registry/common/reg_interface.c @@ -340,7 +340,7 @@ WERROR reg_key_num_subkeys(struct registry_key *key, int *count) talloc_destroy(mem_ctx); *count = i; - if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) return WERR_OK; + if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) error = WERR_OK; return error; } @@ -351,8 +351,26 @@ WERROR reg_key_num_values(struct registry_key *key, int *count) { if(!key) return WERR_INVALID_PARAM; - - return key->hive->functions->num_values(key, count); + + if (key->hive->functions->num_values) { + return key->hive->functions->num_values(key, count); + } + + if(key->hive->functions->get_value_by_index) { + int i; + WERROR error; + struct registry_value *dest; + TALLOC_CTX *mem_ctx = talloc_init("num_subkeys"); + + for(i = 0; W_ERROR_IS_OK(error = key->hive->functions->get_value_by_index(mem_ctx, key, i, &dest)); i++); + talloc_destroy(mem_ctx); + + *count = i; + if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) error = WERR_OK; + return error; + } + + return WERR_NOT_SUPPORTED; } WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key *key, int idx, struct registry_key **subkey) @@ -646,3 +664,55 @@ WERROR reg_key_flush(struct registry_key *key) /* No need for flushing, apparently */ return WERR_OK; } + +WERROR reg_key_subkeysizes(struct registry_key *key, uint32 *max_subkeylen, uint32 *max_subkeysize) +{ + int i = 0; + struct registry_key *subkey; + WERROR error; + TALLOC_CTX *mem_ctx = talloc_init("subkeysize"); + + *max_subkeylen = *max_subkeysize = 0; + + do { + error = reg_key_get_subkey_by_index(mem_ctx, key, i, &subkey); + + if (W_ERROR_IS_OK(error)) { + *max_subkeysize = MAX(*max_subkeysize, 0xFF); + *max_subkeylen = MAX(*max_subkeylen, strlen(subkey->name)); + } + + i++; + } while (W_ERROR_IS_OK(error)); + + talloc_destroy(mem_ctx); + + return WERR_OK; +} + +WERROR reg_key_valuesizes(struct registry_key *key, uint32 *max_valnamelen, uint32 *max_valbufsize) +{ + int i = 0; + struct registry_value *value; + WERROR error; + TALLOC_CTX *mem_ctx = talloc_init("subkeysize"); + + *max_valnamelen = *max_valbufsize = 0; + + do { + error = reg_key_get_value_by_index(mem_ctx, key, i, &value); + + if (W_ERROR_IS_OK(error)) { + if (value->name) { + *max_valnamelen = MAX(*max_valnamelen, strlen(value->name)); + } + *max_valbufsize = MAX(*max_valbufsize, value->data_len); + } + + i++; + } while (W_ERROR_IS_OK(error)); + + talloc_destroy(mem_ctx); + + return WERR_OK; +} diff --git a/source/rpc_server/winreg/rpc_winreg.c b/source/rpc_server/winreg/rpc_winreg.c index 0a071ef7413..fcbbf124c04 100644 --- a/source/rpc_server/winreg/rpc_winreg.c +++ b/source/rpc_server/winreg/rpc_winreg.c @@ -197,8 +197,31 @@ static WERROR winreg_EnumKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem static WERROR winreg_EnumValue(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_EnumValue *r) { + struct dcesrv_handle *h; + struct registry_key *key; + struct registry_value *value; + WERROR result; - return WERR_NOT_SUPPORTED; + h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY); + DCESRV_CHECK_HANDLE(h); + + key = h->data; + + result = reg_key_get_value_by_index(mem_ctx, key, r->in.enum_index, &value); + if (!W_ERROR_IS_OK(result)) { + return result; + } + + r->out.type = &value->data_type; + r->out.name_out.name = value->name; + r->out.value_out = talloc_p(mem_ctx, struct EnumValueOut); + r->out.value_out->offset = 0; + r->out.value_out->buffer = data_blob_talloc(mem_ctx, value->data_blk, value->data_len); + r->out.value_len1 = r->in.value_len1; + r->out.value_len2 = r->in.value_len2; + + + return WERR_OK; } @@ -280,7 +303,41 @@ static WERROR winreg_OpenKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem static WERROR winreg_QueryInfoKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_QueryInfoKey *r) { - return WERR_NOT_SUPPORTED; + struct dcesrv_handle *h; + struct registry_key *k; + WERROR ret; + + h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY); + DCESRV_CHECK_HANDLE(h); + k = h->data; + + ret = reg_key_num_subkeys(k, &r->out.num_subkeys); + if (!W_ERROR_IS_OK(ret)) { + return ret; + } + + ret = reg_key_num_values(k, &r->out.num_values); + if (!W_ERROR_IS_OK(ret)) { + return ret; + } + + ret = reg_key_subkeysizes(k, &r->out.max_subkeysize, &r->out.max_subkeylen); + if (!W_ERROR_IS_OK(ret)) { + return ret; + } + + ret = reg_key_valuesizes(k, &r->out.max_valnamelen, &r->out.max_valbufsize); + if (!W_ERROR_IS_OK(ret)) { + return ret; + } + + r->out.secdescsize = 0; /* FIXME */ + ZERO_STRUCT(r->out.last_changed_time); /* FIXME */ if (!W_ERROR_IS_OK(ret)) { + return ret; + } + + + return WERR_OK; } @@ -380,7 +437,8 @@ static WERROR winreg_AbortSystemShutdown(struct dcesrv_call_state *dce_call, TAL static WERROR winreg_GetVersion(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_GetVersion *r) { - return WERR_NOT_SUPPORTED; + r->out.version = 5; + return WERR_OK; }