mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
r3369: More registry updates
We now pass the RPC-WINREG torture test. Also, constructions like the following work now: regtree <-> smbd <-> NTUSER.DAT
This commit is contained in:
parent
313034b10d
commit
df952e95cd
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user