r4209: Fix several smaller bugs
authorJelmer Vernooij <jelmer@samba.org>
Wed, 15 Dec 2004 00:16:54 +0000 (00:16 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:07:27 +0000 (13:07 -0500)
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
source4/lib/registry/common/reg_interface.c
source4/lib/registry/common/reg_util.c
source4/lib/registry/reg_backend_dir.c
source4/lib/registry/reg_backend_ldb.c
source4/lib/registry/reg_backend_nt4.c
source4/lib/registry/reg_backend_rpc.c
source4/lib/registry/tools/regshell.c
source4/rpc_server/winreg/rpc_winreg.c

index e2f8bc087a3fc220b01a5485428b7784147f4003..d90e9ccfc14e3549c806074c8be846926e18a864 100644 (file)
@@ -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 *);
 
index c729945a262cec1478ec4ae5ce871f40d9e64ce3..f5c3598721111c22309cdb28de18ee9202e2ecb4 100644 (file)
@@ -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;
        
index 1d1f7703245d38fcd4ec8530cc3b9f96b5351bb2..68144fc56fdd10968553ea25564565ca983782a1 100644 (file)
 #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:"<No 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;
index 41a0da58c017bcc836548cd36075b70ce926f143..4af219facbfb1d0bb3eeb0a295e11fde63063cb9 100644 (file)
@@ -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;
index 7a63f4a5304b3f80835a0344f2d815d7e952a9e6..9b0b5759cedde035fd7ef255e2bf6a6ea5c1a816 100644 (file)
@@ -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;
index 117d8d1b81841a8ecead9bf7d5a68d3e48d24c35..5633156b2073aa038dc028d51153fce4832f46f9 100644 (file)
@@ -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
index 224a061762dd57e93910db88dc28a4017cb87db2..c5ed9b2c8849743e3bbae93add9ccf72031a861a 100644 (file)
@@ -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;
index 6de8b25c9cf66e43454a7f4b0fe157706b66f5e1..1dd0e04561d3937a9ec20dc0589494534d4154d0 100644 (file)
@@ -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 <name>\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 <valuename>\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;
                }
        }
index b34ccfa4b9e572a93f47eefa6473c6a8064339bd..20bf7f9117fa3e10ed2c45522cd809aa25fc5e98 100644 (file)
@@ -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;
 }