From 69c19afb6226e93a244490fa582200364a3b7069 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 5 Apr 2004 09:17:11 +0000 Subject: r31: More registry updates. regdiff/regpatch work now. (This used to be commit 98224f5436695eb265f5d997cf4bc9cf735a4fb9) --- source4/lib/registry/TODO | 4 - source4/lib/registry/common/reg_interface.c | 65 ++++++++- source4/lib/registry/common/reg_objects.c | 2 +- .../lib/registry/reg_backend_dir/reg_backend_dir.c | 63 ++++----- .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 25 ++-- source4/lib/registry/tools/regdiff.c | 12 +- source4/lib/registry/tools/regpatch.c | 148 ++++++++------------- source4/librpc/idl/winreg.idl | 15 +-- source4/rpc_server/winreg/rpc_winreg.c | 13 -- 9 files changed, 169 insertions(+), 178 deletions(-) (limited to 'source4') diff --git a/source4/lib/registry/TODO b/source4/lib/registry/TODO index 26fb8d217d..ac467d0078 100644 --- a/source4/lib/registry/TODO +++ b/source4/lib/registry/TODO @@ -3,7 +3,6 @@ - use memory pools? - get rid of all the nasty memory leaks.. - security stuff -- finish 'regpatch' - clean up code - rpc_server @@ -22,6 +21,3 @@ reg_backend_ldb: reg_backend_wine.c: - implement - -regpatch.c: - - test/finish diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index dc49dab4c1..d40a855f89 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -187,6 +187,8 @@ REG_VAL *reg_key_get_value_by_index(REG_KEY *key, int idx) int reg_key_num_subkeys(REG_KEY *key) { + if(!key) return 0; + if(!key->handle->functions->num_subkeys) { if(!key->cache_subkeys) key->handle->functions->fetch_subkeys(key, &key->cache_subkeys_count, &key->cache_subkeys); @@ -306,8 +308,12 @@ REG_VAL *reg_key_get_value_by_name(REG_KEY *key, const char *name) BOOL reg_key_del(REG_KEY *key) { - if(key->handle->functions->del_key) - return key->handle->functions->del_key(key); + if(key->handle->functions->del_key) { + if(key->handle->functions->del_key(key)) { + free_cached_keys(key); + return True; + } + } return False; } @@ -349,17 +355,53 @@ BOOL reg_val_del(REG_VAL *val) return False; } - return val->handle->functions->del_value(val); + if(val->handle->functions->del_value(val)) { + free_cached_values(val->parent); + return True; + } + return False; +} + +BOOL reg_key_add_name_recursive(REG_KEY *parent, const char *path) +{ + REG_KEY *cur, *prevcur = parent; + char *begin = (char *)path, *end; + + while(1) { + end = strchr(begin, '\\'); + if(end) *end = '\0'; + cur = reg_key_get_subkey_by_name(prevcur, begin); + if(!cur) { + if(!reg_key_add_name(prevcur, begin)) { printf("foo\n"); return False; } + cur = reg_key_get_subkey_by_name(prevcur, begin); + if(!cur) { + DEBUG(0, ("Can't find key after adding it : %s\n", begin)); + return False; + } + } + + if(!end) break; + *end = '\\'; + begin = end+1; + prevcur = cur; + } + return True; } BOOL reg_key_add_name(REG_KEY *parent, const char *name) { + if (!parent) return False; + if (!parent->handle->functions->add_key) { DEBUG(1, ("Backend '%s' doesn't support method add_key\n", parent->handle->functions->name)); return False; } - return parent->handle->functions->add_key(parent, name); + if(parent->handle->functions->add_key(parent, name)) { + free_cached_keys(parent); + return True; + } + return False; } BOOL reg_val_update(REG_VAL *val, int type, void *data, int len) @@ -377,6 +419,7 @@ BOOL reg_val_update(REG_VAL *val, int type, void *data, int len) new = val->handle->functions->add_value(val->parent, val->name, type, data, len); memcpy(val, new, sizeof(REG_VAL)); + free_cached_values(val->parent); return True; } @@ -419,5 +462,19 @@ REG_VAL *reg_key_add_value(REG_KEY *key, const char *name, int type, void *value ret = key->handle->functions->add_value(key, name, type, value, vallen); ret->parent = key; ret->handle = key->handle; + free_cached_values(key); return ret; } + +void free_cached_values(REG_KEY *key) +{ + free(key->cache_values); key->cache_values = NULL; + key->cache_values_count = 0; +} + + +void free_cached_keys(REG_KEY *key) +{ + free(key->cache_subkeys); key->cache_subkeys = NULL; + key->cache_subkeys_count = 0; +} diff --git a/source4/lib/registry/common/reg_objects.c b/source4/lib/registry/common/reg_objects.c index 911dc15c8e..8de0065da0 100644 --- a/source4/lib/registry/common/reg_objects.c +++ b/source4/lib/registry/common/reg_objects.c @@ -161,7 +161,7 @@ char *reg_val_get_path(REG_VAL *v) return NULL; } -char *reg_key_get_path(REG_KEY *k) +const char *reg_key_get_path(REG_KEY *k) { SMB_REG_ASSERT(k); return k->path; diff --git a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c index baed39b4eb..5fec782e95 100644 --- a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c @@ -21,27 +21,11 @@ #include "includes.h" #include "lib/registry/common/registry.h" -static DIR *reg_dir_dir(REG_HANDLE *h, const char *base, const char *name) -{ - char *path = NULL; - DIR *d; - asprintf(&path, "%s/%s/%s", h->location, base, name); - path = reg_path_win2unix(path); - - d = opendir(path); - if(!d) { - printf("Unable to open '%s'\n", path); - return NULL; - } - SAFE_FREE(path); - return d; -} - static BOOL reg_dir_add_key(REG_KEY *parent, const char *name) { char *path; int ret; - asprintf(&path, "%s/%s/%s", parent->handle->location, reg_key_get_path(parent), name); + asprintf(&path, "%s%s\\%s", parent->handle->location, reg_key_get_path(parent), name); path = reg_path_win2unix(path); ret = mkdir(path, 0700); free(path); @@ -50,13 +34,7 @@ static BOOL reg_dir_add_key(REG_KEY *parent, const char *name) static BOOL reg_dir_del_key(REG_KEY *k) { - char *path; - int ret; - asprintf(&path, "%s/%s", k->handle->location, reg_key_get_path(k)); - path = reg_path_win2unix(path); - ret = rmdir(path); - free(path); - return (ret == 0); + return (rmdir((char *)k->backend_data) == 0); } static REG_KEY *reg_dir_open_key(REG_HANDLE *h, const char *name) @@ -67,32 +45,41 @@ static REG_KEY *reg_dir_open_key(REG_HANDLE *h, const char *name) DEBUG(0, ("NULL pointer passed as directory name!")); return NULL; } - fullpath = reg_path_win2unix(strdup(name)); - d = reg_dir_dir(h, "", fullpath); - free(fullpath); + asprintf(&fullpath, "%s%s", h->location, name); + fullpath = reg_path_win2unix(fullpath); - if(d) return reg_key_new_abs(name, h, d); - return NULL; + d = opendir(fullpath); + if(!d) { + DEBUG(3,("Unable to open '%s': %s\n", fullpath, strerror(errno))); + SAFE_FREE(fullpath); + return NULL; + } + closedir(d); + + return reg_key_new_abs(name, h, fullpath); } static BOOL reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r) { - DIR *d = (DIR *)k->backend_data; struct dirent *e; int max = 200; + char *fullpath = k->backend_data; REG_KEY **ar; - if(!d) return False; - rewinddir(d); + DIR *d; (*count) = 0; ar = malloc(sizeof(REG_KEY *) * max); + + d = opendir(fullpath); + + if(!d) return False; while((e = readdir(d))) { if(e->d_type == DT_DIR && strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) { - char *fullpath = reg_path_win2unix(strdup(k->path)); - ar[(*count)] = reg_key_new_rel(e->d_name, k, reg_dir_dir(k->handle, fullpath, e->d_name)); - free(fullpath); + char *newfullpath; + asprintf(&newfullpath, "%s/%s", fullpath, e->d_name); + ar[(*count)] = reg_key_new_rel(e->d_name, k, newfullpath); if(ar[(*count)])(*count)++; if((*count) == max) { @@ -101,6 +88,8 @@ static BOOL reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r) } } } + + closedir(d); *r = ar; return True; @@ -113,7 +102,7 @@ static BOOL reg_dir_open(REG_HANDLE *h, const char *loc, BOOL try) { static void dir_free(REG_KEY *k) { - closedir((DIR *)k->backend_data); + free(k->backend_data); } static REG_VAL *reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len) @@ -132,7 +121,7 @@ static REG_VAL *reg_dir_add_value(REG_KEY *p, const char *name, int type, void * static BOOL reg_dir_del_value(REG_VAL *v) { - char *fullpath = reg_path_win2unix(strdup(reg_val_get_path(v))); + /* FIXME*/ return False; } diff --git a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c index 7e8ad9bf48..796d957076 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -230,9 +230,8 @@ static BOOL rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys) static BOOL rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values) { struct winreg_EnumValue r; - struct winreg_EnumValueName name; struct winreg_Uint8buf value; - struct winreg_Uint16buf buf; + struct winreg_String valuename; struct rpc_data *mydata = parent->handle->backend_data; TALLOC_CTX *mem_ctx; uint32 type, requested_len, returned_len; @@ -241,6 +240,12 @@ static BOOL rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values) (*count) = 0; + /* Root */ + if(parent->backend_data == parent->handle->backend_data) { + *values = ar; + return True; + } + if(!parent->backend_data) parent->backend_data = rpc_get_key_handle(parent->handle, reg_key_get_path(parent)); if(!parent->backend_data) return False; @@ -248,16 +253,8 @@ static BOOL rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values) r.in.handle = parent->backend_data; r.in.enum_index = 0; - buf.max_len = 0x7fff; - buf.offset = 0; - buf.len = 0; - buf.buffer = NULL; - - name.len = 0; - name.max_len = buf.max_len *2; - name.buf = &buf; - - r.in.name = r.out.name = &name; + init_winreg_String(&valuename, NULL); + r.in.name = r.out.name = &valuename; type = 0; r.in.type = r.out.type = &type; @@ -280,7 +277,7 @@ static BOOL rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values) if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { r.in.enum_index++; ar[(*count)] = reg_val_new(parent, NULL); - ar[(*count)]->name = strdup((char *)name.buf); + ar[(*count)]->name = strdup(r.out.name->name); ar[(*count)]->data_type = *r.out.type; ar[(*count)]->data_len = value.len; ar[(*count)]->data_blk = malloc(value.len); @@ -292,6 +289,8 @@ static BOOL rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values) talloc_destroy(mem_ctx); + *values = ar; + return True; } diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 070516b798..5e2b97cb98 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -23,14 +23,22 @@ void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) { - int i, numvals1, numvals2, numkeys2; + int i, numkeys1, numvals1, numvals2, numkeys2; + + numkeys1 = reg_key_num_subkeys(oldkey); + for(i = 0; i < numkeys1; i++) { + REG_KEY *t1 = reg_key_get_subkey_by_index(oldkey, i); + if(!reg_key_get_subkey_by_name(newkey, reg_key_name(t1))) { + fprintf(out, "-%s\n", reg_key_get_path(t1)+1); + } + } numkeys2 = reg_key_num_subkeys(newkey); for(i = 0; i < numkeys2; i++) { REG_KEY *t1 = reg_key_get_subkey_by_index(newkey, i); REG_KEY *t2 = reg_key_get_subkey_by_name(oldkey, reg_key_name(t1)); if(!t2) { - fprintf(out, "[%s]\n", reg_key_get_path(t1)); + fprintf(out, "\n[%s]\n", reg_key_get_path(t1)+1); } writediff(t2, t1, out); } diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index f76da7ebf9..27f578e37f 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -172,7 +172,7 @@ static struct cmd_line *get_cmd_line(int fd) while ((rc = read(fd, &ch, 1)) == 1 && ch != '\n') { if (ch == '\r') continue; /* skip CR */ - if (i == cl->len) { + if (i == cl->len-1) { /* * Allocate some more memory */ @@ -193,6 +193,7 @@ static struct cmd_line *get_cmd_line(int fd) return NULL; } + cl->line[i] = '\0'; cl->line_len = i; return cl; @@ -276,9 +277,9 @@ static char *parse_value(struct cmd_line *cl, int *vtype, char **val) char *p1 = NULL, *p2 = NULL, *nstr = NULL, *tstr = NULL, *vstr = NULL; if (!cl || !vtype || !val) return NULL; - if (!cl->line_len) return NULL; + if (!cl->line[0]) return NULL; - p1 = strndup(cl->line, cl->line_len); + p1 = strdup(cl->line); /* FIXME: Better return codes etc ... */ if (!p1) return NULL; p2 = strchr(p1, '='); @@ -380,7 +381,7 @@ static int regedit4_file_type(int fd) cur_ofs = lseek(fd, 0, SEEK_CUR); /* Get current offset */ if (cur_ofs < 0) { - DEBUG(0, ("Unable to get current offset: %s\n", strerror(errno))); + DEBUG(0, ("Unable to get current offset: (%d) %s\n", cur_ofs, strerror(errno))); exit(1); /* FIXME */ } @@ -398,8 +399,7 @@ static int regedit4_file_type(int fd) if (strcmp(desc, FMT_STRING_REGEDIT4) == 0) { if (cur_ofs) { lseek(fd, cur_ofs, SEEK_SET); - } - else { + } else { skip_to_eol(fd); } return FMT_REGEDIT4; @@ -420,47 +420,13 @@ static void strip_comment(struct cmd_line *cl) for (i = 0; i < cl->line_len; i++) { if (cl->line[i] == ';') { + cl->line[i] = '\0'; cl->line_len = i; return; } } } -/* - * trim leading space - */ - -static void trim_leading_spaces(struct cmd_line *cl) -{ - int i; - - if (!cl) return; - - for (i = 0; i < cl->line_len; i++) { - if (cl->line[i] != ' '){ - if (i) memcpy(cl->line, &cl->line[i], cl->line_len - i); - return; - } - } -} - -/* - * trim trailing spaces - */ -static void trim_trailing_spaces(struct cmd_line *cl) -{ - int i; - - if (!cl) return; - - for (i = cl->line_len; i == 0; i--) { - if (cl->line[i-1] != ' ' && - cl->line[i-1] != '\t') { - cl->line_len = i; - } - } -} - /* * Get a command ... This consists of possibly multiple lines: * [key] @@ -497,10 +463,9 @@ static CMD *regedit4_get_cmd(int fd) } strip_comment(cl); /* remove anything beyond a comment char */ - trim_trailing_spaces(cl); - trim_leading_spaces(cl); + trim_string(cl->line, " \t", " \t"); - if (cl->line_len == 0) { /* An empty line */ + if (!cl->line[0]) { /* An empty line */ free_cmd_line(cl); } else { /* Else, non-empty ... */ @@ -625,7 +590,7 @@ typedef struct command_file_s { * Create a new command file structure */ -static CMD_FILE *cmd_file_create(char *file) +static CMD_FILE *cmd_file_create(const char *file) { CMD_FILE *tmp; struct stat sbuf; @@ -637,7 +602,7 @@ static CMD_FILE *cmd_file_create(char *file) */ if (stat(file, &sbuf) < 0) { /* Not able to access file */ - + DEBUG(0,("Stat on %s failed\n", file)); return NULL; } @@ -650,6 +615,7 @@ static CMD_FILE *cmd_file_create(char *file) tmp->name = strdup(file); if ((tmp->fd = open(file, O_RDONLY, 666)) < 0) { + DEBUG(0,("Error opening %s\n", file)); free(tmp); return NULL; } @@ -673,6 +639,7 @@ static CMD_FILE *cmd_file_create(char *file) */ free(tmp); + DEBUG(0,("Unknown type\n")); return NULL; } @@ -711,49 +678,51 @@ int nt_apply_reg_command_file(REG_HANDLE *regf, const char *cmd_file_name) */ switch (cmd->cmd) { case CMD_ADD_KEY: { - REG_KEY *tmp = NULL; - tmp = reg_open_key(reg_get_root(regf), cmd->key); - /* If we found it, apply the other bits, else create such a key */ - if (!tmp) { - if(reg_key_add_name(reg_get_root(regf), cmd->key)) { - tmp = reg_open_key(reg_get_root(regf), cmd->key); - } - modified = 1; - } - - while (cmd->val_count) { - VAL_SPEC_LIST *val = cmd->val_spec_list; - REG_VAL *reg_val = NULL; - - if (val->type == REG_DELETE) { - reg_val = reg_key_get_value_by_name( tmp, val->name); - reg_val_del(reg_val); - modified = 1; - } - else { - /* FIXME - reg_val = nt_add_reg_value(tmp, val->name, val->type, - val->val); */ - modified = 1; - } - - cmd->val_spec_list = val->next; - free_val_spec_list(val); - cmd->val_count--; - } - - break; + REG_KEY *tmp = NULL; + tmp = reg_open_key(reg_get_root(regf), cmd->key); + /* If we found it, apply the other bits, else create such a key */ + if (!tmp) { + if(reg_key_add_name_recursive(reg_get_root(regf), cmd->key)) { + tmp = reg_open_key(reg_get_root(regf), cmd->key); + } else { + DEBUG(0, ("Error adding new key '%s'\n", cmd->key)); + } + modified = 1; + } + + while (cmd->val_count) { + VAL_SPEC_LIST *val = cmd->val_spec_list; + REG_VAL *reg_val = NULL; + + if (val->type == REG_DELETE) { + reg_val = reg_key_get_value_by_name( tmp, val->name); + reg_val_del(reg_val); + modified = 1; + } + else { + /* FIXME + reg_val = nt_add_reg_value(tmp, val->name, val->type, + val->val); */ + modified = 1; + } + + cmd->val_spec_list = val->next; + free_val_spec_list(val); + cmd->val_count--; + } + + break; } case CMD_DEL_KEY: - /* - * Any value does not matter ... - * Find the key if it exists, and delete it ... - */ - - reg_key_del_recursive(reg_open_key(reg_get_root(regf), cmd->key)); - modified = 1; - break; + /* + * Any value does not matter ... + * Find the key if it exists, and delete it ... + */ + + reg_key_del_recursive(reg_open_key(reg_get_root(regf), cmd->key)); + modified = 1; + break; } } free_cmd(cmd); @@ -779,7 +748,7 @@ int main (int argc, char **argv) }; pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); - + while((opt = poptGetNextOpt(pc)) != -1) { } @@ -797,12 +766,11 @@ int main (int argc, char **argv) return 1; } - poptFreeContext(pc); - patch = poptGetArg(pc); if(!patch) patch = "/dev/stdin"; + poptFreeContext(pc); nt_apply_reg_command_file(h, patch); - + return 0; } diff --git a/source4/librpc/idl/winreg.idl b/source4/librpc/idl/winreg.idl index 54cba24760..14f2bcfd5d 100644 --- a/source4/librpc/idl/winreg.idl +++ b/source4/librpc/idl/winreg.idl @@ -114,19 +114,6 @@ [in,out] winreg_Time *last_changed_time ); - typedef struct { - uint32 max_len; - uint32 offset; - uint32 len; - uint16 buffer[len]; - } winreg_Uint16buf; - - typedef struct { - uint16 len; - uint16 max_len; - winreg_Uint16buf *buf; - } winreg_EnumValueName; - typedef struct { uint32 max_len; uint32 offset; @@ -139,7 +126,7 @@ WERROR winreg_EnumValue( [in,ref] policy_handle *handle, [in] uint32 enum_index, - [in,out,ref] winreg_EnumValueName *name, + [in,out,ref] winreg_String *name, [in,out] uint32 *type, [in,out] winreg_Uint8buf *value, [in,out] uint32 *requested_len, diff --git a/source4/rpc_server/winreg/rpc_winreg.c b/source4/rpc_server/winreg/rpc_winreg.c index 2dc6dcd741..2787c07847 100644 --- a/source4/rpc_server/winreg/rpc_winreg.c +++ b/source4/rpc_server/winreg/rpc_winreg.c @@ -22,10 +22,6 @@ #include "includes.h" -REG_HANDLE *get_registry_handle() { - return reg_open("nt4", "/home/aurelia/jelmer/NTUSER.dat", False); -} - /* winreg_OpenHKCR */ @@ -42,15 +38,6 @@ static NTSTATUS winreg_OpenHKCR(struct dcesrv_call_state *dce_call, TALLOC_CTX * static NTSTATUS winreg_OpenHKCU(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_OpenHKCU *r) { - REG_KEY *hkcu = reg_open_key(get_registry_handle(), "\\HKEY_CURRENT_USER"); - - if(!hkcu) { - r->out.result = WERR_NO_MORE_ITEMS; - return NT_STATUS_OK; - } - - r->out.result = WERR_OK; - return NT_STATUS_NOT_IMPLEMENTED; } -- cgit