From d8c3428b3bb10075cec3b37adbca54db634d3b00 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 15 Dec 2004 00:16:54 +0000 Subject: r4209: Fix several smaller bugs Add "predef" and "set" commands in regshell Some of the remote calls from a Windows box work now. (This used to be commit f3e05782804fe4b4942fa966f1b9650c64bc234d) --- source4/include/registry.h | 6 +- source4/lib/registry/common/reg_interface.c | 9 ++- source4/lib/registry/common/reg_util.c | 67 ++++++++++++++++++--- source4/lib/registry/reg_backend_dir.c | 2 +- source4/lib/registry/reg_backend_ldb.c | 48 +++++++-------- source4/lib/registry/reg_backend_nt4.c | 7 ++- source4/lib/registry/reg_backend_rpc.c | 2 +- source4/lib/registry/tools/regshell.c | 92 ++++++++++++++++++++--------- source4/rpc_server/winreg/rpc_winreg.c | 20 ++++++- 9 files changed, 181 insertions(+), 72 deletions(-) diff --git a/source4/include/registry.h b/source4/include/registry.h index e2f8bc087a..d90e9ccfc1 100644 --- a/source4/include/registry.h +++ b/source4/include/registry.h @@ -122,15 +122,15 @@ struct hive_operations { WERROR (*get_value_by_name) (TALLOC_CTX *, struct registry_key *, const char *name, struct registry_value **); /* Security control */ - WERROR (*key_get_sec_desc) (TALLOC_CTX *, struct registry_key *, SEC_DESC **); - WERROR (*key_set_sec_desc) (struct registry_key *, SEC_DESC *); + WERROR (*key_get_sec_desc) (TALLOC_CTX *, struct registry_key *, struct security_descriptor **); + WERROR (*key_set_sec_desc) (struct registry_key *, struct security_descriptor *); /* Notification */ WERROR (*request_key_change_notify) (struct registry_key *, key_notification_function); WERROR (*request_value_change_notify) (struct registry_value *, value_notification_function); /* Key management */ - WERROR (*add_key)(TALLOC_CTX *, struct registry_key *, const char *name, uint32_t access_mask, SEC_DESC *, struct registry_key **); + WERROR (*add_key)(TALLOC_CTX *, struct registry_key *, const char *name, uint32_t access_mask, struct security_descriptor *, struct registry_key **); WERROR (*del_key)(struct registry_key *, const char *name); WERROR (*flush_key) (struct registry_key *); diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index c729945a26..f5c3598721 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -348,9 +348,12 @@ WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key, for(i = 0; W_ERROR_IS_OK(error); i++) { error = reg_key_get_subkey_by_index(mem_ctx, key, i, subkey); if(W_ERROR_IS_OK(error) && !strcmp((*subkey)->name, name)) { - return error; + break; } } + + if (W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) + error = WERR_DEST_NOT_FOUND; } else { return WERR_NOT_SUPPORTED; } @@ -375,7 +378,7 @@ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key, } else { for(i = 0; W_ERROR_IS_OK(error); i++) { error = reg_key_get_value_by_index(mem_ctx, key, i, val); - if(W_ERROR_IS_OK(error) && StrCaseCmp((*val)->name, name)) { + if(W_ERROR_IS_OK(error) && !strcmp((*val)->name, name)) { break; } } @@ -402,7 +405,7 @@ WERROR reg_key_del(struct registry_key *parent, const char *name) return WERR_OK; } -WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, uint32_t access_mask, SEC_DESC *desc, struct registry_key **newkey) +WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *desc, struct registry_key **newkey) { WERROR error; diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index 1d1f770324..68144fc56f 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -24,14 +24,27 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_REGISTRY +static const struct { + uint32 id; + const char *name; +} reg_value_types[] = { + { REG_SZ, "REG_SZ" }, + { REG_DWORD, "REG_DWORD" }, + { REG_BINARY, "REG_BINARY" }, + { REG_EXPAND_SZ, "REG_EXPAND_SZ" }, + { REG_NONE, "REG_NONE" }, + { 0, NULL } +}; + /* Return string description of registry value type */ const char *str_regtype(int type) { - switch(type) { - case REG_SZ: return "STRING"; - case REG_DWORD: return "DWORD"; - case REG_BINARY: return "BINARY"; + int i; + for (i = 0; reg_value_types[i].name; i++) { + if (reg_value_types[i].id == type) + return reg_value_types[i].name; } + return "Unknown"; } @@ -84,10 +97,48 @@ char *reg_val_description(TALLOC_CTX *mem_ctx, struct registry_value *val) return talloc_asprintf(mem_ctx, "%s = %s : %s", val->name?val->name:"", str_regtype(val->data_type), reg_val_data_string(mem_ctx, val)); } -BOOL reg_val_set_string(struct registry_value *val, char *str) +BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, struct registry_value **value) { - /* FIXME */ - return False; + int i; + *value = talloc_p(mem_ctx, struct registry_value); + (*value)->data_type = -1; + + /* Find the correct type */ + for (i = 0; reg_value_types[i].name; i++) { + if (!strcmp(reg_value_types[i].name, type_str)) { + (*value)->data_type = reg_value_types[i].id; + break; + } + } + + if ((*value)->data_type == -1) + return False; + + /* Convert data appropriately */ + + switch ((*value)->data_type) + { + case REG_SZ: + case REG_EXPAND_SZ: + (*value)->data_blk = talloc_strdup(mem_ctx, data_str); + (*value)->data_len = strlen(data_str); + break; + case REG_DWORD: + (*value)->data_len = sizeof(uint32); + (*value)->data_blk = talloc_p(mem_ctx, uint32); + *((uint32 *)(*value)->data_blk) = atol(data_str); + break; + + case REG_NONE: + (*value)->data_len = 0; + (*value)->data_blk = NULL; + break; + + default: + case REG_BINARY: /* FIXME */ + return False; + } + return True; } WERROR reg_key_get_subkey_val(TALLOC_CTX *mem_ctx, struct registry_key *key, const char *subname, const char *valname, struct registry_value **val) @@ -220,7 +271,7 @@ WERROR reg_key_del_abs(struct registry_context *ctx, const char *path) return error; } -WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx, const char *path, uint32 access_mask, SEC_DESC *sec_desc, struct registry_key **result) +WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx, const char *path, uint32 access_mask, struct security_descriptor *sec_desc, struct registry_key **result) { struct registry_key *parent; const char *n; diff --git a/source4/lib/registry/reg_backend_dir.c b/source4/lib/registry/reg_backend_dir.c index 41a0da58c0..4af219facb 100644 --- a/source4/lib/registry/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir.c @@ -22,7 +22,7 @@ #include "registry.h" #include "system/dir.h" -static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, uint32_t access_mask, SEC_DESC *desc, struct registry_key **result) +static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *desc, struct registry_key **result) { char *path; int ret; diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 7a63f4a530..9b0b5759ce 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -56,18 +56,19 @@ static int reg_close_ldb_key (void *data) return 0; } -static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char *add) +static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, struct registry_key *from, const char *path, const char *add) { char *ret = talloc_strdup(mem_ctx, ""); - char *mypath = strdup(path); - char *end = mypath, *begin; + char *mypath = talloc_strdup(mem_ctx, path); + char *begin; + struct ldb_key_data *kd = from->backend_data; if(add) ret = talloc_asprintf_append(ret, "%s", add); - while(end) { + while(mypath) { char *keyname; - begin = strrchr(end, '\\'); + begin = strrchr(mypath, '\\'); if(begin) keyname = begin + 1; else keyname = mypath; @@ -77,18 +78,13 @@ static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char * if(begin) { *begin = '\0'; - end = begin-1; } else { - end = NULL; + break; } } - SAFE_FREE(mypath); + ret = talloc_asprintf_append(ret, "%s", kd->dn); - ret[strlen(ret)-1] = '\0'; - - if(strlen(ret) == 0) return NULL; - return ret; } @@ -127,6 +123,7 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, i struct ldb_context *c = k->hive->backend_data; struct ldb_message_element *el; struct ldb_key_data *kd = k->backend_data; + const struct ldb_val *val; /* Do the search if necessary */ if (kd->values == NULL) { @@ -144,7 +141,10 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, i *value = talloc_p(mem_ctx, struct registry_value); (*value)->name = talloc_strdup(mem_ctx, el->values[0].data); - /* FIXME */ + (*value)->data_type = ldb_msg_find_uint(kd->values[idx], "type", 0); + val = ldb_msg_find_ldb_val(kd->values[idx], "data"); + (*value)->data_blk = talloc_memdup(mem_ctx, val->data, val->length); + (*value)->data_len = val->length; return WERR_OK; } @@ -155,11 +155,9 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const ch struct ldb_message **msg; char *ldap_path; int ret; - struct ldb_key_data *kd = h->backend_data, *newkd; - ldap_path = talloc_asprintf(mem_ctx, "%s%s%s", - reg_path_to_ldb(mem_ctx, name, NULL), - kd->dn?",":"", - kd->dn?kd->dn:""); + struct ldb_key_data *newkd; + + ldap_path = reg_path_to_ldb(mem_ctx, h, name, NULL); ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL,&msg); @@ -185,9 +183,12 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) { struct ldb_context *c; struct ldb_key_data *kd; + struct ldb_wrap *wrap; if (!hive->location) return WERR_INVALID_PARAM; - c = ldb_connect(hive->location, 0, NULL); + wrap = ldb_wrap_connect(hive, hive->location, 0, NULL); + + c = wrap->ldb; if(!c) { DEBUG(1, ("ldb_open_hive: %s\n", ldb_errstring(hive->backend_data))); @@ -201,13 +202,13 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) talloc_set_destructor (hive, ldb_close_hive); (*k)->name = talloc_strdup(*k, ""); (*k)->backend_data = kd = talloc_zero_p(*k, struct ldb_key_data); - kd->dn = talloc_strdup(*k, "key=root"); + kd->dn = talloc_strdup(*k, "hive="); return WERR_OK; } -static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, uint32_t access_mask, SEC_DESC *sd, struct registry_key **newkey) +static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *sd, struct registry_key **newkey) { struct ldb_context *ctx = parent->hive->backend_data; struct ldb_message msg; @@ -216,7 +217,7 @@ static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, struct registry_key *parent, con ZERO_STRUCT(msg); - msg.dn = reg_path_to_ldb(mem_ctx, parent->path, talloc_asprintf(mem_ctx, "key=%s,", name)); + msg.dn = reg_path_to_ldb(mem_ctx, parent, name, NULL); ldb_msg_add_string(ctx, &msg, "key", talloc_strdup(mem_ctx, name)); @@ -276,13 +277,14 @@ static WERROR ldb_set_value (struct registry_key *parent, const char *name, uint struct ldb_context *ctx = parent->hive->backend_data; struct ldb_message msg; struct ldb_val val; + struct ldb_key_data *kd = parent->backend_data; int ret; char *type_s; TALLOC_CTX *mem_ctx = talloc_init("ldb_set_value"); ZERO_STRUCT(msg); - msg.dn = reg_path_to_ldb(mem_ctx, parent->path, talloc_asprintf(mem_ctx, "value=%s,", name)); + msg.dn = talloc_asprintf(mem_ctx, "value=%s,%s", name, kd->dn); ldb_msg_add_string(ctx, &msg, "value", talloc_strdup(mem_ctx, name)); val.length = len; diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index 117d8d1b81..5633156b20 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -64,7 +64,8 @@ marked with ???? the rest of the first 4kb page is not important... the "hbin"-Block ================ -I don't know what "hbin" stands for, but this block is always a multiple +hbin probably means hive-bin (what bin stands for I don't know) +This block is always a multiple of 4kb in size. Inside these hbin-blocks the different records are placed. The memory- @@ -419,7 +420,7 @@ typedef struct key_sec_desc_s { int state; int offset; SK_HDR *sk_hdr; /* This means we must keep the registry in memory */ - SEC_DESC *sec_desc; + struct security_descriptor *sec_desc; } KEY_SEC_DESC; /* A map of sk offsets in the regf to KEY_SEC_DESCs for quick lookup etc */ @@ -481,7 +482,7 @@ typedef struct regf_struct_s { int sk_count, sk_map_size; SK_MAP *sk_map; const char *owner_sid_str; - SEC_DESC *def_sec_desc; + struct security_descriptor *def_sec_desc; /* * These next pointers point to the blocks used to contain the * keys when we are preparing to write them to a file diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 224a061762..c5ed9b2c88 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -257,7 +257,7 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key * return r.out.result; } -static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, uint32_t access_mask, SEC_DESC *sec, struct registry_key **key) +static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *sec, struct registry_key **key) { NTSTATUS status; struct winreg_CreateKey r; diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 6de8b25c9c..1dd0e04561 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -37,7 +37,7 @@ * exit */ -static struct registry_key *cmd_info(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) +static struct registry_key *cmd_info(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) { time_t last_mod; printf("Name: %s\n", cur->name); @@ -49,19 +49,50 @@ static struct registry_key *cmd_info(TALLOC_CTX *mem_ctx, struct registry_key *c return cur; } -static struct registry_key *cmd_pwd(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) +static struct registry_key *cmd_predef(TALLOC_CTX *mem_ctx, struct registry_context *ctx, struct registry_key *cur, int argc, char **argv) +{ + struct registry_key *ret = NULL; + if (argc < 2) { + fprintf(stderr, "Usage: predef predefined-key-name\n"); + } else if (!ctx) { + fprintf(stderr, "No full registry loaded, no predefined keys defined\n"); + } else { + WERROR error = reg_get_predefined_key_by_name(ctx, argv[1], &ret); + + if (!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Error opening predefined key %s: %s\n", argv[1], win_errstr(error)); + ret = NULL; + } + } + return ret; +} + +static struct registry_key *cmd_pwd(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) { printf("%s\n", cur->path); return cur; } -static struct registry_key *cmd_set(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) +static struct registry_key *cmd_set(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) { - /* FIXME */ - return NULL; + if (argc < 4) { + fprintf(stderr, "Usage: set value-name type value\n"); + } else { + struct registry_value *val; + if (reg_string_to_val(mem_ctx, argv[2], argv[3], &val)) { + WERROR error = reg_val_set(cur, argv[1], val->data_type, val->data_blk, val->data_len); + if (!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Error setting value: %s\n", win_errstr(error)); + return NULL; + } + } else { + fprintf(stderr, "Unable to interpret data\n"); + } + } + return cur; } -static struct registry_key *cmd_ck(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) +static struct registry_key *cmd_ck(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) { struct registry_key *new = NULL; WERROR error; @@ -80,7 +111,7 @@ static struct registry_key *cmd_ck(TALLOC_CTX *mem_ctx, struct registry_key *cur return new; } -static struct registry_key *cmd_ls(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) +static struct registry_key *cmd_ls(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) { int i; WERROR error; @@ -100,7 +131,7 @@ static struct registry_key *cmd_ls(TALLOC_CTX *mem_ctx, struct registry_key *cur return NULL; } -static struct registry_key *cmd_mkkey(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) +static struct registry_key *cmd_mkkey(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) { struct registry_key *tmp; if(argc < 2) { @@ -113,12 +144,10 @@ static struct registry_key *cmd_mkkey(TALLOC_CTX *mem_ctx, struct registry_key * return NULL; } - fprintf(stderr, "Successfully added new subkey '%s' to '%s'\n", argv[1], cur->path); - return NULL; } -static struct registry_key *cmd_rmkey(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) +static struct registry_key *cmd_rmkey(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) { if(argc < 2) { fprintf(stderr, "Usage: rmkey \n"); @@ -134,7 +163,7 @@ static struct registry_key *cmd_rmkey(TALLOC_CTX *mem_ctx, struct registry_key * return NULL; } -static struct registry_key *cmd_rmval(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) +static struct registry_key *cmd_rmval(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) { if(argc < 2) { fprintf(stderr, "Usage: rmval \n"); @@ -150,19 +179,19 @@ static struct registry_key *cmd_rmval(TALLOC_CTX *mem_ctx, struct registry_key * return NULL; } -static struct registry_key *cmd_exit(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) +static struct registry_key *cmd_exit(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) { exit(0); return NULL; } -static struct registry_key *cmd_help(TALLOC_CTX *mem_ctx, struct registry_key *, int, char **); +static struct registry_key *cmd_help(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *, int, char **); struct { const char *name; const char *alias; const char *help; - struct registry_key *(*handle)(TALLOC_CTX *mem_ctx, struct registry_key *, int argc, char **argv); + struct registry_key *(*handle)(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *, int argc, char **argv); } regshell_cmds[] = { {"ck", "cd", "Change current key", cmd_ck }, {"info", "i", "Show detailed information of a key", cmd_info }, @@ -174,10 +203,11 @@ struct { {"set", "update", "Update value", cmd_set }, {"help", "?", "Help", cmd_help }, {"exit", "quit", "Exit", cmd_exit }, + {"predef", "predefined", "Go to predefined key", cmd_predef }, {NULL } }; -static struct registry_key *cmd_help(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) +static struct registry_key *cmd_help(TALLOC_CTX *mem_ctx, struct registry_context *ctx, struct registry_key *cur, int argc, char **argv) { int i; printf("Available commands:\n"); @@ -187,7 +217,7 @@ static struct registry_key *cmd_help(TALLOC_CTX *mem_ctx, struct registry_key *c return NULL; } -static struct registry_key *process_cmd(TALLOC_CTX *mem_ctx, struct registry_key *k, char *line) +static struct registry_key *process_cmd(TALLOC_CTX *mem_ctx, struct registry_context *ctx, struct registry_key *k, char *line) { int argc; char **argv = NULL; @@ -201,7 +231,7 @@ static struct registry_key *process_cmd(TALLOC_CTX *mem_ctx, struct registry_key for(i = 0; regshell_cmds[i].name; i++) { if(!strcmp(regshell_cmds[i].name, argv[0]) || (regshell_cmds[i].alias && !strcmp(regshell_cmds[i].alias, argv[0]))) { - return regshell_cmds[i].handle(mem_ctx, k, argc, argv); + return regshell_cmds[i].handle(mem_ctx, ctx, k, argc, argv); } } @@ -214,7 +244,7 @@ static struct registry_key *process_cmd(TALLOC_CTX *mem_ctx, struct registry_key static struct registry_key *current_key = NULL; -static char **reg_complete_command(const char *text, int end) +static char **reg_complete_command(const char *text, int start, int end) { /* Complete command */ char **matches; @@ -262,23 +292,28 @@ cleanup: return NULL; } -static char **reg_complete_key(const char *text, int end) +static char **reg_complete_key(const char *text, int start, int end) { + struct registry_key *base; struct registry_key *subkey; int i, j = 1; int samelen = 0; int len; char **matches; + const char *base_n = ""; TALLOC_CTX *mem_ctx; + WERROR status; matches = malloc_array_p(char *, MAX_COMPLETIONS); if (!matches) return NULL; matches[0] = NULL; + mem_ctx = talloc_init("completion"); + + base = current_key; len = strlen(text); - mem_ctx = talloc_init("completion"); for(i = 0; j < MAX_COMPLETIONS-1; i++) { - WERROR status = reg_key_get_subkey_by_index(mem_ctx, current_key, i, &subkey); + status = reg_key_get_subkey_by_index(mem_ctx, base, i, &subkey); if(W_ERROR_IS_OK(status)) { if(!strncmp(text, subkey->name, len)) { matches[j] = strdup(subkey->name); @@ -298,18 +333,19 @@ static char **reg_complete_key(const char *text, int end) return NULL; } } - talloc_destroy(mem_ctx); if (j == 1) { /* No matches at all */ SAFE_FREE(matches); + talloc_destroy(mem_ctx); return NULL; } if (j == 2) { /* Exact match */ - matches[0] = strdup(matches[1]); + asprintf(&matches[0], "%s%s", base_n, matches[1]); } else { - matches[0] = strndup(matches[1], samelen); + asprintf(&matches[0], "%s%s", base_n, talloc_strndup(mem_ctx, matches[1], samelen)); } + talloc_destroy(mem_ctx); matches[j] = NULL; return matches; @@ -320,9 +356,9 @@ static char **reg_completion(const char *text, int start, int end) smb_readline_ca_char(' '); if (start == 0) { - return reg_complete_command(text, end); + return reg_complete_command(text, start, end); } else { - return reg_complete_key(text, end); + return reg_complete_key(text, start, end); } } @@ -395,7 +431,7 @@ static char **reg_completion(const char *text, int start, int end) break; if(line[0] != '\n') { - struct registry_key *new = process_cmd(mem_ctx, curkey, line); + struct registry_key *new = process_cmd(mem_ctx, h, curkey, line); if(new)curkey = new; } } diff --git a/source4/rpc_server/winreg/rpc_winreg.c b/source4/rpc_server/winreg/rpc_winreg.c index b34ccfa4b9..20bf7f9117 100644 --- a/source4/rpc_server/winreg/rpc_winreg.c +++ b/source4/rpc_server/winreg/rpc_winreg.c @@ -328,7 +328,8 @@ static WERROR winreg_QueryInfoKey(struct dcesrv_call_state *dce_call, TALLOC_CTX } r->out.secdescsize = 0; /* FIXME */ - ZERO_STRUCT(r->out.last_changed_time); /* FIXME */ if (!W_ERROR_IS_OK(ret)) { + ZERO_STRUCT(r->out.last_changed_time); /* FIXME */ + if (!W_ERROR_IS_OK(ret)) { return ret; } @@ -414,7 +415,22 @@ static WERROR winreg_SetKeySecurity(struct dcesrv_call_state *dce_call, TALLOC_C static WERROR winreg_SetValue(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_SetValue *r) { - return WERR_NOT_SUPPORTED; + struct dcesrv_handle *h; + struct registry_key *key; + WERROR result; + + h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY); + DCESRV_CHECK_HANDLE(h); + + key = h->data; + + result = reg_val_set(key, r->in.name.name, r->in.type, r->in.data, r->in.size); + + if (!W_ERROR_IS_OK(result)) { + return result; + } + + return WERR_OK; } -- cgit