From c424c2b857fe08587eb81a5c5e3625545119d1c2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 4 Apr 2004 16:24:08 +0000 Subject: r20: Add the registry library. Still needs a lot of work, see source/lib/registry/TODO for details. (This used to be commit 7cab3a00d7b4b1d95a3bfa6b28f318b4aaa5d493) --- source4/lib/registry/TODO | 27 + source4/lib/registry/common/reg_display.c | 60 + source4/lib/registry/common/reg_interface.c | 423 +++++ source4/lib/registry/common/reg_objects.c | 202 +++ source4/lib/registry/common/reg_util.c | 164 ++ source4/lib/registry/common/registry.h | 121 ++ source4/lib/registry/config.m4 | 16 + .../lib/registry/reg_backend_dir/reg_backend_dir.c | 154 ++ .../registry/reg_backend_gconf/reg_backend_gconf.c | 189 +++ .../lib/registry/reg_backend_ldb/reg_backend_ldb.c | 61 + .../lib/registry/reg_backend_nt4/reg_backend_nt4.c | 1745 ++++++++++++++++++++ .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 311 ++++ .../registry/reg_backend_wine/reg_backend_wine.c | 32 + source4/lib/registry/tools/regdiff.c | 148 ++ source4/lib/registry/tools/regpatch.c | 808 +++++++++ source4/lib/registry/tools/regshell.c | 243 +++ source4/lib/registry/tools/regtree.c | 91 + source4/lib/registry/winregistry.pc.in | 10 + 18 files changed, 4805 insertions(+) create mode 100644 source4/lib/registry/TODO create mode 100644 source4/lib/registry/common/reg_display.c create mode 100644 source4/lib/registry/common/reg_interface.c create mode 100644 source4/lib/registry/common/reg_objects.c create mode 100644 source4/lib/registry/common/reg_util.c create mode 100644 source4/lib/registry/common/registry.h create mode 100644 source4/lib/registry/config.m4 create mode 100644 source4/lib/registry/reg_backend_dir/reg_backend_dir.c create mode 100644 source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c create mode 100644 source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c create mode 100644 source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c create mode 100644 source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c create mode 100644 source4/lib/registry/reg_backend_wine/reg_backend_wine.c create mode 100644 source4/lib/registry/tools/regdiff.c create mode 100644 source4/lib/registry/tools/regpatch.c create mode 100644 source4/lib/registry/tools/regshell.c create mode 100644 source4/lib/registry/tools/regtree.c create mode 100644 source4/lib/registry/winregistry.pc.in (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/TODO b/source4/lib/registry/TODO new file mode 100644 index 0000000000..26fb8d217d --- /dev/null +++ b/source4/lib/registry/TODO @@ -0,0 +1,27 @@ +- support subtrees +- ../../, /bla/blie support in regshell +- use memory pools? +- get rid of all the nasty memory leaks.. +- security stuff +- finish 'regpatch' +- clean up code +- rpc_server + +reg_backend_dir: + - value support + +reg_backend_nt4: + - write support + +reg_backend_rpc: + - value enum support + - write support + +reg_backend_ldb: + - implement + +reg_backend_wine.c: + - implement + +regpatch.c: + - test/finish diff --git a/source4/lib/registry/common/reg_display.c b/source4/lib/registry/common/reg_display.c new file mode 100644 index 0000000000..e12f4ba20e --- /dev/null +++ b/source4/lib/registry/common/reg_display.c @@ -0,0 +1,60 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Gerald Carter 2001 + Copyright (C) Tim Potter 2000 + Copyright (C) Jelmer Vernooij 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +void display_reg_value(REG_VAL *value) +{ + pstring text; + + switch(reg_val_type(value)) { + case REG_DWORD: + printf("%s: REG_DWORD: 0x%08x\n", reg_val_name(value), + *((uint32 *) reg_val_data_blk(value))); + break; + case REG_SZ: + rpcstr_pull(text, reg_val_data_blk(value), sizeof(text), reg_val_size(value), + STR_TERMINATE); + printf("%s: REG_SZ: %s\n", reg_val_name(value), text); + break; + case REG_BINARY: + printf("%s: REG_BINARY: unknown length value not displayed\n", + reg_val_name(value)); + break; + case REG_MULTI_SZ: { + uint16 *curstr = (uint16 *) reg_val_data_blk(value); + uint8 *start = reg_val_data_blk(value); + printf("%s: REG_MULTI_SZ:\n", reg_val_name(value)); + while ((*curstr != 0) && + ((uint8 *) curstr < start + reg_val_size(value))) { + rpcstr_pull(text, curstr, sizeof(text), -1, + STR_TERMINATE); + printf(" %s\n", text); + curstr += strlen(text) + 1; + } + } + break; + default: + printf("%s: unknown type %d\n", reg_val_name(value), reg_val_type(value)); + } + +} diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c new file mode 100644 index 0000000000..dc49dab4c1 --- /dev/null +++ b/source4/lib/registry/common/reg_interface.c @@ -0,0 +1,423 @@ +/* + Unix SMB/CIFS implementation. + Transparent registry backend handling + Copyright (C) Jelmer Vernooij 2003-2004. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "lib/registry/common/registry.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_REGISTRY + +/* List of available backends */ +static struct reg_init_function_entry *backends = NULL; + +static struct reg_init_function_entry *reg_find_backend_entry(const char *name); + +/* Register new backend */ +NTSTATUS registry_register(void *_function) +{ + REG_OPS *functions = _function; + struct reg_init_function_entry *entry = backends; + + if (!functions || !functions->name) { + return NT_STATUS_INVALID_PARAMETER; + } + + DEBUG(5,("Attempting to register registry backend %s\n", functions->name)); + + /* Check for duplicates */ + if (reg_find_backend_entry(functions->name)) { + DEBUG(0,("There already is a registry backend registered with the name %s!\n", functions->name)); + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + entry = malloc(sizeof(struct reg_init_function_entry)); + entry->functions = functions; + + DLIST_ADD(backends, entry); + DEBUG(5,("Successfully added registry backend '%s'\n", functions->name)); + return NT_STATUS_OK; +} + + +/* Find a backend in the list of available backends */ +static struct reg_init_function_entry *reg_find_backend_entry(const char *name) +{ + struct reg_init_function_entry *entry = backends; + + while(entry) { + if (strcmp(entry->functions->name, name)==0) return entry; + entry = entry->next; + } + + return NULL; +} + +/* Open a registry file/host/etc */ +REG_HANDLE *reg_open(const char *backend, const char *location, BOOL try_full_load) +{ + struct reg_init_function_entry *entry; + static BOOL reg_first_init = True; + REG_HANDLE *ret; + + if(reg_first_init) { + if (!NT_STATUS_IS_OK(register_subsystem("registry", registry_register))) { + return False; + } + + static_init_reg; + reg_first_init = False; + } + + entry = reg_find_backend_entry(backend); + + if (!entry) { + DEBUG(0, ("No such registry backend '%s' loaded!\n", backend)); + return NULL; + } + + ret = malloc(sizeof(REG_HANDLE)); + ZERO_STRUCTP(ret); + ret->location = location?strdup(location):NULL; + ret->functions = entry->functions; + ret->backend_data = NULL; + + if(!entry->functions->open_registry) { + return ret; + } + + if(entry->functions->open_registry(ret, location, try_full_load)) + return ret; + + SAFE_FREE(ret); + return NULL; +} + +/* Open a key */ +REG_KEY *reg_open_key(REG_KEY *parent, const char *name) +{ + char *fullname; + REG_KEY *ret = NULL; + + if(!parent) { + DEBUG(0, ("Invalid parent key specified")); + return NULL; + } + + if(!parent->handle->functions->open_key && + (parent->handle->functions->get_subkey_by_name || + parent->handle->functions->get_subkey_by_index)) { + char *orig = strdup(name), + *curbegin = orig, + *curend = strchr(orig, '\\'); + REG_KEY *curkey = parent; + + while(curbegin && *curbegin) { + if(curend)*curend = '\0'; + curkey = reg_key_get_subkey_by_name(curkey, curbegin); + if(!curkey) return NULL; + if(!curend) break; + curbegin = curend + 1; + curend = strchr(curbegin, '\\'); + } + + return curkey; + } + + asprintf(&fullname, "%s%s%s", parent->path, parent->path[strlen(parent->path)-1] == '\\'?"":"\\", name); + + if(!parent->handle->functions->open_key) { + DEBUG(0, ("Registry backend doesn't have get_subkey_by_name nor open_key!\n")); + return NULL; + } + + ret = parent->handle->functions->open_key(parent->handle, fullname); + + if(ret) { + ret->handle = parent->handle; + ret->path = fullname; + } else + SAFE_FREE(fullname); + + return ret; +} + +REG_VAL *reg_key_get_value_by_index(REG_KEY *key, int idx) +{ + REG_VAL *ret; + + if(!key) return NULL; + + if(!key->handle->functions->get_value_by_index) { + if(!key->cache_values) + key->handle->functions->fetch_values(key, &key->cache_values_count, &key->cache_values); + + if(idx < key->cache_values_count && idx >= 0) { + ret = reg_val_dup(key->cache_values[idx]); + } else { + return NULL; + } + } else { + ret = key->handle->functions->get_value_by_index(key, idx); + } + + if(ret) { + ret->parent = key; + ret->handle = key->handle; + } + + return ret; +} + +int reg_key_num_subkeys(REG_KEY *key) +{ + if(!key->handle->functions->num_subkeys) { + if(!key->cache_subkeys) + key->handle->functions->fetch_subkeys(key, &key->cache_subkeys_count, &key->cache_subkeys); + + return key->cache_subkeys_count; + } + + return key->handle->functions->num_subkeys(key); +} + +int reg_key_num_values(REG_KEY *key) +{ + + if(!key) return 0; + + if(!key->handle->functions->num_values) { + if(!key->handle->functions->fetch_values) { + DEBUG(1, ("Backend '%s' doesn't support enumerating values\n", key->handle->functions->name)); + return 0; + } + + if(!key->cache_values) + key->handle->functions->fetch_values(key, &key->cache_values_count, &key->cache_values); + + return key->cache_values_count; + } + + + return key->handle->functions->num_values(key); +} + +REG_KEY *reg_key_get_subkey_by_index(REG_KEY *key, int idx) +{ + REG_KEY *ret = NULL; + + if(!key) return NULL; + + if(!key->handle->functions->get_subkey_by_index) { + if(!key->cache_subkeys) + key->handle->functions->fetch_subkeys(key, &key->cache_subkeys_count, &key->cache_subkeys); + + if(idx < key->cache_subkeys_count) { + ret = reg_key_dup(key->cache_subkeys[idx]); + } else { + /* No such key ! */ + return NULL; + } + } else { + ret = key->handle->functions->get_subkey_by_index(key, idx); + } + + if(ret && !ret->path) { + asprintf(&ret->path, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name); + ret->handle = key->handle; + } + + return ret; +} + +REG_KEY *reg_key_get_subkey_by_name(REG_KEY *key, const char *name) +{ + int i, max; + REG_KEY *ret = NULL; + + if(!key) return NULL; + + if(key->handle->functions->get_subkey_by_name) { + ret = key->handle->functions->get_subkey_by_name(key,name); + } else { + max = reg_key_num_subkeys(key); + for(i = 0; i < max; i++) { + REG_KEY *v = reg_key_get_subkey_by_index(key, i); + if(v && !strcmp(v->name, name)) { + ret = v; + break; + } + reg_key_free(v); + } + } + + if(ret && !ret->path) { + asprintf(&ret->path, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name); + ret->handle = key->handle; + } + + return ret; +} + +REG_VAL *reg_key_get_value_by_name(REG_KEY *key, const char *name) +{ + int i, max; + REG_VAL *ret = NULL; + + if(!key) return NULL; + + if(key->handle->functions->get_value_by_name) { + ret = key->handle->functions->get_value_by_name(key,name); + } else { + max = reg_key_num_values(key); + for(i = 0; i < max; i++) { + REG_VAL *v = reg_key_get_value_by_index(key, i); + if(v && StrCaseCmp(v->name, name)) { + ret = v; + break; + } + reg_val_free(v); + } + } + + if(ret) { + ret->parent = key; + ret->handle = key->handle; + } + + return ret; +} + +BOOL reg_key_del(REG_KEY *key) +{ + if(key->handle->functions->del_key) + return key->handle->functions->del_key(key); + + return False; +} + +BOOL reg_sync(REG_HANDLE *h, const char *location) +{ + if(!h->functions->sync) + return True; + + return h->functions->sync(h, location); +} + +BOOL reg_key_del_recursive(REG_KEY *key) +{ + BOOL succeed = True; + int i; + + /* Delete all values for specified key */ + for(i = 0; i < reg_key_num_values(key); i++) { + if(!reg_val_del(reg_key_get_value_by_index(key, i))) + succeed = False; + } + + /* Delete all keys below this one */ + for(i = 0; i < reg_key_num_subkeys(key); i++) { + if(!reg_key_del_recursive(reg_key_get_subkey_by_index(key, i))) + succeed = False; + } + + if(succeed)reg_key_del(key); + + return succeed; +} + +BOOL reg_val_del(REG_VAL *val) +{ + if (!val->handle->functions->del_value) { + DEBUG(1, ("Backend '%s' doesn't support method del_value\n", val->handle->functions->name)); + return False; + } + + return val->handle->functions->del_value(val); +} + +BOOL reg_key_add_name(REG_KEY *parent, const char *name) +{ + 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); +} + +BOOL reg_val_update(REG_VAL *val, int type, void *data, int len) +{ + /* A 'real' update function has preference */ + if (val->handle->functions->update_value) + return val->handle->functions->update_value(val, type, data, len); + + /* Otherwise, just remove and add again */ + if (val->handle->functions->add_value && + val->handle->functions->del_value) { + REG_VAL *new; + if(!val->handle->functions->del_value(val)) + return False; + + new = val->handle->functions->add_value(val->parent, val->name, type, data, len); + memcpy(val, new, sizeof(REG_VAL)); + return True; + } + + DEBUG(1, ("Backend '%s' doesn't support method update_value\n", val->handle->functions->name)); + return False; +} + +void reg_free(REG_HANDLE *h) +{ + if(!h->functions->close_registry) return; + + h->functions->close_registry(h); +} + +REG_KEY *reg_get_root(REG_HANDLE *h) +{ + REG_KEY *ret = NULL; + if(h->functions->open_root_key) { + ret = h->functions->open_root_key(h); + } else if(h->functions->open_key) { + ret = h->functions->open_key(h, "\\"); + } else { + DEBUG(0, ("Backend '%s' has neither open_root_key nor open_key method implemented\n", h->functions->name)); + } + + if(ret) { + ret->handle = h; + ret->path = strdup("\\"); + } + + return ret; +} + +REG_VAL *reg_key_add_value(REG_KEY *key, const char *name, int type, void *value, size_t vallen) +{ + REG_VAL *ret; + if(!key->handle->functions->add_value) + return NULL; + + ret = key->handle->functions->add_value(key, name, type, value, vallen); + ret->parent = key; + ret->handle = key->handle; + return ret; +} diff --git a/source4/lib/registry/common/reg_objects.c b/source4/lib/registry/common/reg_objects.c new file mode 100644 index 0000000000..911dc15c8e --- /dev/null +++ b/source4/lib/registry/common/reg_objects.c @@ -0,0 +1,202 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines + * Copyright (C) Gerald Carter 2002. + * Copyright (C) Jelmer Vernooij 2003-2004. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* Implementation of registry frontend view functions. */ + +#include "includes.h" +#include "lib/registry/common/registry.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_SRV + +/*********************************************************************** + allocate memory for and duplicate a REG_VAL. + This is malloc'd memory so the caller should free it when done + **********************************************************************/ + +REG_VAL* reg_val_dup( REG_VAL *val ) +{ + REG_VAL *copy = NULL; + + if ( !val ) + return NULL; + + if ( !(copy = malloc( sizeof(REG_VAL) )) ) { + DEBUG(0,("dup_registry_value: malloc() failed!\n")); + return NULL; + } + + /* copy all the non-pointer initial data */ + + memcpy( copy, val, sizeof(REG_VAL) ); + if ( val->data_blk ) + { + if ( !(copy->data_blk = memdup( val->data_blk, val->data_len )) ) { + DEBUG(0,("dup_registry_value: memdup() failed for [%d] bytes!\n", + val->data_len)); + SAFE_FREE( copy ); + } + } + + return copy; +} + +/********************************************************************** + free the memory allocated to a REG_VAL + *********************************************************************/ + +void reg_val_free( REG_VAL *val ) +{ + if ( !val ) + return; + + if(val->handle->functions->free_val_backend_data) + val->handle->functions->free_val_backend_data(val); + + SAFE_FREE( val->data_blk ); + SAFE_FREE( val ); + + return; +} + +/********************************************************************** + *********************************************************************/ + +uint8* reg_val_data_blk( REG_VAL *val ) +{ + return val->data_blk; +} + +/********************************************************************** + *********************************************************************/ + +int reg_val_size( REG_VAL *val ) +{ + return val->data_len; +} + +/********************************************************************** + *********************************************************************/ + +char *reg_val_name( REG_VAL *val ) +{ + return val->name; +} + +/********************************************************************** + *********************************************************************/ + +uint32 reg_val_type( REG_VAL *val ) +{ + return val->data_type; +} + +/********************************************************************** + *********************************************************************/ + +char *reg_key_name( REG_KEY *key ) +{ + return key->name; +} + +REG_KEY *reg_key_dup(REG_KEY *key) +{ + key->ref++; + return key; +} + +void reg_key_free(REG_KEY *key) +{ + if(!key) + return; + + key->ref--; + if(key->ref) return; + + if(key->handle->functions->free_key_backend_data) + key->handle->functions->free_key_backend_data(key); + + if(key->cache_values) { + int i; + for(i = 0; i < key->cache_values_count; i++) { + reg_val_free(key->cache_values[i]); + } + SAFE_FREE(key->cache_values); + } + + if(key->cache_subkeys) { + int i; + for(i = 0; i < key->cache_subkeys_count; i++) { + reg_key_free(key->cache_subkeys[i]); + } + SAFE_FREE(key->cache_subkeys); + } + + SAFE_FREE(key->path); + SAFE_FREE(key->name); + SAFE_FREE(key); +} + +char *reg_val_get_path(REG_VAL *v) +{ + /* FIXME */ + return NULL; +} + +char *reg_key_get_path(REG_KEY *k) +{ + SMB_REG_ASSERT(k); + return k->path; +} + +/* For use by the backends _ONLY_ */ +REG_KEY *reg_key_new_abs(const char *path, REG_HANDLE *h, void *data) +{ + REG_KEY *r = malloc(sizeof(REG_KEY)); + ZERO_STRUCTP(r); + r->handle = h; + r->path = strdup(path); + r->name = strdup(strrchr(path, '\\')?strrchr(path,'\\')+1:path); + r->backend_data = data; + r->ref = 1; + return r; +} + +REG_KEY *reg_key_new_rel(const char *name, REG_KEY *k, void *data) +{ + REG_KEY *r = malloc(sizeof(REG_KEY)); + ZERO_STRUCTP(r); + r->handle = k->handle; + r->name = strdup(name); + r->backend_data = data; + r->ref = 1; + return r; +} + +REG_VAL *reg_val_new(REG_KEY *parent, void *data) +{ + REG_VAL *r = malloc(sizeof(REG_VAL)); + ZERO_STRUCTP(r); + r->handle = parent->handle; + r->backend_data = data; + r->ref = 1; + return r; +} diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c new file mode 100644 index 0000000000..2941c38cf4 --- /dev/null +++ b/source4/lib/registry/common/reg_util.c @@ -0,0 +1,164 @@ +/* + Unix SMB/CIFS implementation. + Transparent registry backend handling + Copyright (C) Jelmer Vernooij 2003-2004. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_REGISTRY + +/* 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"; + } + return "Unknown"; +} + +char *reg_val_data_string(REG_VAL *v) +{ + char *asciip; + char *ret = NULL; + int i; + + if(reg_val_size(v) == 0) return strdup(""); + + switch (reg_val_type(v)) { + case REG_SZ: + /* FIXME: Convert to ascii */ + return strdup(reg_val_data_blk(v)); + + case REG_EXPAND_SZ: + return strdup(reg_val_data_blk(v)); + + case REG_BINARY: + ret = malloc(reg_val_size(v) * 3 + 2); + asciip = ret; + for (i=0; i 0) + *asciip = ' '; asciip++; + } + *asciip = '\0'; + return ret; + break; + + case REG_DWORD: + if (*(int *)reg_val_data_blk(v) == 0) + ret = strdup("0"); + else + asprintf(&ret, "0x%x", *(int *)reg_val_data_blk(v)); + break; + + case REG_MULTI_SZ: + /* FIXME */ + break; + + default: + return 0; + break; + } + + return ret; +} + +const char *reg_val_description(REG_VAL *val) +{ + char *ret, *ds = reg_val_data_string(val); + asprintf(&ret, "%s = %s : %s", reg_val_name(val)?reg_val_name(val):"", str_regtype(reg_val_type(val)), ds); + free(ds); + return ret; +} + +BOOL reg_val_set_string(REG_VAL *val, char *str) +{ + /* FIXME */ + return False; +} + +REG_VAL *reg_key_get_subkey_val(REG_KEY *key, const char *subname, const char *valname) +{ + REG_KEY *k = reg_key_get_subkey_by_name(key, subname); + if(!k) return NULL; + + return reg_key_get_value_by_name(k, valname); +} + +BOOL reg_key_set_subkey_val(REG_KEY *key, const char *subname, const char *valname, uint32 type, uint8 *data, int real_len) +{ + REG_KEY *k = reg_key_get_subkey_by_name(key, subname); + REG_VAL *v; + if(!k) return False; + + v = reg_key_get_value_by_name(k, valname); + if(!v) return False; + + return reg_val_update(v, type, data, real_len); +} + +/*********************************************************************** + Utility function for splitting the base path of a registry path off + by setting base and new_path to the apprapriate offsets withing the + path. + + WARNING!! Does modify the original string! + ***********************************************************************/ + +BOOL reg_split_path( char *path, char **base, char **new_path ) +{ + char *p; + + *new_path = *base = NULL; + + if ( !path) + return False; + + *base = path; + + p = strchr( path, '\\' ); + + if ( p ) { + *p = '\0'; + *new_path = p+1; + } + + return True; +} + +char *reg_path_win2unix(char *path) +{ + int i; + for(i = 0; path[i]; i++) { + if(path[i] == '\\') path[i] = '/'; + } + return path; +} + +char *reg_path_unix2win(char *path) +{ + int i; + for(i = 0; path[i]; i++) { + if(path[i] == '/') path[i] = '\\'; + } + return path; +} diff --git a/source4/lib/registry/common/registry.h b/source4/lib/registry/common/registry.h new file mode 100644 index 0000000000..4b29006217 --- /dev/null +++ b/source4/lib/registry/common/registry.h @@ -0,0 +1,121 @@ +/* + Unix SMB/CIFS implementation. + Registry interface + This file contains the _internal_ structs for the registry + subsystem. Backends and the subsystem itself are the only + files that need to include this file. + Copyright (C) Gerald Carter 2002. + Copyright (C) Jelmer Vernooij 2003-2004. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _REGISTRY_REGISTRY_H /* _REGISTRY_REGISTRY_H */ +#define _REGISTRY_REGISTRY_H + +#define REGISTRY_INTERFACE_VERSION 1 + +/* structure to store the registry handles */ +struct reg_key_s { + char *name; /* Name of the key */ + char *path; /* Full path to the key */ + smb_ucs2_t *class_name; /* Name of key class */ + NTTIME last_mod; /* Time last modified */ + SEC_DESC *security; + REG_HANDLE *handle; + void *backend_data; + REG_VAL **cache_values; + int cache_values_count; + REG_KEY **cache_subkeys; + int cache_subkeys_count; + int ref; +}; + +struct reg_val_s { + char *name; + int has_name; + int data_type; + int data_len; + void *data_blk; /* Might want a separate block */ + REG_HANDLE *handle; + REG_KEY *parent; + void *backend_data; + int ref; +}; + +/* + * Container for function pointers to enumeration routines + * for virtual registry view + */ + +struct reg_ops_s { + const char *name; + BOOL (*open_registry) (REG_HANDLE *, const char *location, BOOL try_complete_load); + BOOL (*sync)(REG_HANDLE *, const char *location); + BOOL (*close_registry) (REG_HANDLE *); + + /* Either implement these */ + REG_KEY *(*open_root_key) (REG_HANDLE *); + int (*num_subkeys) (REG_KEY *); + int (*num_values) (REG_KEY *); + REG_KEY *(*get_subkey_by_index) (REG_KEY *, int idx); + REG_KEY *(*get_subkey_by_name) (REG_KEY *, const char *name); + REG_VAL *(*get_value_by_index) (REG_KEY *, int idx); + REG_VAL *(*get_value_by_name) (REG_KEY *, const char *name); + + /* Or these */ + REG_KEY *(*open_key) (REG_HANDLE *, const char *name); + BOOL (*fetch_subkeys) (REG_KEY *, int *count, REG_KEY ***); + BOOL (*fetch_values) (REG_KEY *, int *count, REG_VAL ***); + + /* Key management */ + BOOL (*add_key)(REG_KEY *, const char *name); + BOOL (*del_key)(REG_KEY *); + + /* Value management */ + REG_VAL *(*add_value)(REG_KEY *, const char *name, int type, void *data, int len); + BOOL (*del_value)(REG_VAL *); + + /* If update is not available, value will first be deleted and then added + * again */ + BOOL (*update_value)(REG_VAL *, int type, void *data, int len); + + void (*free_key_backend_data) (REG_KEY *); + void (*free_val_backend_data) (REG_VAL *); +}; + +typedef struct reg_sub_tree_s { + char *path; + REG_HANDLE *handle; + struct reg_sub_tree_s *prev, *next; +} REG_SUBTREE; + +struct reg_handle_s { + REG_OPS *functions; + REG_SUBTREE *subtrees; + char *location; + void *backend_data; +}; + +struct reg_init_function_entry { + /* Function to create a member of the pdb_methods list */ + REG_OPS *functions; + struct reg_init_function_entry *prev, *next; +}; + +/* Used internally */ +#define SMB_REG_ASSERT(a) { if(!(a)) { DEBUG(0,("%s failed! (%s:%d)", #a, __FILE__, __LINE__)); }} + +#endif /* _REGISTRY_H */ diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 new file mode 100644 index 0000000000..277fd30dd1 --- /dev/null +++ b/source4/lib/registry/config.m4 @@ -0,0 +1,16 @@ +# Registry backends + +if test t$BLDSHARED = ttrue; then + LIBWINREG_SHARED=bin/libwinregistry.$SHLIBEXT +fi +LIBWINREG=libwinregistry + +PKG_CHECK_MODULES(GCONF, gconf-2.0, [ SMB_MODULE_DEFAULT(reg_gconf,STATIC) + CFLAGS="$CFLAGS $GCONF_CFLAGS";], [AC_MSG_WARN([GConf not found, not building reg_gconf])]) + +SMB_MODULE(reg_nt4, REG, STATIC, lib/registry/reg_backend_nt4/reg_backend_nt4.o) +SMB_MODULE(reg_dir, REG, STATIC, lib/registry/reg_backend_dir/reg_backend_dir.o) +SMB_MODULE(reg_rpc, REG, STATIC, lib/registry/reg_backend_rpc/reg_backend_rpc.o) +SMB_MODULE(reg_gconf, REG, NOT, lib/registry/reg_backend_gconf/reg_backend_gconf.o, [], [$GCONF_LIBS]) +SMB_SUBSYSTEM(REG,lib/registry/common/reg_interface.o,[lib/registry/common/reg_objects.o lib/registry/common/reg_util.o],lib/registry/common/winregistry_proto.h,[]) +AC_OUTPUT(lib/registry/winregistry.pc) diff --git a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c new file mode 100644 index 0000000000..baed39b4eb --- /dev/null +++ b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c @@ -0,0 +1,154 @@ +/* + Unix SMB/CIFS implementation. + Registry interface + Copyright (C) Jelmer Vernooij 2004. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#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); + path = reg_path_win2unix(path); + ret = mkdir(path, 0700); + free(path); + return (ret == 0); +} + +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); +} + +static REG_KEY *reg_dir_open_key(REG_HANDLE *h, const char *name) +{ + DIR *d; + char *fullpath; + if(!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); + + if(d) return reg_key_new_abs(name, h, d); + return NULL; +} + +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; + REG_KEY **ar; + if(!d) return False; + rewinddir(d); + (*count) = 0; + ar = malloc(sizeof(REG_KEY *) * max); + + 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); + if(ar[(*count)])(*count)++; + + if((*count) == max) { + max+=200; + ar = realloc(ar, sizeof(REG_KEY *) * max); + } + } + } + + *r = ar; + return True; +} + +static BOOL reg_dir_open(REG_HANDLE *h, const char *loc, BOOL try) { + if(!loc) return False; + return True; +} + +static void dir_free(REG_KEY *k) +{ + closedir((DIR *)k->backend_data); +} + +static REG_VAL *reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len) +{ + REG_VAL *ret = reg_val_new(p, NULL); + char *fullpath; + FILE *fd; + ret->name = name?strdup(name):NULL; + fullpath = reg_path_win2unix(strdup(reg_val_get_path(ret))); + + fd = fopen(fullpath, "w+"); + + /* FIXME */ + return NULL; +} + +static BOOL reg_dir_del_value(REG_VAL *v) +{ + char *fullpath = reg_path_win2unix(strdup(reg_val_get_path(v))); + return False; +} + +static REG_OPS reg_backend_dir = { + .name = "dir", + .open_registry = reg_dir_open, + .open_key = reg_dir_open_key, + .fetch_subkeys = reg_dir_fetch_subkeys, + .add_key = reg_dir_add_key, + .del_key = reg_dir_del_key, + .add_value = reg_dir_add_value, + .del_value = reg_dir_del_value, + .free_key_backend_data = dir_free +}; + +NTSTATUS reg_dir_init(void) +{ + return register_backend("registry", ®_backend_dir); +} diff --git a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c new file mode 100644 index 0000000000..14da2f54e9 --- /dev/null +++ b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c @@ -0,0 +1,189 @@ +/* + Unix SMB/CIFS implementation. + Registry interface + Copyright (C) Jelmer Vernooij 2004. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "lib/registry/common/registry.h" +#include + +static BOOL reg_open_gconf(REG_HANDLE *h, const char *location, BOOL try_complete_load) +{ + h->backend_data = (void *)gconf_client_get_default(); + return True; +} + +static BOOL reg_close_gconf(REG_HANDLE *h) +{ + return True; +} + +static REG_KEY *gconf_open_key (REG_HANDLE *h, const char *name) +{ + char *fullpath = reg_path_win2unix(strdup(name)); + + /* Check if key exists */ + if(!gconf_client_dir_exists((GConfClient *)h->backend_data, fullpath, NULL)) { + free(fullpath); + return NULL; + } + free(fullpath); + + return reg_key_new_abs(name, h, NULL); +} + +static BOOL gconf_fetch_values(REG_KEY *p, int *count, REG_VAL ***vals) +{ + GSList *entries; + GSList *cur; + REG_VAL **ar = malloc(sizeof(REG_VAL *)); + char *fullpath = strdup(reg_key_get_path(p)); + fullpath = reg_path_win2unix(fullpath); + cur = entries = gconf_client_all_entries((GConfClient*)p->handle->backend_data, fullpath, NULL); + free(fullpath); + + (*count) = 0; + while(cur) { + GConfEntry *entry = cur->data; + GConfValue *value = gconf_entry_get_value(entry); + REG_VAL *newval = reg_val_new(p, NULL); + newval->name = strdup(strrchr(gconf_entry_get_key(entry), '/')+1); + if(value) { + switch(value->type) { + case GCONF_VALUE_INVALID: + newval->data_type = REG_NONE; + break; + + case GCONF_VALUE_STRING: + newval->data_type = REG_SZ; + newval->data_blk = strdup(gconf_value_get_string(value)); + newval->data_len = strlen(newval->data_blk); + break; + + case GCONF_VALUE_INT: + newval->data_type = REG_DWORD; + newval->data_blk = malloc(sizeof(long)); + *((long *)newval->data_blk) = gconf_value_get_int(value); + newval->data_len = sizeof(long); + break; + + case GCONF_VALUE_FLOAT: + newval->data_blk = malloc(sizeof(double)); + newval->data_type = REG_BINARY; + *((double *)newval->data_blk) = gconf_value_get_float(value); + newval->data_len = sizeof(double); + break; + + case GCONF_VALUE_BOOL: + newval->data_blk = malloc(sizeof(BOOL)); + newval->data_type = REG_BINARY; + *((BOOL *)newval->data_blk) = gconf_value_get_bool(value); + newval->data_len = sizeof(BOOL); + break; + + default: + newval->data_type = REG_NONE; + DEBUG(0, ("Not implemented..\n")); + break; + } + } else newval->data_type = REG_NONE; + + ar[(*count)] = newval; + ar = realloc(ar, sizeof(REG_VAL *) * ((*count)+2)); + (*count)++; + g_free(cur->data); + cur = cur->next; + } + + g_slist_free(entries); + *vals = ar; + return True; +} + +static BOOL gconf_fetch_subkeys(REG_KEY *p, int *count, REG_KEY ***subs) +{ + GSList *dirs; + GSList *cur; + REG_KEY **ar = malloc(sizeof(REG_KEY *)); + char *fullpath = strdup(reg_key_get_path(p)); + fullpath = reg_path_win2unix(fullpath); + cur = dirs = gconf_client_all_dirs((GConfClient*)p->handle->backend_data, fullpath,NULL); + free(fullpath); + + (*count) = 0; + while(cur) { + ar[(*count)] = reg_key_new_abs(reg_path_unix2win((char *)cur->data), p->handle, NULL); + ar = realloc(ar, sizeof(REG_KEY *) * ((*count)+2)); + (*count)++; + g_free(cur->data); + cur = cur->next; + } + + g_slist_free(dirs); + *subs = ar; + return True; +} + +static BOOL gconf_update_value(REG_VAL *val, int type, void *data, int len) +{ + GError *error = NULL; + char *keypath = reg_path_win2unix(strdup(reg_key_get_path(val->parent))); + char *valpath; + if(val->name)asprintf(&valpath, "%s/%s", keypath, val->name); + else valpath = strdup(keypath); + free(keypath); + + switch(type) { + case REG_SZ: + case REG_EXPAND_SZ: + gconf_client_set_string((GConfClient *)val->handle->backend_data, valpath, data, &error); + free(valpath); + return (error == NULL); + + case REG_DWORD: + gconf_client_set_int((GConfClient *)val->handle->backend_data, valpath, + *((int *)data), &error); + free(valpath); + return (error == NULL); + default: + DEBUG(0, ("Unsupported type: %d\n", type)); + free(valpath); + return False; + } + return False; +} + +static REG_OPS reg_backend_gconf = { + .name = "gconf", + .open_registry = reg_open_gconf, + .close_registry = reg_close_gconf, + .open_key = gconf_open_key, + .fetch_subkeys = gconf_fetch_subkeys, + .fetch_values = gconf_fetch_values, + .update_value = gconf_update_value, + + /* Note: + * since GConf uses schemas for what keys and values are allowed, there + * is no way of 'emulating' add_key and del_key here. + */ +}; + +NTSTATUS reg_gconf_init(void) +{ + return register_backend("registry", ®_backend_gconf); +} diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c new file mode 100644 index 0000000000..75d5a95187 --- /dev/null +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -0,0 +1,61 @@ +/* + Unix SMB/CIFS implementation. + Registry interface + Copyright (C) Jelmer Vernooij 2004. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "lib/registry/common/registry.h" + +/* + * Saves the dn as private_data for every key/val + */ + +static BOOL ldb_open_registry(REG_HANDLE *handle, const char *location, BOOL try_full_load) +{ + struct ldb_context *c; + c = ldb_connect(location, 0, NULL); + + if(!c) return False; + + handle->backend_data = c; + + return True; +} + +static BOOL ldb_close_registry(REG_HANDLE *h) +{ + ldb_close(h); + return True; +} + +static REG_KEY *ldb_open_key(REG_HANDLE *h, const char *name) +{ + /* FIXME */ +} + +static REG_OPS reg_backend_ldb = { + .name = "ldb", + .open_registry = ldb_open_registry, + .close_registry = ldb_close_registry, + .open_key = ldb_open_key, +}; + +NTSTATUS reg_ldb_init(void) +{ + return register_backend("registry", ®_backend_ldb); +} diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c new file mode 100644 index 0000000000..ef2565bda8 --- /dev/null +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -0,0 +1,1745 @@ +/* + Samba Unix/Linux SMB client utility libeditreg.c + Copyright (C) 2002 Richard Sharpe, rsharpe@richardsharpe.com + Copyright (C) 2003-2004 Jelmer Vernooij, jelmer@samba.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/************************************************************************* + + A utility to edit a Windows NT/2K etc registry file. + + Many of the ideas in here come from other people and software. + I first looked in Wine in misc/registry.c and was also influenced by + http://www.wednesday.demon.co.uk/dosreg.html + + Which seems to contain comments from someone else. I reproduce them here + incase the site above disappears. It actually comes from + http://home.eunet.no/~pnordahl/ntpasswd/WinReg.txt. + + The goal here is to read the registry into memory, manipulate it, and then + write it out if it was changed by any actions of the user. + +The windows NT registry has 2 different blocks, where one can occur many +times... + +the "regf"-Block +================ + +"regf" is obviously the abbreviation for "Registry file". "regf" is the +signature of the header-block which is always 4kb in size, although only +the first 64 bytes seem to be used and a checksum is calculated over +the first 0x200 bytes only! + +Offset Size Contents +0x00000000 D-Word ID: ASCII-"regf" = 0x66676572 +0x00000004 D-Word ???? //see struct REG_HANDLE +0x00000008 D-Word ???? Always the same value as at 0x00000004 +0x0000000C Q-Word last modify date in WinNT date-format +0x00000014 D-Word 1 +0x00000018 D-Word 3 +0x0000001C D-Word 0 +0x00000020 D-Word 1 +0x00000024 D-Word Offset of 1st key record +0x00000028 D-Word Size of the data-blocks (Filesize-4kb) +0x0000002C D-Word 1 +0x000001FC D-Word Sum of all D-Words from 0x00000000 to +0x000001FB //XOR of all words. Nigel + +I have analyzed more registry files (from multiple machines running +NT 4.0 german version) and could not find an explanation for the values +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 +of 4kb in size. + +Inside these hbin-blocks the different records are placed. The memory- +management looks like a C-compiler heap management to me... + +hbin-Header +=========== +Offset Size Contents +0x0000 D-Word ID: ASCII-"hbin" = 0x6E696268 +0x0004 D-Word Offset from the 1st hbin-Block +0x0008 D-Word Offset to the next hbin-Block +0x001C D-Word Block-size + +The values in 0x0008 and 0x001C should be the same, so I don't know +if they are correct or swapped... + +From offset 0x0020 inside a hbin-block data is stored with the following +format: + +Offset Size Contents +0x0000 D-Word Data-block size //this size must be a +multiple of 8. Nigel +0x0004 ???? Data + +If the size field is negative (bit 31 set), the corresponding block +is free and has a size of -blocksize! + +That does not seem to be true. All block lengths seem to be negative! +(Richard Sharpe) + +The data is stored as one record per block. Block size is a multiple +of 4 and the last block reaches the next hbin-block, leaving no room. + +(That also seems incorrect, in that the block size if a multiple of 8. +That is, the block, including the 4 byte header, is always a multiple of +8 bytes. Richard Sharpe.) + +Records in the hbin-blocks +========================== + +nk-Record + + The nk-record can be treated as a combination of tree-record and + key-record of the win 95 registry. + +lf-Record + + The lf-record is the counterpart to the RGKN-record (the + hash-function) + +vk-Record + + The vk-record consists information to a single value (value key). + +sk-Record + + sk (? Security Key ?) is the ACL of the registry. + +Value-Lists + + The value-lists contain information about which values are inside a + sub-key and don't have a header. + +Datas + + The datas of the registry are (like the value-list) stored without a + header. + +All offset-values are relative to the first hbin-block and point to the +block-size field of the record-entry. to get the file offset, you have to add +the header size (4kb) and the size field (4 bytes)... + +the nk-Record +============= +Offset Size Contents +0x0000 Word ID: ASCII-"nk" = 0x6B6E +0x0002 Word for the root-key: 0x2C, otherwise 0x20 //key symbolic links 0x10. Nigel +0x0004 Q-Word write-date/time in windows nt notation +0x0010 D-Word Offset of Owner/Parent key +0x0014 D-Word number of sub-Keys +0x001C D-Word Offset of the sub-key lf-Records +0x0024 D-Word number of values +0x0028 D-Word Offset of the Value-List +0x002C D-Word Offset of the sk-Record + +0x0030 D-Word Offset of the Class-Name //see NK structure for the use of these fields. Nigel +0x0044 D-Word Unused (data-trash) //some kind of run time index. Does not appear to be important. Nigel +0x0048 Word name-length +0x004A Word class-name length +0x004C ???? key-name + +the Value-List +============== +Offset Size Contents +0x0000 D-Word Offset 1st Value +0x0004 D-Word Offset 2nd Value +0x???? D-Word Offset nth Value + +To determine the number of values, you have to look at the owner-nk-record! + +Der vk-Record +============= +Offset Size Contents +0x0000 Word ID: ASCII-"vk" = 0x6B76 +0x0002 Word name length +0x0004 D-Word length of the data //if top bit is set when offset contains data. Nigel +0x0008 D-Word Offset of Data +0x000C D-Word Type of value +0x0010 Word Flag +0x0012 Word Unused (data-trash) +0x0014 ???? Name + +If bit 0 of the flag-word is set, a name is present, otherwise the value has no name (=default) + +If the data-size is lower 5, the data-offset value is used to store the data itself! + +The data-types +============== +Wert Beteutung +0x0001 RegSZ: character string (in UNICODE!) +0x0002 ExpandSZ: string with "%var%" expanding (UNICODE!) +0x0003 RegBin: raw-binary value +0x0004 RegDWord: Dword +0x0007 RegMultiSZ: multiple strings, seperated with 0 + (UNICODE!) + +The "lf"-record +=============== +Offset Size Contents +0x0000 Word ID: ASCII-"lf" = 0x666C +0x0002 Word number of keys +0x0004 ???? Hash-Records + +Hash-Record +=========== +Offset Size Contents +0x0000 D-Word Offset of corresponding "nk"-Record +0x0004 D-Word ASCII: the first 4 characters of the key-name, padded with 0's. Case sensitiv! + +Keep in mind, that the value at 0x0004 is used for checking the data-consistency! If you change the +key-name you have to change the hash-value too! + +//These hashrecords must be sorted low to high within the lf record. Nigel. + +The "sk"-block +============== +(due to the complexity of the SAM-info, not clear jet) +(This is just a self-relative security descriptor in the data. R Sharpe.) + + +Offset Size Contents +0x0000 Word ID: ASCII-"sk" = 0x6B73 +0x0002 Word Unused +0x0004 D-Word Offset of previous "sk"-Record +0x0008 D-Word Offset of next "sk"-Record +0x000C D-Word usage-counter +0x0010 D-Word Size of "sk"-record in bytes +???? //standard self +relative security desciptor. Nigel +???? ???? Security and auditing settings... +???? + +The usage counter counts the number of references to this +"sk"-record. You can use one "sk"-record for the entire registry! + +Windows nt date/time format +=========================== +The time-format is a 64-bit integer which is incremented every +0,0000001 seconds by 1 (I don't know how accurate it realy is!) +It starts with 0 at the 1st of january 1601 0:00! All values are +stored in GMT time! The time-zone is important to get the real +time! + +Common values for win95 and win-nt +================================== +Offset values marking an "end of list", are either 0 or -1 (0xFFFFFFFF). +If a value has no name (length=0, flag(bit 0)=0), it is treated as the +"Default" entry... +If a value has no data (length=0), it is displayed as empty. + +simplyfied win-3.?? registry: +============================= + ++-----------+ +| next rec. |---+ +----->+------------+ +| first sub | | | | Usage cnt. | +| name | | +-->+------------+ | | length | +| value | | | | next rec. | | | text |------->+-------+ ++-----------+ | | | name rec. |--+ +------------+ | xxxxx | + +------------+ | | value rec. |-------->+------------+ +-------+ + v | +------------+ | Usage cnt. | ++-----------+ | | length | +| next rec. | | | text |------->+-------+ +| first sub |------+ +------------+ | xxxxx | +| name | +-------+ +| value | ++-----------+ + +Greatly simplyfied structure of the nt-registry: +================================================ + ++---------------------------------------------------------------+ +| | +v | ++---------+ +---------->+-----------+ +----->+---------+ | +| "nk" | | | lf-rec. | | | nk-rec. | | +| ID | | | # of keys | | | parent |---+ +| Date | | | 1st key |--+ | .... | +| parent | | +-----------+ +---------+ +| suk-keys|-----+ +| values |--------------------->+----------+ +| SK-rec. |---------------+ | 1. value |--> +----------+ +| class |--+ | +----------+ | vk-rec. | ++---------+ | | | .... | + v | | data |--> +-------+ + +------------+ | +----------+ | xxxxx | + | Class name | | +-------+ + +------------+ | + v + +---------+ +---------+ + +----->| next sk |--->| Next sk |--+ + | +---| prev sk |<---| prev sk | | + | | | .... | | ... | | + | | +---------+ +---------+ | + | | ^ | + | | | | + | +--------------------+ | + +----------------------------------+ + +--------------------------------------------------------------------------- + +Hope this helps.... (Although it was "fun" for me to uncover this things, + it took me several sleepless nights ;) + + B.D. + +*************************************************************************/ + +#include "includes.h" +#include "lib/registry/common/registry.h" + +#define REG_KEY_LIST_SIZE 10 +/*FIXME*/ + +/* + * Structures for dealing with the on-disk format of the registry + */ + +const char *def_owner_sid_str = NULL; + +/* + * These definitions are for the in-memory registry structure. + * It is a tree structure that mimics what you see with tools like regedit + */ + + +/* + * Definition of a Key. It has a name, classname, date/time last modified, + * sub-keys, values, and a security descriptor + */ + +#define REG_ROOT_KEY 1 +#define REG_SUB_KEY 2 +#define REG_SYM_LINK 3 + +/* + * All of the structures below actually have a four-byte length before them + * which always seems to be negative. The following macro retrieves that + * size as an integer + */ + +#define BLK_SIZE(b) ((int)*(int *)(((int *)b)-1)) + +typedef unsigned int DWORD; +typedef unsigned short WORD; + +typedef struct sk_struct SK_HDR; +/* + * This structure keeps track of the output format of the registry + */ +#define REG_OUTBLK_HDR 1 +#define REG_OUTBLK_HBIN 2 + +typedef struct regf_block { + DWORD REGF_ID; /* regf */ + DWORD uk1; + DWORD uk2; + DWORD tim1, tim2; + DWORD uk3; /* 1 */ + DWORD uk4; /* 3 */ + DWORD uk5; /* 0 */ + DWORD uk6; /* 1 */ + DWORD first_key; /* offset */ + unsigned int dblk_size; + DWORD uk7[116]; /* 1 */ + DWORD chksum; +} REGF_HDR; + +typedef struct hbin_sub_struct { + DWORD dblocksize; + char data[1]; +} HBIN_SUB_HDR; + +typedef struct hbin_struct { + DWORD HBIN_ID; /* hbin */ + DWORD off_from_first; + DWORD off_to_next; + DWORD uk1; + DWORD uk2; + DWORD uk3; + DWORD uk4; + DWORD blk_size; + HBIN_SUB_HDR hbin_sub_hdr; +} HBIN_HDR; + +typedef struct nk_struct { + WORD NK_ID; + WORD type; + DWORD t1, t2; + DWORD uk1; + DWORD own_off; + DWORD subk_num; + DWORD uk2; + DWORD lf_off; + DWORD uk3; + DWORD val_cnt; + DWORD val_off; + DWORD sk_off; + DWORD clsnam_off; + DWORD unk4[4]; + DWORD unk5; + WORD nam_len; + WORD clsnam_len; + char key_nam[1]; /* Actual length determined by nam_len */ +} NK_HDR; + +struct sk_struct { + WORD SK_ID; + WORD uk1; + DWORD prev_off; + DWORD next_off; + DWORD ref_cnt; + DWORD rec_size; + char sec_desc[1]; +}; + +typedef struct key_sec_desc_s { + struct key_sec_desc_s *prev, *next; + int ref_cnt; + int state; + int offset; + SK_HDR *sk_hdr; /* This means we must keep the registry in memory */ + SEC_DESC *sec_desc; +} KEY_SEC_DESC; + +/* A map of sk offsets in the regf to KEY_SEC_DESCs for quick lookup etc */ +typedef struct sk_map_s { + int sk_off; + KEY_SEC_DESC *key_sec_desc; +} SK_MAP; + +typedef struct vk_struct { + WORD VK_ID; + WORD nam_len; + DWORD dat_len; /* If top-bit set, offset contains the data */ + DWORD dat_off; + DWORD dat_type; + WORD flag; /* =1, has name, else no name (=Default). */ + WORD unk1; + char dat_name[1]; /* Name starts here ... */ +} VK_HDR; + +typedef DWORD VL_TYPE[1]; /* Value list is an array of vk rec offsets */ + +typedef struct hash_struct { + DWORD nk_off; + char hash[4]; +} HASH_REC; + + +typedef struct lf_struct { + WORD LF_ID; + WORD key_count; + struct hash_struct hr[1]; /* Array of hash records, depending on key_count */} LF_HDR; + + + +/* + * This structure keeps track of the output format of the registry + */ +#define REG_OUTBLK_HDR 1 +#define REG_OUTBLK_HBIN 2 + +typedef struct hbin_blk_s { + int type, size; + struct hbin_blk_s *next; + char *data; /* The data block */ + unsigned int file_offset; /* Offset in file */ + unsigned int free_space; /* Amount of free space in block */ + unsigned int fsp_off; /* Start of free space in block */ + int complete, stored; +} HBIN_BLK; + +typedef struct regf_struct_s { + int reg_type; + int fd; + struct stat sbuf; + char *base; + int modified; + NTTIME last_mod_time; + NK_HDR *first_key; + int sk_count, sk_map_size; + SK_MAP *sk_map; + const char *owner_sid_str; + SEC_DESC *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 + */ + HBIN_BLK *blk_head, *blk_tail, *free_space; + TALLOC_CTX *mem_ctx; +} REGF; + +DWORD str_to_dword(const char *a) { + int i; + unsigned long ret = 0; + for(i = strlen(a)-1; i >= 0; i--) { + ret = ret * 0x100 + a[i]; + } + return ret; +} + +#if 0 + +/* + * Create an ACE + */ +static BOOL nt_create_ace(SEC_ACE *ace, int type, int flags, uint32 perms, const char *sid) +{ + DOM_SID s; + SEC_ACCESS access; + access.mask = perms; + if(!string_to_sid(&s, sid))return False; + init_sec_ace(ace, &s, type, access, flags); + return True; +} + +/* + * Create a default ACL + */ +static SEC_ACL *nt_create_default_acl(REG_HANDLE *regf) +{ + SEC_ACE aces[8]; + + if(!nt_create_ace(&aces[0], 0x00, 0x0, 0xF003F, regf->owner_sid_str)) return NULL; + if(!nt_create_ace(&aces[1], 0x00, 0x0, 0xF003F, "S-1-5-18")) return NULL; + if(!nt_create_ace(&aces[2], 0x00, 0x0, 0xF003F, "S-1-5-32-544")) return NULL; + if(!nt_create_ace(&aces[3], 0x00, 0x0, 0x20019, "S-1-5-12")) return NULL; + if(!nt_create_ace(&aces[4], 0x00, 0x0B, GENERIC_RIGHT_ALL_ACCESS, regf->owner_sid_str)) return NULL; + if(!nt_create_ace(&aces[5], 0x00, 0x0B, 0x10000000, "S-1-5-18")) return NULL; + if(!nt_create_ace(&aces[6], 0x00, 0x0B, 0x10000000, "S-1-5-32-544")) return NULL; + if(!nt_create_ace(&aces[7], 0x00, 0x0B, 0x80000000, "S-1-5-12")) return NULL; + + return make_sec_acl(regf->mem_ctx, 2, 8, aces); +} + +/* + * Create a default security descriptor. We pull in things from env + * if need be + */ +static SEC_DESC *nt_create_def_sec_desc(REG_HANDLE *regf) +{ + SEC_DESC *tmp; + + tmp = (SEC_DESC *)malloc(sizeof(SEC_DESC)); + + tmp->revision = 1; + tmp->type = SEC_DESC_SELF_RELATIVE | SEC_DESC_DACL_PRESENT; + if (!string_to_sid(tmp->owner_sid, "S-1-5-32-544")) goto error; + if (!string_to_sid(tmp->grp_sid, "S-1-5-18")) goto error; + tmp->sacl = NULL; + tmp->dacl = nt_create_default_acl(regf); + + return tmp; + + error: + if (tmp) nt_delete_sec_desc(tmp); + return NULL; +} + +/* + * We will implement inheritence that is based on what the parent's SEC_DESC + * says, but the Owner and Group SIDs can be overwridden from the command line + * and additional ACEs can be applied from the command line etc. + */ +static KEY_SEC_DESC *nt_inherit_security(REG_KEY *key) +{ + + if (!key) return NULL; + return key->security; +} + +/* + * Create an initial security descriptor and init other structures, if needed + * We assume that the initial security stuff is empty ... + */ +static KEY_SEC_DESC *nt_create_init_sec(REG_HANDLE *h) +{ + REGF *regf = h->backend_data; + KEY_SEC_DESC *tsec = NULL; + + tsec = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC)); + + tsec->ref_cnt = 1; + tsec->state = SEC_DESC_NBK; + tsec->offset = 0; + + tsec->sec_desc = regf->def_sec_desc; + + return tsec; +} +#endif + +/* + * Get the starting record for NT Registry file + */ + +/* + * Where we keep all the regf stuff for one registry. + * This is the structure that we use to tie the in memory tree etc + * together. By keeping separate structs, we can operate on different + * registries at the same time. + * Currently, the SK_MAP is an array of mapping structure. + * Since we only need this on input and output, we fill in the structure + * as we go on input. On output, we know how many SK items we have, so + * we can allocate the structure as we need to. + * If you add stuff here that is dynamically allocated, add the + * appropriate free statements below. + */ + +#define REG_HANDLE_REGTYPE_NONE 0 +#define REG_HANDLE_REGTYPE_NT 1 +#define REG_HANDLE_REGTYPE_W9X 2 + +#define TTTONTTIME(r, t1, t2) (r)->last_mod_time.low = (t1); \ + (r)->last_mod_time.high = (t2); + +#define REGF_HDR_BLKSIZ 0x1000 + +#define OFF(f) ((f) + REGF_HDR_BLKSIZ + 4) +#define LOCN(base, f) ((base) + OFF(f)) + +/* Get the header of the registry. Return a pointer to the structure + * If the mmap'd area has not been allocated, then mmap the input file + */ +static REGF_HDR *nt_get_regf_hdr(REG_HANDLE *h) +{ + REGF *regf = h->backend_data; + SMB_REG_ASSERT(regf); + + if (!regf->base) { /* Try to mmap etc the file */ + + if ((regf->fd = open(h->location, O_RDONLY, 0000)) <0) { + return NULL; /* What about errors? */ + } + + if (fstat(regf->fd, ®f->sbuf) < 0) { + return NULL; + } + + regf->base = mmap(0, regf->sbuf.st_size, PROT_READ, MAP_SHARED, regf->fd, 0); + + if ((int)regf->base == 1) { + DEBUG(0,("Could not mmap file: %s, %s\n", h->location, + strerror(errno))); + return NULL; + } + } + + /* + * At this point, regf->base != NULL, and we should be able to read the + * header + */ + + SMB_REG_ASSERT(regf->base != NULL); + + return (REGF_HDR *)regf->base; +} + +/* + * Validate a regf header + * For now, do nothing, but we should check the checksum + */ +static int valid_regf_hdr(REGF_HDR *regf_hdr) +{ + if (!regf_hdr) return 0; + + return 1; +} + +#if 0 + +/* + * Process an SK header ... + * Every time we see a new one, add it to the map. Otherwise, just look it up. + * We will do a simple linear search for the moment, since many KEYs have the + * same security descriptor. + * We allocate the map in increments of 10 entries. + */ + +/* + * Create a new entry in the map, and increase the size of the map if needed + */ +static SK_MAP *alloc_sk_map_entry(REG_HANDLE *h, KEY_SEC_DESC *tmp, int sk_off) +{ + REGF *regf = h->backend_data; + if (!regf->sk_map) { /* Allocate a block of 10 */ + regf->sk_map = (SK_MAP *)malloc(sizeof(SK_MAP) * 10); + regf->sk_map_size = 10; + regf->sk_count = 1; + (regf->sk_map)[0].sk_off = sk_off; + (regf->sk_map)[0].key_sec_desc = tmp; + } + else { /* Simply allocate a new slot, unless we have to expand the list */ + int ndx = regf->sk_count; + if (regf->sk_count >= regf->sk_map_size) { + regf->sk_map = (SK_MAP *)realloc(regf->sk_map, + (regf->sk_map_size + 10)*sizeof(SK_MAP)); + if (!regf->sk_map) { + free(tmp); + return NULL; + } + /* + * ndx already points at the first entry of the new block + */ + regf->sk_map_size += 10; + } + (regf->sk_map)[ndx].sk_off = sk_off; + (regf->sk_map)[ndx].key_sec_desc = tmp; + regf->sk_count++; + } + return regf->sk_map; +} + +/* + * Search for a KEY_SEC_DESC in the sk_map, but don't create one if not + * found + */ +KEY_SEC_DESC *lookup_sec_key(SK_MAP *sk_map, int count, int sk_off) +{ + int i; + + if (!sk_map) return NULL; + + for (i = 0; i < count; i++) { + + if (sk_map[i].sk_off == sk_off) + return sk_map[i].key_sec_desc; + + } + + return NULL; + +} + +/* + * Allocate a KEY_SEC_DESC if we can't find one in the map + */ +static KEY_SEC_DESC *lookup_create_sec_key(REG_HANDLE *h, SK_MAP *sk_map, int sk_off) +{ + REGF *regf = h->backend_data; + KEY_SEC_DESC *tmp = lookup_sec_key(regf->sk_map, regf->sk_count, sk_off); + + if (tmp) { + return tmp; + } + else { /* Allocate a new one */ + tmp = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC)); + memset(tmp, 0, sizeof(KEY_SEC_DESC)); /* Neatly sets offset to 0 */ + tmp->state = SEC_DESC_RES; + if (!alloc_sk_map_entry(h, tmp, sk_off)) { + return NULL; + } + return tmp; + } +} + +static SEC_DESC *process_sec_desc(REG_HANDLE *regf, SEC_DESC *sec_desc) +{ + SEC_DESC *tmp = NULL; + + tmp = (SEC_DESC *)malloc(sizeof(SEC_DESC)); + + tmp->revision = SVAL(&sec_desc->revision,0); + tmp->type = SVAL(&sec_desc->type,0); + DEBUG(2, ("SEC_DESC Rev: %0X, Type: %0X\n", tmp->revision, tmp->type)); + DEBUGADD(2, ("SEC_DESC Owner Off: %0X\n", IVAL(&sec_desc->off_owner_sid,0))); + DEBUGADD(2, ("SEC_DESC Group Off: %0X\n", IVAL(&sec_desc->off_grp_sid,0))); + DEBUGADD(2, ("SEC_DESC DACL Off: %0X\n", IVAL(&sec_desc->off_dacl,0))); + tmp->owner_sid = sid_dup_talloc(regf->mem_ctx, (DOM_SID *)((char *)sec_desc + IVAL(&sec_desc->off_owner_sid,0))); + if (!tmp->owner_sid) { + free(tmp); + return NULL; + } + tmp->grp_sid = sid_dup_talloc(regf->mem_ctx, (DOM_SID *)((char *)sec_desc + IVAL(&sec_desc->off_grp_sid,0))); + if (!tmp->grp_sid) { + free(tmp); + return NULL; + } + + /* Now pick up the SACL and DACL */ + + DEBUG(0, ("%d, %d\n", IVAL(&sec_desc->off_sacl,0), IVAL(&sec_desc->off_dacl,0))); + + if (sec_desc->off_sacl) + tmp->sacl = dup_sec_acl(regf->mem_ctx, (SEC_ACL *)((char *)sec_desc + IVAL(&sec_desc->off_sacl,0))); + else + tmp->sacl = NULL; + + if (sec_desc->off_dacl) + tmp->dacl = dup_sec_acl(regf->mem_ctx, (SEC_ACL *)((char *)sec_desc + IVAL(&sec_desc->off_dacl,0))); + else + tmp->dacl = NULL; + + return tmp; +} + +static KEY_SEC_DESC *process_sk(REG_HANDLE *regf, SK_HDR *sk_hdr, int sk_off, int size) +{ + KEY_SEC_DESC *tmp = NULL; + int sk_next_off, sk_prev_off, sk_size; + SEC_DESC *sec_desc; + + if (!sk_hdr) return NULL; + + if (SVAL(&sk_hdr->SK_ID,0) != str_to_dword("sk")) { + DEBUG(0, ("Unrecognized SK Header ID: %08X, %s\n", (int)sk_hdr, + regf->regfile_name)); + return NULL; + } + + if (-size < (sk_size = IVAL(&sk_hdr->rec_size,0))) { + DEBUG(0, ("Incorrect SK record size: %d vs %d. %s\n", + -size, sk_size, regf->regfile_name)); + return NULL; + } + + /* + * Now, we need to look up the SK Record in the map, and return it + * Since the map contains the SK_OFF mapped to KEY_SEC_DESC, we can + * use that + */ + + if (regf->sk_map && + ((tmp = lookup_sec_key(regf->sk_map, regf->sk_count, sk_off)) != NULL) + && (tmp->state == SEC_DESC_OCU)) { + tmp->ref_cnt++; + return tmp; + } + + /* Here, we have an item in the map that has been reserved, or tmp==NULL. */ + + SMB_REG_ASSERT(tmp == NULL || (tmp && tmp->state != SEC_DESC_NON)); + + /* + * Now, allocate a KEY_SEC_DESC, and parse the structure here, and add the + * new KEY_SEC_DESC to the mapping structure, since the offset supplied is + * the actual offset of structure. The same offset will be used by + * all future references to this structure + * We could put all this unpleasantness in a function. + */ + + if (!tmp) { + tmp = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC)); + memset(tmp, 0, sizeof(KEY_SEC_DESC)); + + /* + * Allocate an entry in the SK_MAP ... + * We don't need to free tmp, because that is done for us if the + * sm_map entry can't be expanded when we need more space in the map. + */ + + if (!alloc_sk_map_entry(regf, tmp, sk_off)) { + return NULL; + } + } + + tmp->ref_cnt++; + tmp->state = SEC_DESC_OCU; + + /* + * Now, process the actual sec desc and plug the values in + */ + + sec_desc = (SEC_DESC *)&sk_hdr->sec_desc[0]; + tmp->sec_desc = process_sec_desc(regf, sec_desc); + + /* + * Now forward and back links. Here we allocate an entry in the sk_map + * if it does not exist, and mark it reserved + */ + + sk_prev_off = IVAL(&sk_hdr->prev_off,0); + tmp->prev = lookup_create_sec_key(regf, regf->sk_map, sk_prev_off); + SMB_REG_ASSERT(tmp->prev != NULL); + sk_next_off = IVAL(&sk_hdr->next_off,0); + tmp->next = lookup_create_sec_key(regf, regf->sk_map, sk_next_off); + SMB_REG_ASSERT(tmp->next != NULL); + + return tmp; +} +#endif + +/* + * Process a VK header and return a value + */ +static REG_VAL *vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size) +{ + char val_name[1024]; + REGF *regf = parent->handle->backend_data; + int nam_len, dat_len, flag, dat_type, dat_off, vk_id; + const char *val_type; + REG_VAL *tmp = NULL; + + if (!vk_hdr) return NULL; + + if ((vk_id = SVAL(&vk_hdr->VK_ID,0)) != str_to_dword("vk")) { + DEBUG(0, ("Unrecognized VK header ID: %0X, block: %0X, %s\n", + vk_id, (int)vk_hdr, parent->handle->location)); + return NULL; + } + + nam_len = SVAL(&vk_hdr->nam_len,0); + val_name[nam_len] = '\0'; + flag = SVAL(&vk_hdr->flag,0); + dat_type = IVAL(&vk_hdr->dat_type,0); + dat_len = IVAL(&vk_hdr->dat_len,0); /* If top bit, offset contains data */ + dat_off = IVAL(&vk_hdr->dat_off,0); + + tmp = reg_val_new(parent, NULL); + tmp->has_name = flag; + tmp->data_type = dat_type; + + if (flag & 0x01) { + strncpy(val_name, vk_hdr->dat_name, nam_len); + tmp->name = strdup(val_name); + } + else + strncpy(val_name, "", 10); + + /* + * Allocate space and copy the data as a BLOB + */ + + if (dat_len&0x7FFFFFFF) { + + char *dtmp = (char *)malloc(dat_len&0x7FFFFFFF); + + tmp->data_blk = dtmp; + + if ((dat_len&0x80000000) == 0) { /* The data is pointed to by the offset */ + char *dat_ptr = LOCN(regf->base, dat_off); + memcpy(dtmp, dat_ptr, dat_len); + } + else { /* The data is in the offset or type */ + /* + * FIXME. + * Some registry files seem to have weird fields. If top bit is set, + * but len is 0, the type seems to be the value ... + * Not sure how to handle this last type for the moment ... + */ + dat_len = dat_len & 0x7FFFFFFF; + memcpy(dtmp, &dat_off, dat_len); + } + + tmp->data_len = dat_len; + } + + return tmp; +} + +static BOOL vl_verify(VL_TYPE vl, int count, int size) +{ + if(!vl) return False; + if (-size < (count+1)*sizeof(int)){ + DEBUG(0, ("Error in VL header format. Size less than space required. %d\n", -size)); + return False; + } + return True; +} + +static BOOL lf_verify(REG_HANDLE *h, LF_HDR *lf_hdr, int size) +{ + int lf_id; + if ((lf_id = SVAL(&lf_hdr->LF_ID,0)) != str_to_dword("lf")) { + DEBUG(0, ("Unrecognized LF Header format: %0X, Block: %0X, %s.\n", + lf_id, (int)lf_hdr, h->location)); + return False; + } + return True; +} + +static int lf_num_entries(REG_HANDLE *h, LF_HDR *lf_hdr, int size) +{ + int count; + + if(!lf_verify(h, lf_hdr, size)) return 0; + + SMB_REG_ASSERT(size < 0); + + count = SVAL(&lf_hdr->key_count,0); + DEBUG(2, ("Key Count: %u\n", count)); + if (count <= 0) return 0; + + return count; +} + + +static REG_KEY *nk_to_key(REG_HANDLE *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent); + + + +/* + * Process an LF Header and return a list of sub-keys + */ +static REG_KEY *lf_get_entry(REG_KEY *parent, LF_HDR *lf_hdr, int size, int n) +{ + REGF *regf = parent->handle->backend_data; + int count, nk_off; + NK_HDR *nk_hdr; + + if (!lf_hdr) return NULL; + + if(!lf_verify(parent->handle, lf_hdr, size)) return NULL; + + SMB_REG_ASSERT(size < 0); + + count = SVAL(&lf_hdr->key_count,0); + DEBUG(2, ("Key Count: %u\n", count)); + if (count <= 0 || n > count) return NULL; + + nk_off = IVAL(&lf_hdr->hr[n].nk_off,0); + DEBUG(2, ("NK Offset: %0X\n", nk_off)); + nk_hdr = (NK_HDR *)LOCN(regf->base, nk_off); + return nk_to_key(parent->handle, nk_hdr, BLK_SIZE(nk_hdr), parent); +} + +static REG_KEY *nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent) +{ + REGF *regf = h->backend_data; + REG_KEY *tmp = NULL, *own; + int name_len, clsname_len, sk_off, own_off; + unsigned int nk_id; + SK_HDR *sk_hdr; + int type; + char key_name[1024], cls_name[1024]; + + if (!nk_hdr) return NULL; + + if ((nk_id = SVAL(&nk_hdr->NK_ID,0)) != str_to_dword("nk")) { + DEBUG(0, ("Unrecognized NK Header format: %08X, Block: %0X. %s\n", + nk_id, (int)nk_hdr, parent->handle->location)); + return NULL; + } + + SMB_REG_ASSERT(size < 0); + + name_len = SVAL(&nk_hdr->nam_len,0); + clsname_len = SVAL(&nk_hdr->clsnam_len,0); + + /* + * The value of -size should be ge + * (sizeof(NK_HDR) - 1 + name_len) + * The -1 accounts for the fact that we included the first byte of + * the name in the structure. clsname_len is the length of the thing + * pointed to by clsnam_off + */ + + if (-size < (sizeof(NK_HDR) - 1 + name_len)) { + DEBUG(0, ("Incorrect NK_HDR size: %d, %0X\n", -size, (int)nk_hdr)); + DEBUG(0, ("Sizeof NK_HDR: %d, name_len %d, clsname_len %d\n", + sizeof(NK_HDR), name_len, clsname_len)); + /*return NULL;*/ + } + + DEBUG(2, ("NK HDR: Name len: %d, class name len: %d\n", name_len, clsname_len)); + + /* Fish out the key name and process the LF list */ + + SMB_REG_ASSERT(name_len < sizeof(key_name)); + + strncpy(key_name, nk_hdr->key_nam, name_len); + key_name[name_len] = '\0'; + + type = (SVAL(&nk_hdr->type,0)==0x2C?REG_ROOT_KEY:REG_SUB_KEY); + if(type == REG_ROOT_KEY && parent) { + DEBUG(0,("Root key encountered below root level!\n")); + return NULL; + } + + if(type == REG_ROOT_KEY) tmp = reg_key_new_abs(key_name, h, nk_hdr); + else tmp = reg_key_new_rel(key_name, parent, nk_hdr); + + DEBUG(2, ("Key name: %s\n", key_name)); + + /* + * Fish out the class name, it is in UNICODE, while the key name is + * ASCII :-) + */ + + if (clsname_len) { /* Just print in Ascii for now */ + smb_ucs2_t *clsnamep; + int clsnam_off; + + clsnam_off = IVAL(&nk_hdr->clsnam_off,0); + clsnamep = (smb_ucs2_t *)LOCN(regf->base, clsnam_off); + DEBUG(2, ("Class Name Offset: %0X\n", clsnam_off)); + + tmp->class_name = talloc_strdup_w(regf->mem_ctx, clsnamep); + + DEBUGADD(2,(" Class Name: %s\n", cls_name)); + + } + + /* + * Process the owner offset ... + */ + + own_off = IVAL(&nk_hdr->own_off,0); + own = (REG_KEY *)LOCN(regf->base, own_off); + DEBUG(2, ("Owner Offset: %0X\n", own_off)); + + DEBUGADD(2, (" Owner locn: %0X, Our locn: %0X\n", + (unsigned int)own, (unsigned int)nk_hdr)); + + /* + * We should verify that the owner field is correct ... + * for now, we don't worry ... + */ + + /* + * Also handle the SK header ... + */ + + sk_off = IVAL(&nk_hdr->sk_off,0); + sk_hdr = (SK_HDR *)LOCN(regf->base, sk_off); + DEBUG(2, ("SK Offset: %0X\n", sk_off)); + + if (sk_off != -1) { + +#if 0 + tmp->security = process_sk(regf, sk_hdr, sk_off, BLK_SIZE(sk_hdr)); +#endif + + } + + return tmp; +} + +/* + * Allocate a new hbin block, set up the header for the block etc + */ +static HBIN_BLK *nt_create_hbin_blk(REG_HANDLE *h, int size) +{ + REGF *regf = h->backend_data; + HBIN_BLK *tmp; + HBIN_HDR *hdr; + + if (!regf || !size) return NULL; + + /* Round size up to multiple of REGF_HDR_BLKSIZ */ + + size = (size + (REGF_HDR_BLKSIZ - 1)) & ~(REGF_HDR_BLKSIZ - 1); + + tmp = (HBIN_BLK *)malloc(sizeof(HBIN_BLK)); + memset(tmp, 0, sizeof(HBIN_BLK)); + + tmp->data = malloc(size); + + memset(tmp->data, 0, size); /* Make it pristine */ + + tmp->size = size; + /*FIXMEtmp->file_offset = regf->blk_tail->file_offset + regf->blk_tail->size;*/ + + tmp->free_space = size - (sizeof(HBIN_HDR) - sizeof(HBIN_SUB_HDR)); + tmp->fsp_off = size - tmp->free_space; + + /* + * Now, build the header in the data block + */ + hdr = (HBIN_HDR *)tmp->data; + hdr->HBIN_ID = str_to_dword("hbin"); + hdr->off_from_first = tmp->file_offset - REGF_HDR_BLKSIZ; + hdr->off_to_next = tmp->size; + hdr->blk_size = tmp->size; + + /* + * Now link it in + */ + + regf->blk_tail->next = tmp; + regf->blk_tail = tmp; + if (!regf->free_space) regf->free_space = tmp; + + return tmp; +} + +/* + * Allocate a unit of space ... and return a pointer as function param + * and the block's offset as a side effect + */ +static void *nt_alloc_regf_space(REG_HANDLE *h, int size, unsigned int *off) +{ + REGF *regf = h->backend_data; + int tmp = 0; + void *ret = NULL; + HBIN_BLK *blk; + + if (!regf || !size || !off) return NULL; + + SMB_REG_ASSERT(regf->blk_head != NULL); + + /* + * round up size to include header and then to 8-byte boundary + */ + size = (size + 4 + 7) & ~7; + + /* + * Check if there is space, if none, grab a block + */ + if (!regf->free_space) { + if (!nt_create_hbin_blk(h, REGF_HDR_BLKSIZ)) + return NULL; + } + + /* + * Now, chain down the list of blocks looking for free space + */ + + for (blk = regf->free_space; blk != NULL; blk = blk->next) { + if (blk->free_space <= size) { + tmp = blk->file_offset + blk->fsp_off - REGF_HDR_BLKSIZ; + ret = blk->data + blk->fsp_off; + blk->free_space -= size; + blk->fsp_off += size; + + /* Insert the header */ + ((HBIN_SUB_HDR *)ret)->dblocksize = -size; + + /* + * Fix up the free space ptr + * If it is NULL, we fix it up next time + */ + + if (!blk->free_space) + regf->free_space = blk->next; + + *off = tmp; + return (((char *)ret)+4);/* The pointer needs to be to the data struct */ + } + } + + /* + * If we got here, we need to add another block, which might be + * larger than one block -- deal with that later + */ + if (nt_create_hbin_blk(h, REGF_HDR_BLKSIZ)) { + blk = regf->free_space; + tmp = blk->file_offset + blk->fsp_off - REGF_HDR_BLKSIZ; + ret = blk->data + blk->fsp_off; + blk->free_space -= size; + blk->fsp_off += size; + + /* Insert the header */ + ((HBIN_SUB_HDR *)ret)->dblocksize = -size; + + /* + * Fix up the free space ptr + * If it is NULL, we fix it up next time + */ + + if (!blk->free_space) + regf->free_space = blk->next; + + *off = tmp; + return (((char *)ret) + 4);/* The pointer needs to be to the data struct */ + } + + return NULL; +} + +/* + * Store a SID at the location provided + */ +static int nt_store_SID(REG_HANDLE *regf, DOM_SID *sid, unsigned char *locn) +{ + int i; + unsigned char *p = locn; + + if (!regf || !sid || !locn) return 0; + + *p = sid->sid_rev_num; p++; + *p = sid->num_auths; p++; + + for (i=0; i < 6; i++) { + *p = sid->id_auth[i]; p++; + } + + for (i=0; i < sid->num_auths; i++) { + SIVAL(p, 0, sid->sub_auths[i]); p+=4; + } + + return p - locn; + +} + +static int nt_store_ace(REG_HANDLE *regf, SEC_ACE *ace, unsigned char *locn) +{ + int size = 0; + SEC_ACE *reg_ace = (SEC_ACE *)locn; + unsigned char *p; + + if (!regf || !ace || !locn) return 0; + + reg_ace->type = ace->type; + reg_ace->flags = ace->flags; + + /* Deal with the length when we have stored the SID */ + + p = (unsigned char *)®_ace->info.mask; + + SIVAL(p, 0, ace->info.mask); p += 4; + + size = nt_store_SID(regf, &ace->trustee, p); + + size += 8; /* Size of the fixed header */ + + p = (unsigned char *)®_ace->size; + + SSVAL(p, 0, size); + + return size; +} + +/* + * Store an ACL at the location provided + */ +static int nt_store_acl(REG_HANDLE *regf, SEC_ACL *acl, unsigned char *locn) { + int size = 0, i; + unsigned char *p = locn, *s; + + if (!regf || !acl || !locn) return 0; + + /* + * Now store the header and then the ACEs ... + */ + + SSVAL(p, 0, acl->revision); + + p += 2; s = p; /* Save this for the size field */ + + p += 2; + + SIVAL(p, 0, acl->num_aces); + + p += 4; + + for (i = 0; i < acl->num_aces; i++) { + size = nt_store_ace(regf, &acl->ace[i], p); + p += size; + } + + size = s - locn; + SSVAL(s, 0, size); + return size; +} + +/* + * Flatten and store the Sec Desc + * Windows lays out the DACL first, but since there is no SACL, it might be + * that first, then the owner, then the group SID. So, we do it that way + * too. + */ +static unsigned int nt_store_sec_desc(REG_HANDLE *regf, SEC_DESC *sd, char *locn) +{ + SEC_DESC *rsd = (SEC_DESC *)locn; + unsigned int size = 0, off = 0; + + if (!regf || !sd || !locn) return 0; + + /* + * Now, fill in the first two fields, then lay out the various fields + * as needed + */ + + rsd->revision = SEC_DESC_REVISION; + rsd->type = SEC_DESC_DACL_PRESENT | SEC_DESC_SELF_RELATIVE; + + off = 4 * sizeof(DWORD) + 4; + + if (sd->sacl){ + size = nt_store_acl(regf, sd->sacl, (char *)(locn + off)); + rsd->off_sacl = off; + } + else + rsd->off_sacl = 0; + + off += size; + + if (sd->dacl) { + rsd->off_dacl = off; + size = nt_store_acl(regf, sd->dacl, (char *)(locn + off)); + } + else { + rsd->off_dacl = 0; + } + + off += size; + + /* Now the owner and group SIDs */ + + if (sd->owner_sid) { + rsd->off_owner_sid = off; + size = nt_store_SID(regf, sd->owner_sid, (char *)(locn + off)); + } + else { + rsd->off_owner_sid = 0; + } + + off += size; + + if (sd->grp_sid) { + rsd->off_grp_sid = off; + size = nt_store_SID(regf, sd->grp_sid, (char *)(locn + off)); + } + else { + rsd->off_grp_sid = 0; + } + + off += size; + + return size; +} + +/* + * Store the security information + * + * If it has already been stored, just get its offset from record + * otherwise, store it and record its offset + */ +static unsigned int nt_store_security(REG_HANDLE *regf, KEY_SEC_DESC *sec) +{ + int size = 0; + unsigned int sk_off; + SK_HDR *sk_hdr; + + if (sec->offset) return sec->offset; + + /* + * OK, we don't have this one in the file yet. We must compute the + * size taken by the security descriptor as a self-relative SD, which + * means making one pass over each structure and figuring it out + */ + +//FIXME size = sec_desc_size(sec->sec_desc); + + /* Allocate that much space */ + + sk_hdr = nt_alloc_regf_space(regf, size, &sk_off); + sec->sk_hdr = sk_hdr; + + if (!sk_hdr) return 0; + + /* Now, lay out the sec_desc in the space provided */ + + sk_hdr->SK_ID = str_to_dword("sk"); + + /* + * We can't deal with the next and prev offset in the SK_HDRs until the + * whole tree has been stored, then we can go and deal with them + */ + + sk_hdr->ref_cnt = sec->ref_cnt; + sk_hdr->rec_size = size; /* Is this correct */ + + /* Now, lay out the sec_desc */ + + if (!nt_store_sec_desc(regf, sec->sec_desc, (char *)&sk_hdr->sec_desc)) + return 0; + + return sk_off; + +} + +#if 0 + +/* + * Store a KEY in the file ... + * + * We store this depth first, and defer storing the lf struct until + * all the sub-keys have been stored. + * + * We store the NK hdr, any SK header, class name, and VK structure, then + * recurse down the LF structures ... + * + * We return the offset of the NK struct + * FIXME, FIXME, FIXME: Convert to using SIVAL and SSVAL ... + */ +static int nt_store_reg_key(REG_HANDLE *regf, REG_KEY *key) +{ + NK_HDR *nk_hdr; + unsigned int nk_off, sk_off, size; + + if (!regf || !key) return 0; + + size = sizeof(NK_HDR) + strlen(key->name) - 1; + nk_hdr = nt_alloc_regf_space(regf, size, &nk_off); + if (!nk_hdr) goto error; + + key->offset = nk_off; /* We will need this later */ + + /* + * Now fill in each field etc ... + */ + + nk_hdr->NK_ID = str_to_dword("nk"); + if (key->type == REG_ROOT_KEY) + nk_hdr->type = 0x2C; + else + nk_hdr->type = 0x20; + + /* FIXME: Fill in the time of last update */ + + if (key->type != REG_ROOT_KEY) + nk_hdr->own_off = key->owner->offset; + + if (key->sub_keys) + nk_hdr->subk_num = key->sub_keys->key_count; + + /* + * Now, process the Sec Desc and then store its offset + */ + + sk_off = nt_store_security(regf, key->security); + nk_hdr->sk_off = sk_off; + + /* + * Then, store the val list and store its offset + */ + if (key->values) { + nk_hdr->val_cnt = key->values->val_count; + nk_hdr->val_off = nt_store_val_list(regf, key->values); + } + else { + nk_hdr->val_off = -1; + nk_hdr->val_cnt = 0; + } + + /* + * Finally, store the subkeys, and their offsets + */ + +error: + return 0; +} +#endif + +/* + * Store the registry header ... + * We actually create the registry header block and link it to the chain + * of output blocks. + */ +static REGF_HDR *nt_get_reg_header(REG_HANDLE *h) { + REGF *regf = h->backend_data; + HBIN_BLK *tmp = NULL; + + tmp = (HBIN_BLK *)malloc(sizeof(HBIN_BLK)); + + memset(tmp, 0, sizeof(HBIN_BLK)); + tmp->type = REG_OUTBLK_HDR; + tmp->size = REGF_HDR_BLKSIZ; + tmp->data = malloc(REGF_HDR_BLKSIZ); + if (!tmp->data) goto error; + + memset(tmp->data, 0, REGF_HDR_BLKSIZ); /* Make it pristine, unlike Windows */ + regf->blk_head = regf->blk_tail = tmp; + + return (REGF_HDR *)tmp->data; + +error: + if (tmp) free(tmp); + return NULL; +} + +static BOOL nt_close_registry (REG_HANDLE *h) +{ + REGF *regf = h->backend_data; + if (regf->base) munmap(regf->base, regf->sbuf.st_size); + regf->base = NULL; + close(regf->fd); /* Ignore the error :-) */ + + free(regf->sk_map); + regf->sk_count = regf->sk_map_size = 0; + + free(regf); + return False; +} + +static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load) +{ + REGF *regf = (REGF *)malloc(sizeof(REGF)); + REGF_HDR *regf_hdr; + unsigned int regf_id, hbin_id; + HBIN_HDR *hbin_hdr; + + memset(regf, 0, sizeof(REGF)); + regf->mem_ctx = talloc_init("regf"); + regf->owner_sid_str = def_owner_sid_str; + h->backend_data = regf; + + DEBUG(5, ("Attempting to load registry file\n")); + + /* Get the header */ + + if ((regf_hdr = nt_get_regf_hdr(h)) == NULL) { + DEBUG(0, ("Unable to get header\n")); + return False; + } + + /* Now process that header and start to read the rest in */ + + if ((regf_id = IVAL(®f_hdr->REGF_ID,0)) != str_to_dword("regf")) { + DEBUG(0, ("Unrecognized NT registry header id: %0X, %s\n", + regf_id, h->location)); + return False; + } + + /* + * Validate the header ... + */ + if (!valid_regf_hdr(regf_hdr)) { + DEBUG(0, ("Registry file header does not validate: %s\n", + h->location)); + return False; + } + + /* Update the last mod date, and then go get the first NK record and on */ + + TTTONTTIME(regf, IVAL(®f_hdr->tim1,0), IVAL(®f_hdr->tim2,0)); + + /* + * The hbin hdr seems to be just uninteresting garbage. Check that + * it is there, but that is all. + */ + + hbin_hdr = (HBIN_HDR *)(regf->base + REGF_HDR_BLKSIZ); + + if ((hbin_id = IVAL(&hbin_hdr->HBIN_ID,0)) != str_to_dword("hbin")) { + DEBUG(0, ("Unrecognized registry hbin hdr ID: %0X, %s\n", + hbin_id, h->location)); + return False; + } + + /* + * Get a pointer to the first key from the hreg_hdr + */ + + DEBUG(2, ("First Key: %0X\n", + IVAL(®f_hdr->first_key, 0))); + + regf->first_key = (NK_HDR *)LOCN(regf->base, IVAL(®f_hdr->first_key,0)); + DEBUGADD(2, ("First Key Offset: %0X\n", + IVAL(®f_hdr->first_key, 0))); + + DEBUGADD(2, ("Data Block Size: %d\n", + IVAL(®f_hdr->dblk_size, 0))); + + DEBUGADD(2, ("Offset to next hbin block: %0X\n", + IVAL(&hbin_hdr->off_to_next, 0))); + + DEBUGADD(2, ("HBIN block size: %0X\n", + IVAL(&hbin_hdr->blk_size, 0))); + + /* + * Unmap the registry file, as we might want to read in another + * tree etc. + */ + + h->backend_data = regf; + + return True; +} + +static REG_KEY *nt_get_root_key(REG_HANDLE *h) +{ + return nk_to_key(h, ((REGF *)h->backend_data)->first_key, BLK_SIZE(((REGF *)h->backend_data)->first_key), NULL); +} + +static int nt_num_subkeys(REG_KEY *k) +{ + REGF *regf = k->handle->backend_data; + LF_HDR *lf_hdr; + int lf_off; + NK_HDR *nk_hdr = k->backend_data; + lf_off = IVAL(&nk_hdr->lf_off,0); + DEBUG(2, ("SubKey list offset: %0X\n", lf_off)); + if(lf_off == -1) return 0; + lf_hdr = (LF_HDR *)LOCN(regf->base, lf_off); + + return lf_num_entries(k->handle, lf_hdr, BLK_SIZE(lf_hdr)); +} + +static int nt_num_values(REG_KEY *k) +{ + NK_HDR *nk_hdr = k->backend_data; + return IVAL(&nk_hdr->val_cnt,0); +} + +static REG_VAL *nt_value_by_index(REG_KEY *k, int n) +{ + VL_TYPE *vl; + int val_off, vk_off; + VK_HDR *vk_hdr; + REGF *regf = k->handle->backend_data; + NK_HDR *nk_hdr = k->backend_data; + val_off = IVAL(&nk_hdr->val_off,0); + vl = (VL_TYPE *)LOCN(regf->base, val_off); + DEBUG(2, ("Val List Offset: %0X\n", val_off)); + + vk_off = IVAL(&vl[n],0); + vk_hdr = (VK_HDR *)LOCN(regf->base, vk_off); + return vk_to_val(k, vk_hdr, BLK_SIZE(vk_hdr)); +} + +static REG_KEY *nt_key_by_index(REG_KEY *k, int n) +{ + REGF *regf = k->handle->backend_data; + int lf_off; + NK_HDR *nk_hdr = k->backend_data; + LF_HDR *lf_hdr; + lf_off = IVAL(&nk_hdr->lf_off,0); + DEBUG(2, ("SubKey list offset: %0X\n", lf_off)); + + /* + * No more subkeys if lf_off == -1 + */ + + if (lf_off != -1) { + lf_hdr = (LF_HDR *)LOCN(regf->base, lf_off); + return lf_get_entry(k, lf_hdr, BLK_SIZE(lf_hdr), n); + } + + return NULL; +} + +static REG_OPS reg_backend_nt4 = { + .name = "nt4", + .open_registry = nt_open_registry, + .close_registry = nt_close_registry, + .open_root_key = nt_get_root_key, + .num_subkeys = nt_num_subkeys, + .num_values = nt_num_values, + .get_subkey_by_index = nt_key_by_index, + .get_value_by_index = nt_value_by_index, + + /* TODO: + .add_key + .add_value + .del_key + .del_value + .update_value + */ +}; + +NTSTATUS reg_nt4_init(void) +{ + return register_backend("registry", ®_backend_nt4); +} diff --git a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c new file mode 100644 index 0000000000..7e8ad9bf48 --- /dev/null +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -0,0 +1,311 @@ +/* + Samba Unix/Linux SMB implementation + RPC backend for the registry library + Copyright (C) 2003-2004 Jelmer Vernooij, jelmer@samba.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "includes.h" +#include "lib/registry/common/registry.h" + +static void init_winreg_String(struct winreg_String *name, const char *s) +{ + name->name = s; + if (s) { + name->name_len = 2 * (strlen_m(s) + 1); + name->name_size = name->name_len; + } else { + name->name_len = 0; + name->name_size = 0; + } +} + + +#define openhive(u) static struct policy_handle *open_ ## u(struct dcerpc_pipe *p, REG_HANDLE *h) \ +{ \ + NTSTATUS status; \ + struct winreg_Open ## u r; \ + struct winreg_OpenUnknown unknown; \ + struct policy_handle *hnd = malloc(sizeof(struct policy_handle)); \ + TALLOC_CTX *mem_ctx = talloc_init("openhive"); \ + \ + unknown.unknown0 = 0x84e0; \ + unknown.unknown1 = 0x0000; \ + r.in.unknown = &unknown; \ + r.in.access_required = SEC_RIGHTS_MAXIMUM_ALLOWED; \ + r.out.handle = hnd;\ + \ + if (!NT_STATUS_IS_OK(dcerpc_winreg_Open ## u(p, mem_ctx, &r))) {\ + printf("Error executing open\n");\ + return NULL;\ + }\ +\ + talloc_destroy(mem_ctx);\ +\ + return hnd;\ +} + +openhive(HKLM) +openhive(HKCU) +openhive(HKPD) +openhive(HKU) +openhive(HKCR) + +struct rpc_data { + struct dcerpc_pipe *pipe; + struct policy_handle *hives[10]; +}; + +struct { + char *name; + struct policy_handle *(*open) (struct dcerpc_pipe *p, REG_HANDLE *h); +} known_hives[] = { +{ "HKEY_LOCAL_MACHINE", open_HKLM }, +{ "HKEY_CURRENT_USER", open_HKCU }, +{ "HKEY_CLASSES_ROOT", open_HKCR }, +{ "HKEY_PERFORMANCE_DATA", open_HKPD }, +{ "HKEY_USERS", open_HKU }, +{ NULL, NULL } +}; + +static BOOL rpc_open_registry(REG_HANDLE *h, const char *location, BOOL try_full) +{ + BOOL res = True; + struct rpc_data *mydata = malloc(sizeof(struct rpc_data)); + char *binding = strdup(location); + NTSTATUS status; + + ZERO_STRUCTP(mydata); + + status = dcerpc_pipe_connect(&mydata->pipe, binding, + DCERPC_WINREG_UUID, + DCERPC_WINREG_VERSION, + lp_workgroup(), + "jelwin", "dds"); + + if(!NT_STATUS_IS_OK(status)) return False; + + h->backend_data = mydata; + + return True; +} + +static REG_KEY *rpc_open_root(REG_HANDLE *h) +{ + /* There's not really a 'root' key here */ + return reg_key_new_abs("\\", h, h->backend_data); +} + +static BOOL rpc_close_registry(REG_HANDLE *h) +{ + dcerpc_pipe_close(((struct rpc_data *)h->backend_data)->pipe); + free(h->backend_data); + return True; +} + +static struct policy_handle *rpc_get_key_handle(REG_HANDLE *h, const char *path) +{ + char *hivename; + int i = 0; + struct rpc_data *mydata = h->backend_data; + struct policy_handle *hive = NULL; + char *end = strchr(path+1, '\\'); + NTSTATUS status; + struct winreg_OpenKey r; + struct policy_handle *key_handle = malloc(sizeof(struct policy_handle)); + TALLOC_CTX *mem_ctx; + + if(end) hivename = strndup(path+1, end-path-1); + else hivename = strdup(path+1); + + for(i = 0; known_hives[i].name; i++) { + if(!strcmp(hivename, known_hives[i].name)) { + if(!mydata->hives[i]) mydata->hives[i] = known_hives[i].open(mydata->pipe, h); + hive = mydata->hives[i]; + } + } + + if(!hive) { + DEBUG(0, ("No such hive: %s\n", hivename)); + return NULL; + } + + DEBUG(2, ("Opening %s, hive: %s\n", path, hivename)); + + if(!end || !(*end) || !(*(end+1))) return hive; + + memset(&r, 0, sizeof(struct winreg_OpenKey)); + r.in.handle = hive; + init_winreg_String(&r.in.keyname, end+1); + r.in.unknown = 0x00000000; + r.in.access_mask = 0x02000000; + r.out.handle = key_handle; + + mem_ctx = talloc_init("openkey"); + status = dcerpc_winreg_OpenKey(mydata->pipe, mem_ctx, &r); + talloc_destroy(mem_ctx); + + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { + return NULL; + } + + return key_handle; +} + +static REG_KEY *rpc_open_key(REG_HANDLE *h, const char *name) +{ + return reg_key_new_abs(name, h, rpc_get_key_handle(h, name)); +} + +static BOOL rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys) +{ + struct winreg_EnumKey r; + struct winreg_EnumKeyNameRequest keyname; + struct winreg_String classname; + struct winreg_Time tm; + struct rpc_data *mydata = parent->handle->backend_data; + int i; + REG_KEY **ar = malloc(sizeof(REG_KEY *)); + NTSTATUS status = NT_STATUS_OK; + TALLOC_CTX *mem_ctx; + + /* List the hives */ + if(parent->backend_data == parent->handle->backend_data) { + REG_KEY **ar = malloc(sizeof(REG_KEY *)); + for(i = 0; known_hives[i].name; i++) { + ar[i] = reg_key_new_rel(known_hives[i].name, parent, NULL); + (*count)++; + ar = realloc(ar, sizeof(REG_KEY *) * ((*count)+1)); + } + + *subkeys = 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; + + mem_ctx = talloc_init("enumkey"); + (*count) = 0; + r.in.handle = parent->backend_data; + keyname.unknown = 0x0000020a; + init_winreg_String(&keyname.key_name, NULL); + init_winreg_String(&classname, NULL); + r.in.in_name = &keyname; + r.in.class = &classname; + tm.low = tm.high = 0x7fffffff; + r.in.last_changed_time = &tm; + r.out.result.v = 0; + + for(i = 0; NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result); i++) { + r.in.enum_index = i; + r.in.unknown = r.out.unknown = 0x0414; + r.in.key_name_len = r.out.key_name_len = 0; + status = dcerpc_winreg_EnumKey(mydata->pipe, mem_ctx, &r); + if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { + ar[(*count)] = reg_key_new_rel(r.out.out_name->name, parent, NULL); + (*count)++; + ar = realloc(ar, ((*count)+1) * sizeof(REG_KEY *)); + } + } + + *subkeys = ar; + return True; +} + +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 rpc_data *mydata = parent->handle->backend_data; + TALLOC_CTX *mem_ctx; + uint32 type, requested_len, returned_len; + NTSTATUS status = NT_STATUS_OK; + REG_VAL **ar = malloc(sizeof(REG_VAL *)); + + (*count) = 0; + + if(!parent->backend_data) parent->backend_data = rpc_get_key_handle(parent->handle, reg_key_get_path(parent)); + + if(!parent->backend_data) return False; + + 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; + + type = 0; + r.in.type = r.out.type = &type; + value.max_len = 0x7fff; + value.offset = 0; + value.len = 0; + value.buffer = NULL; + + r.in.value = r.out.value = &value; + + requested_len = value.max_len; + r.in.requested_len = &requested_len; + returned_len = 0; + r.in.returned_len = &returned_len; + r.out.result.v = 0; + + mem_ctx = talloc_init("fetchvalues"); + while(1) { + status = dcerpc_winreg_EnumValue(mydata->pipe, mem_ctx, &r); + 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)]->data_type = *r.out.type; + ar[(*count)]->data_len = value.len; + ar[(*count)]->data_blk = malloc(value.len); + memcpy(ar[(*count)]->data_blk, value.buffer, value.len); + (*count)++; + ar = realloc(ar, ((*count)+1) * sizeof(REG_VAL *)); + } else break; + } + + talloc_destroy(mem_ctx); + + return True; +} + +static REG_OPS reg_backend_rpc = { + .name = "rpc", + .open_registry = rpc_open_registry, + .close_registry = rpc_close_registry, + .open_root_key = rpc_open_root, + .open_key = rpc_open_key, + .fetch_subkeys = rpc_fetch_subkeys, + .fetch_values = rpc_fetch_values, +}; + +NTSTATUS reg_rpc_init(void) +{ + return register_backend("registry", ®_backend_rpc); +} diff --git a/source4/lib/registry/reg_backend_wine/reg_backend_wine.c b/source4/lib/registry/reg_backend_wine/reg_backend_wine.c new file mode 100644 index 0000000000..6c8d7885cb --- /dev/null +++ b/source4/lib/registry/reg_backend_wine/reg_backend_wine.c @@ -0,0 +1,32 @@ +/* + Unix SMB/CIFS implementation. + Registry interface + Copyright (C) Jelmer Vernooij 2004. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "lib/registry/common/registry.h" + +static REG_OPS reg_backend_wine = { + .name = "wine", +}; + +NTSTATUS reg_wine_init(void) +{ + register_backend("registry", ®_backend_wine); + return NT_STATUS_OK; +} diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c new file mode 100644 index 0000000000..070516b798 --- /dev/null +++ b/source4/lib/registry/tools/regdiff.c @@ -0,0 +1,148 @@ +/* + Unix SMB/CIFS implementation. + simple registry frontend + + Copyright (C) Jelmer Vernooij 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) +{ + int i, numvals1, numvals2, numkeys2; + + 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)); + } + writediff(t2, t1, out); + } + + numvals2 = reg_key_num_values(newkey); + for(i = 0; i < numvals2; i++) { + REG_VAL *t1 = reg_key_get_value_by_index(newkey, i); + REG_VAL *t2 = reg_key_get_value_by_name(oldkey, reg_val_name(t1)); + if(!t2 || reg_val_size(t2) != reg_val_size(t1) || memcmp(reg_val_data_blk(t1), reg_val_data_blk(t2), reg_val_size(t1))) { + fprintf(out, "\"%s\"=%s:%s\n", reg_val_name(t1), str_regtype(reg_val_type(t1)), reg_val_data_string(t1)); + } + } + + numvals1 = reg_key_num_values(oldkey); + for(i = 0; i < numvals1; i++) { + REG_VAL *t1 = reg_key_get_value_by_index(oldkey, i); + if(!reg_key_get_value_by_name(newkey, reg_val_name(t1))) { + fprintf(out, "\"%s\"=-\n", reg_val_name(t1)); + } + } +} + +int main (int argc, char **argv) +{ + uint32 setparms, checkparms; + int opt; + poptContext pc; + REG_KEY *root; + const char *backend1 = NULL, *backend2 = NULL; + const char *location2; + char *outputfile = NULL; + FILE *fd = stdout; + REG_HANDLE *h2; + REG_KEY *root1 = NULL, *root2; + int from_null = 0; + int fullpath = 0, no_values = 0; + struct poptOption long_options[] = { + POPT_AUTOHELP + {"backend", 'b', POPT_ARG_STRING, NULL, 'b', "backend to use", NULL}, + {"output", 'o', POPT_ARG_STRING, &outputfile, 'o', "output file to use", NULL }, + {"null", 'n', POPT_ARG_NONE, &from_null, 'n', "Diff from NULL" }, + POPT_TABLEEND + }; + + pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); + + while((opt = poptGetNextOpt(pc)) != -1) { + switch(opt) { + case 'b': + if(!backend1 && !from_null) backend1 = poptGetOptArg(pc); + else if(!backend2) backend2 = poptGetOptArg(pc); + break; + } + } + setup_logging(argv[0], True); + + if(!from_null) { + REG_HANDLE *h1; + const char *location1; + location1 = poptGetArg(pc); + if(!location1) { + poptPrintUsage(pc, stderr, 0); + return 1; + } + + if(!backend1) backend1 = "dir"; + + h1 = reg_open(backend1, location1, True); + if(!h1) { + fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location1, backend1); + return 1; + } + + root1 = reg_get_root(h1); + } + + location2 = poptGetArg(pc); + if(!location2) { + poptPrintUsage(pc, stderr, 0); + return 2; + } + + if(!backend2) backend2 = "dir"; + + h2 = reg_open(backend2, location2, True); + if(!h2) { + fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location2, backend2); + return 1; + } + + root2 = reg_get_root(h2); + if(!root2) { + fprintf(stderr, "Can't open root key for '%s:%s'\n", backend2, location2); + return 1; + } + + poptFreeContext(pc); + + if(outputfile) { + fd = fopen(outputfile, "w+"); + if(!fd) { + fprintf(stderr, "Unable to open '%s'\n", outputfile); + return 1; + } + } + + fprintf(fd, "REGEDIT4\n\n"); + fprintf(fd, "; Generated using regdiff\n"); + + writediff(root1, root2, fd); + + fclose(fd); + + return 0; +} diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c new file mode 100644 index 0000000000..f76da7ebf9 --- /dev/null +++ b/source4/lib/registry/tools/regpatch.c @@ -0,0 +1,808 @@ +/* + Unix SMB/CIFS implementation. + simple registry frontend + + Copyright (C) 2002, Richard Sharpe, rsharpe@richardsharpe.com + Copyright (C) 2004, Jelmer Vernooij, jelmer@samba.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* + * Routines to parse a REGEDIT4 file + * + * The file consists of: + * + * REGEDIT4 + * \[[-]key-path\]\n + * * + * + * Format: + * [cmd:]name=type:value + * + * cmd = a|d|c|add|delete|change|as|ds|cs + * + * There can be more than one key-path and value-spec. + * + * Since we want to support more than one type of file format, we + * construct a command-file structure that keeps info about the command file + */ + +#define FMT_UNREC -1 +#define FMT_REGEDIT4 0 +#define FMT_EDITREG1_1 1 + +#define FMT_STRING_REGEDIT4 "REGEDIT4" +#define FMT_STRING_EDITREG1_0 "EDITREG1.0" + +#define CMD_NONE 0 +#define CMD_ADD_KEY 1 +#define CMD_DEL_KEY 2 + +#define CMD_KEY 1 +#define CMD_VAL 2 + +#include + +typedef struct val_spec_list { + struct val_spec_list *next; + char *name; + int type; + char *val; /* Kept as a char string, really? */ +} VAL_SPEC_LIST; + +typedef struct command_s { + int cmd; + char *key; + int val_count; + VAL_SPEC_LIST *val_spec_list, *val_spec_last; +} CMD; + +typedef struct cmd_line { + int len, line_len; + char *line; +} CMD_LINE; + +static void free_val_spec_list(VAL_SPEC_LIST *vl) +{ + if (!vl) return; + if (vl->name) free(vl->name); + if (vl->val) free(vl->val); + free(vl); + +} + +/* + * Some routines to handle lines of info in the command files + */ +static void skip_to_eol(int fd) +{ + int rc; + char ch = 0; + + while ((rc = read(fd, &ch, 1)) == 1) { + if (ch == 0x0A) return; + } + if (rc < 0) { + DEBUG(0, ("Could not read file descriptor: %d, %s\n", + fd, strerror(errno))); + exit(1); + } +} + +static void free_cmd(CMD *cmd) +{ + if (!cmd) return; + + while (cmd->val_spec_list) { + VAL_SPEC_LIST *tmp; + + tmp = cmd->val_spec_list; + cmd->val_spec_list = tmp->next; + free(tmp); + } + + free(cmd); + +} + +static void free_cmd_line(CMD_LINE *cmd_line) +{ + if (cmd_line) { + if (cmd_line->line) free(cmd_line->line); + free(cmd_line); + } +} + +static void print_line(struct cmd_line *cl) +{ + char *pl; + + if (!cl) return; + + pl = smb_xmalloc(cl->line_len + 1); + + strncpy(pl, cl->line, cl->line_len); + pl[cl->line_len] = 0; + + fprintf(stdout, "%s\n", pl); + free(pl); +} + +#define INIT_ALLOC 10 + +/* + * Read a line from the input file. + * NULL returned when EOF and no chars read + * Otherwise we return a cmd_line * + * Exit if other errors + */ +static struct cmd_line *get_cmd_line(int fd) +{ + struct cmd_line *cl = (CMD_LINE *)smb_xmalloc(sizeof(CMD_LINE)); + int i = 0, rc; + unsigned char ch; + + cl->len = INIT_ALLOC; + + /* + * Allocate some space for the line. We extend later if needed. + */ + + cl->line = (char *)smb_xmalloc(INIT_ALLOC); + + /* + * Now read in the chars to EOL. Don't store the EOL in the + * line. What about CR? + */ + + while ((rc = read(fd, &ch, 1)) == 1 && ch != '\n') { + if (ch == '\r') continue; /* skip CR */ + if (i == cl->len) { + /* + * Allocate some more memory + */ + if ((cl->line = realloc(cl->line, cl->len + INIT_ALLOC)) == NULL) { + DEBUG(0, ("Unable to realloc space for line: %s\n", + strerror(errno))); + exit(1); + } + cl->len += INIT_ALLOC; + } + cl->line[i] = ch; + i++; + } + + /* read 0 and we were at loc'n 0, return NULL */ + if (rc == 0 && i == 0) { + free_cmd_line(cl); + return NULL; + } + + cl->line_len = i; + + return cl; + +} + +/* + * parse_value: parse out a value. We pull it apart as: + * + * ::= =: + * + * ::= char-string-without-spaces | '"' char-string '"' + * + * If it parsed OK, return the as a string, and the + * value type and value-string in parameters. + * + * The value name can be empty. There can only be one empty name in + * a list of values. A value of - removes the value entirely. + */ + +static char *parse_name(char *nstr) +{ + int len = 0, start = 0; + if (!nstr) return NULL; + + len = strlen(nstr); + + while (len && nstr[len - 1] == ' ') len--; + + nstr[len] = 0; /* Trim any spaces ... if there were none, doesn't matter */ + + /* + * Beginning and end should be '"' or neither should be so + */ + if ((nstr[0] == '"' && nstr[len - 1] != '"') || + (nstr[0] != '"' && nstr[len - 1] == '"')) + return NULL; + + if (nstr[0] == '"') { + start = 1; + len -= 2; + } + + return strndup(&nstr[start], len); +} + +static int parse_value_type(char *tstr) +{ + int len = strlen(tstr); + + while (len && tstr[len - 1] == ' ') len--; + tstr[len] = 0; + + if (strcmp(tstr, "REG_DWORD") == 0) + return REG_DWORD; + else if (strcmp(tstr, "dword") == 0) + return REG_DWORD; + else if (strcmp(tstr, "REG_EXPAND_SZ") == 0) + return REG_EXPAND_SZ; + else if (strcmp(tstr, "REG_BIN") == 0) + return REG_BINARY; + else if (strcmp(tstr, "REG_SZ") == 0) + return REG_SZ; + else if (strcmp(tstr, "REG_MULTI_SZ") == 0) + return REG_MULTI_SZ; + else if (strcmp(tstr, "-") == 0) + return REG_DELETE; + + return 0; +} + +static char *parse_val_str(char *vstr) +{ + + return strndup(vstr, strlen(vstr)); + +} + +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; + + p1 = strndup(cl->line, cl->line_len); + /* FIXME: Better return codes etc ... */ + if (!p1) return NULL; + p2 = strchr(p1, '='); + if (!p2) return NULL; + + *p2 = 0; p2++; /* Split into two strings at p2 */ + + /* Now, parse the name ... */ + + nstr = parse_name(p1); + if (!nstr) goto error; + + /* Now, split the remainder and parse on type and val ... */ + + tstr = p2; + while (*tstr == ' ') tstr++; /* Skip leading white space */ + p2 = strchr(p2, ':'); + + if (p2) { + *p2 = 0; p2++; /* split on the : */ + } + + *vtype = parse_value_type(tstr); + + if (!vtype) goto error; + + if (!p2 || !*p2) return nstr; + + /* Now, parse the value string. It should return a newly malloc'd string */ + + while (*p2 == ' ') p2++; /* Skip leading space */ + vstr = parse_val_str(p2); + + if (!vstr) goto error; + + *val = vstr; + + return nstr; + + error: + if (p1) free(p1); + if (nstr) free(nstr); + if (vstr) free(vstr); + return NULL; +} + +/* + * Parse out a key. Look for a correctly formatted key [...] + * and whether it is a delete or add? A delete is signalled + * by a - in front of the key. + * Assumes that there are no leading and trailing spaces + */ + +static char *parse_key(struct cmd_line *cl, int *cmd) +{ + int start = 1; + char *tmp; + + if (cl->line[0] != '[' || + cl->line[cl->line_len - 1] != ']') return NULL; + if (cl->line_len == 2) return NULL; + *cmd = CMD_ADD_KEY; + if (cl->line[1] == '-') { + if (cl->line_len == 3) return NULL; + start = 2; + *cmd = CMD_DEL_KEY; + } + tmp = smb_xmalloc(cl->line_len - 1 - start + 1); + strncpy(tmp, &cl->line[start], cl->line_len - 1 - start); + tmp[cl->line_len - 1 - start] = 0; + return tmp; +} + +/* + * Parse a line to determine if we have a key or a value + * We only check for key or val ... + */ + +static int parse_line(struct cmd_line *cl) +{ + + if (!cl || cl->len == 0) return 0; + + if (cl->line[0] == '[') /* No further checking for now */ + return CMD_KEY; + else + return CMD_VAL; +} + +/* + * We seek to offset 0, read in the required number of bytes, + * and compare to the correct value. + * We then seek back to the original location + */ +static int regedit4_file_type(int fd) +{ + int cur_ofs = 0; + char desc[9]; + + 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))); + exit(1); /* FIXME */ + } + + if (cur_ofs) { + lseek(fd, 0, SEEK_SET); + } + + if (read(fd, desc, 8) < 8) { + DEBUG(0, ("Unable to read command file format\n")); + exit(2); /* FIXME */ + } + + desc[8] = 0; + + if (strcmp(desc, FMT_STRING_REGEDIT4) == 0) { + if (cur_ofs) { + lseek(fd, cur_ofs, SEEK_SET); + } + else { + skip_to_eol(fd); + } + return FMT_REGEDIT4; + } + + return FMT_UNREC; +} + +/* + * Run though the data in the line and strip anything after a comment + * char. + */ +static void strip_comment(struct cmd_line *cl) +{ + int i; + + if (!cl) return; + + for (i = 0; i < cl->line_len; i++) { + if (cl->line[i] == ';') { + 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] + * values* + * possibly Empty line + * + * value ::= =':' + * is some path, possibly enclosed in quotes ... + * We alctually look for the next key to terminate a previous key + * if == '-', then it is a delete type. + */ +static CMD *regedit4_get_cmd(int fd) +{ + struct command_s *cmd = NULL; + struct cmd_line *cl = NULL; + struct val_spec_list *vl = NULL; + + cmd = (struct command_s *)smb_xmalloc(sizeof(struct command_s)); + + cmd->cmd = CMD_NONE; + cmd->key = NULL; + cmd->val_count = 0; + cmd->val_spec_list = cmd->val_spec_last = NULL; + while ((cl = get_cmd_line(fd))) { + + /* + * If it is an empty command line, and we already have a key + * then exit from here ... FIXME: Clean up the parser + */ + + if (cl->line_len == 0 && cmd->key) { + free_cmd_line(cl); + break; + } + + strip_comment(cl); /* remove anything beyond a comment char */ + trim_trailing_spaces(cl); + trim_leading_spaces(cl); + + if (cl->line_len == 0) { /* An empty line */ + free_cmd_line(cl); + } + else { /* Else, non-empty ... */ + /* + * Parse out the bits ... + */ + switch (parse_line(cl)) { + case CMD_KEY: + if ((cmd->key = parse_key(cl, &cmd->cmd)) == NULL) { + DEBUG(0, ("Error parsing key from line: ")); + print_line(cl); + DEBUG(0, ("\n")); + } + break; + + case CMD_VAL: + /* + * We need to add the value stuff to the list + * There could be a \ on the end which we need to + * handle at some time + */ + vl = (struct val_spec_list *)smb_xmalloc(sizeof(struct val_spec_list)); + vl->next = NULL; + vl->val = NULL; + vl->name = parse_value(cl, &vl->type, &vl->val); + if (!vl->name) goto error; + if (cmd->val_spec_list == NULL) { + cmd->val_spec_list = cmd->val_spec_last = vl; + } + else { + cmd->val_spec_last->next = vl; + cmd->val_spec_last = vl; + } + cmd->val_count++; + break; + + default: + DEBUG(0, ("Unrecognized line in command file: \n")); + print_line(cl); + break; + } + } + + } + if (!cmd->cmd) goto error; /* End of file ... */ + + return cmd; + + error: + if (vl) free(vl); + if (cmd) free_cmd(cmd); + return NULL; +} + +static int regedit4_exec_cmd(CMD *cmd) +{ + + return 0; +} + +static int editreg_1_0_file_type(int fd) +{ + int cur_ofs = 0; + char desc[11]; + + 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))); + exit(1); /* FIXME */ + } + + if (cur_ofs) { + lseek(fd, 0, SEEK_SET); + } + + if (read(fd, desc, 10) < 10) { + DEBUG(0, ("Unable to read command file format\n")); + exit(2); /* FIXME */ + } + + desc[10] = 0; + + if (strcmp(desc, FMT_STRING_EDITREG1_0) == 0) { + lseek(fd, cur_ofs, SEEK_SET); + return FMT_REGEDIT4; + } + + return FMT_UNREC; +} + +static CMD *editreg_1_0_get_cmd(int fd) +{ + return NULL; +} + +static int editreg_1_0_exec_cmd(CMD *cmd) +{ + + return -1; +} + +typedef struct command_ops_s { + int type; + int (*file_type)(int fd); + CMD *(*get_cmd)(int fd); + int (*exec_cmd)(CMD *cmd); +} CMD_OPS; + +CMD_OPS default_cmd_ops[] = { + {0, regedit4_file_type, regedit4_get_cmd, regedit4_exec_cmd}, + {1, editreg_1_0_file_type, editreg_1_0_get_cmd, editreg_1_0_exec_cmd}, + {-1, NULL, NULL, NULL} +}; + +typedef struct command_file_s { + char *name; + int type, fd; + CMD_OPS cmd_ops; +} CMD_FILE; + +/* + * Create a new command file structure + */ + +static CMD_FILE *cmd_file_create(char *file) +{ + CMD_FILE *tmp; + struct stat sbuf; + int i = 0; + + /* + * Let's check if the file exists ... + * No use creating the cmd_file structure if the file does not exist + */ + + if (stat(file, &sbuf) < 0) { /* Not able to access file */ + + return NULL; + } + + tmp = (CMD_FILE *)smb_xmalloc(sizeof(CMD_FILE)); + + /* + * Let's fill in some of the fields; + */ + + tmp->name = strdup(file); + + if ((tmp->fd = open(file, O_RDONLY, 666)) < 0) { + free(tmp); + return NULL; + } + + /* + * Now, try to find the format by indexing through the table + */ + while (default_cmd_ops[i].type != -1) { + if ((tmp->type = default_cmd_ops[i].file_type(tmp->fd)) >= 0) { + tmp->cmd_ops = default_cmd_ops[i]; + return tmp; + } + i++; + } + + /* + * If we got here, return NULL, as we could not figure out the type + * of command file. + * + * What about errors? + */ + + free(tmp); + return NULL; +} + +/* + * Extract commands from the command file, and execute them. + * We pass a table of command callbacks for that + */ + +//FIXME + +/* + * Main code from here on ... + */ + +/* + * key print function here ... + */ + +/* + * Sec Desc print functions + */ + +char *str_type(unsigned char type); + +int nt_apply_reg_command_file(REG_HANDLE *regf, const char *cmd_file_name) +{ + CMD *cmd; + int modified = 0; + CMD_FILE *cmd_file = NULL; + cmd_file = cmd_file_create(cmd_file_name); + + while ((cmd = cmd_file->cmd_ops.get_cmd(cmd_file->fd)) != NULL) { + + /* + * Now, apply the requests to the tree ... + */ + 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; + } + + 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; + } + } + free_cmd(cmd); + + return modified; +} + +int main (int argc, char **argv) +{ + uint32 setparms, checkparms; + int opt; + poptContext pc; + REG_KEY *root; + const char *location; + const char *patch; + char *backend = "dir"; + REG_HANDLE *h; + int fullpath = 0, no_values = 0; + struct poptOption long_options[] = { + POPT_AUTOHELP + {"backend", 'b', POPT_ARG_STRING, &backend, 'b', "backend to use", NULL}, + POPT_TABLEEND + }; + + pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); + + while((opt = poptGetNextOpt(pc)) != -1) { + } + + setup_logging(argv[0], True); + + location = poptGetArg(pc); + if(!location) { + poptPrintUsage(pc, stderr, 0); + return 1; + } + + h = reg_open(backend, location, True); + if(!h) { + fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location, backend); + return 1; + } + + poptFreeContext(pc); + + patch = poptGetArg(pc); + if(!patch) patch = "/dev/stdin"; + + nt_apply_reg_command_file(h, patch); + + return 0; +} diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c new file mode 100644 index 0000000000..9074d1c716 --- /dev/null +++ b/source4/lib/registry/tools/regshell.c @@ -0,0 +1,243 @@ +/* + Unix SMB/CIFS implementation. + simple registry frontend + + Copyright (C) Jelmer Vernooij 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* + * ck/cd - change key + * ls - list values/keys + * rmval/rm - remove value + * rmkey/rmdir - remove key + * mkkey/mkdir - make key + * help + * exit + */ + +static REG_KEY *cmd_set(REG_KEY *cur, int argc, char **argv) +{ + /* FIXME */ + return NULL; +} + +static REG_KEY *cmd_ck(REG_KEY *cur, int argc, char **argv) +{ + REG_KEY *new; + if(argc < 2) { + new = cur; + } else { + new = reg_open_key(cur, argv[1]); + } + + if(!new) new = cur; + + printf("Current path is: %s\n", reg_key_get_path(new)); + + return new; +} + +static REG_KEY *cmd_ls(REG_KEY *cur, int argc, char **argv) +{ + int i, num; + num = reg_key_num_subkeys(cur); + for(i = 0; i < num; i++) { + REG_KEY *sub = reg_key_get_subkey_by_index(cur, i); + printf("K %s\n", reg_key_name(sub)); + } + + num = reg_key_num_values(cur); + for(i = 0; i < num; i++) { + REG_VAL *sub = reg_key_get_value_by_index(cur, i); + printf("V %s %s %s\n", reg_val_name(sub), str_regtype(reg_val_type(sub)), reg_val_data_string(sub)); + } + + return NULL; +} +static REG_KEY *cmd_mkkey(REG_KEY *cur, int argc, char **argv) +{ + if(argc < 2) { + fprintf(stderr, "Usage: mkkey \n"); + return NULL; + } + + if(!reg_key_add_name(cur, argv[1])) { + fprintf(stderr, "Error adding new subkey '%s'\n", argv[1]); + return NULL; + } + + fprintf(stderr, "Successfully added new subkey '%s' to '%s'\n", argv[1], reg_key_get_path(cur)); + + return NULL; +} + +static REG_KEY *cmd_rmkey(REG_KEY *cur, int argc, char **argv) +{ + REG_KEY *key; + if(argc < 2) { + fprintf(stderr, "Usage: rmkey \n"); + return NULL; + } + + key = reg_open_key(cur, argv[1]); + if(!key) { + fprintf(stderr, "No such subkey '%s'\n", argv[1]); + return NULL; + } + + if(!reg_key_del(key)) { + fprintf(stderr, "Error deleting '%s'\n", argv[1]); + } else { + fprintf(stderr, "Successfully deleted '%s'\n", argv[1]); + } + + return NULL; +} + +static REG_KEY *cmd_rmval(REG_KEY *cur, int argc, char **argv) +{ + REG_VAL *val; + if(argc < 2) { + fprintf(stderr, "Usage: rmval \n"); + return NULL; + } + + val = reg_key_get_value_by_name(cur, argv[1]); + if(!val) { + fprintf(stderr, "No such value '%s'\n", argv[1]); + return NULL; + } + + if(!reg_val_del(val)) { + fprintf(stderr, "Error deleting value '%s'\n", argv[1]); + } else { + fprintf(stderr, "Successfully deleted value '%s'\n", argv[1]); + } + + return NULL; +} + +static REG_KEY *cmd_exit(REG_KEY *cur, int argc, char **argv) +{ + exit(0); + return NULL; +} + +static REG_KEY *cmd_help(REG_KEY *, int, char **); + +struct { + const char *name; + const char *alias; + const char *help; + REG_KEY *(*handle)(REG_KEY *, int argc, char **argv); +} regshell_cmds[] = { + {"ck", "cd", "Change current key", cmd_ck }, + {"list", "ls", "List values/keys in current key", cmd_ls }, + {"mkkey", "mkdir", "Make new key", cmd_mkkey }, + {"rmval", "rm", "Remove value", cmd_rmval }, + {"rmkey", "rmdir", "Remove key", cmd_rmkey }, + {"set", "update", "Update value", cmd_set }, + {"help", "?", "Help", cmd_help }, + {"exit", "quit", "Exit", cmd_exit }, + {NULL } +}; + +static REG_KEY *cmd_help(REG_KEY *cur, int argc, char **argv) +{ + int i; + printf("Available commands:\n"); + for(i = 0; regshell_cmds[i].name; i++) { + printf("%s - %s\n", regshell_cmds[i].name, regshell_cmds[i].help); + } + return NULL; +} + +REG_KEY *process_cmd(REG_KEY *k, char *line) +{ + int argc; + char **argv = NULL; + int ret, i; + + if ((ret = poptParseArgvString(line, &argc, (const char ***) &argv)) != 0) { + fprintf(stderr, "regshell: %s\n", poptStrerror(ret)); + return k; + } + + 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(k, argc, argv); + } + } + + fprintf(stderr, "No such command '%s'\n", argv[0]); + + return k; +} + +int main (int argc, char **argv) +{ + uint32 setparms, checkparms; + int opt; + char *backend = "dir"; + REG_KEY *curkey = NULL;; + poptContext pc; + REG_HANDLE *h; + struct poptOption long_options[] = { + POPT_AUTOHELP + {"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL}, + POPT_TABLEEND + }; + + pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); + + while((opt = poptGetNextOpt(pc)) != -1) { + } + + h = reg_open(backend, poptPeekArg(pc), True); + if(!h) { + fprintf(stderr, "Unable to open '%s' with backend '%s'\n", poptGetArg(pc), backend); + return 1; + } + poptFreeContext(pc); + + setup_logging("regtree", True); + + curkey = reg_get_root(h); + + if(!curkey) return 1; + + while(True) { + char *line, *prompt; + + asprintf(&prompt, "%s> ", reg_key_get_path(curkey)); + + line = smb_readline(prompt, NULL, NULL); + + if(!line) + break; + + if(line[0] != '\n') { + REG_KEY *new = process_cmd(curkey, line); + if(new)curkey = new; + } + } + + return 0; +} diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c new file mode 100644 index 0000000000..80cbccf48f --- /dev/null +++ b/source4/lib/registry/tools/regtree.c @@ -0,0 +1,91 @@ +/* + Unix SMB/CIFS implementation. + simple registry frontend + + Copyright (C) Jelmer Vernooij 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +void print_tree(int l, REG_KEY *p, int fullpath, int novals) +{ + int num_subkeys, i, num_values; + + for(i = 0; i < l; i++) putchar(' '); + if(fullpath) printf("%s\n", reg_key_get_path(p)); + else printf("%s\n", reg_key_name(p)); + + num_subkeys = reg_key_num_subkeys(p); + for(i = 0; i < num_subkeys; i++) { + REG_KEY *subkey = reg_key_get_subkey_by_index(p, i); + print_tree(l+1, subkey, fullpath, novals); + reg_key_free(subkey); + } + + if(!novals) { + num_values = reg_key_num_values(p); + for(i = 0; i < num_values; i++) { + int j; + char *desc; + REG_VAL *value = reg_key_get_value_by_index(p, i); + for(j = 0; j < l+1; j++) putchar(' '); + desc = reg_val_description(value); + printf("%s\n", desc); + free(desc); + reg_val_free(value); + } + } +} + +int main (int argc, char **argv) +{ + uint32 setparms, checkparms; + int opt; + char *backend = "dir"; + poptContext pc; + REG_KEY *root; + REG_HANDLE *h; + int fullpath = 0, no_values = 0; + struct poptOption long_options[] = { + POPT_AUTOHELP + {"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL}, + {"fullpath", 'f', POPT_ARG_NONE, &fullpath, 0, "show full paths", NULL}, + {"no-values", 'V', POPT_ARG_NONE, &no_values, 0, "don't show values", NULL}, + POPT_TABLEEND + }; + + pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); + + while((opt = poptGetNextOpt(pc)) != -1) { + } + + setup_logging("regtree", True); + + h = reg_open(backend, poptPeekArg(pc), True); + if(!h) { + fprintf(stderr, "Unable to open '%s' with backend '%s'\n", poptGetArg(pc), backend); + return 1; + } + poptFreeContext(pc); + + root = reg_get_root(h); + if(!root) return 1; + + print_tree(0, root, fullpath, no_values); + + return 0; +} diff --git a/source4/lib/registry/winregistry.pc.in b/source4/lib/registry/winregistry.pc.in new file mode 100644 index 0000000000..ad134da236 --- /dev/null +++ b/source4/lib/registry/winregistry.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: winregistry +Description: Windows registry library +Version: @PACKAGE_VERSION@ +Libs: @LIBS@ @REG_LIBS@ -L${prefix}/lib -lwinregistry +Cflags: -I${includedir} @CFLAGS@ @CFLAGS@ -- cgit 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 ++++++++------------- 7 files changed, 168 insertions(+), 151 deletions(-) (limited to 'source4/lib/registry') 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; } -- cgit From 5c49a23a298d37462fc81b470ac35a3fb0ff631e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 5 Apr 2004 10:28:59 +0000 Subject: r36: - Start using memory pools in the registry library - Remove obsolete file (This used to be commit d85b8fb3b74b236fb03cf0931a0f585eec74536a) --- source4/lib/registry/common/reg_display.c | 60 ------------------- source4/lib/registry/common/reg_interface.c | 70 ++++++++++++---------- source4/lib/registry/common/reg_objects.c | 36 ++++++----- source4/lib/registry/common/reg_util.c | 9 ++- source4/lib/registry/common/registry.h | 3 + .../lib/registry/reg_backend_dir/reg_backend_dir.c | 28 ++++----- .../registry/reg_backend_gconf/reg_backend_gconf.c | 37 ++++++------ 7 files changed, 102 insertions(+), 141 deletions(-) delete mode 100644 source4/lib/registry/common/reg_display.c (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_display.c b/source4/lib/registry/common/reg_display.c deleted file mode 100644 index e12f4ba20e..0000000000 --- a/source4/lib/registry/common/reg_display.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Gerald Carter 2001 - Copyright (C) Tim Potter 2000 - Copyright (C) Jelmer Vernooij 2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -void display_reg_value(REG_VAL *value) -{ - pstring text; - - switch(reg_val_type(value)) { - case REG_DWORD: - printf("%s: REG_DWORD: 0x%08x\n", reg_val_name(value), - *((uint32 *) reg_val_data_blk(value))); - break; - case REG_SZ: - rpcstr_pull(text, reg_val_data_blk(value), sizeof(text), reg_val_size(value), - STR_TERMINATE); - printf("%s: REG_SZ: %s\n", reg_val_name(value), text); - break; - case REG_BINARY: - printf("%s: REG_BINARY: unknown length value not displayed\n", - reg_val_name(value)); - break; - case REG_MULTI_SZ: { - uint16 *curstr = (uint16 *) reg_val_data_blk(value); - uint8 *start = reg_val_data_blk(value); - printf("%s: REG_MULTI_SZ:\n", reg_val_name(value)); - while ((*curstr != 0) && - ((uint8 *) curstr < start + reg_val_size(value))) { - rpcstr_pull(text, curstr, sizeof(text), -1, - STR_TERMINATE); - printf(" %s\n", text); - curstr += strlen(text) + 1; - } - } - break; - default: - printf("%s: unknown type %d\n", reg_val_name(value), reg_val_type(value)); - } - -} diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index d40a855f89..b6b38e9b62 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -55,7 +55,6 @@ NTSTATUS registry_register(void *_function) return NT_STATUS_OK; } - /* Find a backend in the list of available backends */ static struct reg_init_function_entry *reg_find_backend_entry(const char *name) { @@ -74,6 +73,7 @@ REG_HANDLE *reg_open(const char *backend, const char *location, BOOL try_full_lo { struct reg_init_function_entry *entry; static BOOL reg_first_init = True; + TALLOC_CTX *mem_ctx; REG_HANDLE *ret; if(reg_first_init) { @@ -91,12 +91,14 @@ REG_HANDLE *reg_open(const char *backend, const char *location, BOOL try_full_lo DEBUG(0, ("No such registry backend '%s' loaded!\n", backend)); return NULL; } - - ret = malloc(sizeof(REG_HANDLE)); + + mem_ctx = talloc_init(backend); + ret = talloc(mem_ctx, sizeof(REG_HANDLE)); ZERO_STRUCTP(ret); - ret->location = location?strdup(location):NULL; + ret->location = location?talloc_strdup(mem_ctx, location):NULL; ret->functions = entry->functions; ret->backend_data = NULL; + ret->mem_ctx = mem_ctx; if(!entry->functions->open_registry) { return ret; @@ -105,15 +107,19 @@ REG_HANDLE *reg_open(const char *backend, const char *location, BOOL try_full_lo if(entry->functions->open_registry(ret, location, try_full_load)) return ret; - SAFE_FREE(ret); + talloc_destroy(mem_ctx); return NULL; } -/* Open a key */ +/* Open a key + * First tries to use the open_key function from the backend + * then falls back to get_subkey_by_name and later get_subkey_by_index + */ REG_KEY *reg_open_key(REG_KEY *parent, const char *name) { char *fullname; REG_KEY *ret = NULL; + TALLOC_CTX *mem_ctx; if(!parent) { DEBUG(0, ("Invalid parent key specified")); @@ -131,16 +137,23 @@ REG_KEY *reg_open_key(REG_KEY *parent, const char *name) while(curbegin && *curbegin) { if(curend)*curend = '\0'; curkey = reg_key_get_subkey_by_name(curkey, curbegin); - if(!curkey) return NULL; + if(!curkey) { + SAFE_FREE(orig); + return NULL; + } if(!curend) break; curbegin = curend + 1; curend = strchr(curbegin, '\\'); } + SAFE_FREE(orig); return curkey; } - asprintf(&fullname, "%s%s%s", parent->path, parent->path[strlen(parent->path)-1] == '\\'?"":"\\", name); + mem_ctx = talloc_init("mem_ctx"); + + fullname = talloc_asprintf(mem_ctx, "%s%s%s", parent->path, parent->path[strlen(parent->path)-1] == '\\'?"":"\\", name); + if(!parent->handle->functions->open_key) { DEBUG(0, ("Registry backend doesn't have get_subkey_by_name nor open_key!\n")); @@ -152,8 +165,10 @@ REG_KEY *reg_open_key(REG_KEY *parent, const char *name) if(ret) { ret->handle = parent->handle; ret->path = fullname; - } else - SAFE_FREE(fullname); + talloc_steal(mem_ctx, ret->mem_ctx, fullname); + } + + talloc_destroy(mem_ctx); return ret; } @@ -241,7 +256,7 @@ REG_KEY *reg_key_get_subkey_by_index(REG_KEY *key, int idx) } if(ret && !ret->path) { - asprintf(&ret->path, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name); + ret->path = talloc_asprintf(ret->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name); ret->handle = key->handle; } @@ -270,7 +285,7 @@ REG_KEY *reg_key_get_subkey_by_name(REG_KEY *key, const char *name) } if(ret && !ret->path) { - asprintf(&ret->path, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name); + ret->path = talloc_asprintf(ret->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name); ret->handle = key->handle; } @@ -310,7 +325,9 @@ BOOL reg_key_del(REG_KEY *key) { if(key->handle->functions->del_key) { if(key->handle->functions->del_key(key)) { - free_cached_keys(key); + /* Invalidate cache */ + key->cache_subkeys = NULL; + key->cache_subkeys_count = 0; return True; } } @@ -356,7 +373,8 @@ BOOL reg_val_del(REG_VAL *val) } if(val->handle->functions->del_value(val)) { - free_cached_values(val->parent); + val->parent->cache_values = NULL; + val->parent->cache_values_count = 0; return True; } return False; @@ -398,7 +416,8 @@ BOOL reg_key_add_name(REG_KEY *parent, const char *name) } if(parent->handle->functions->add_key(parent, name)) { - free_cached_keys(parent); + parent->cache_subkeys = NULL; + parent->cache_subkeys_count = 0; return True; } return False; @@ -419,7 +438,8 @@ 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); + val->parent->cache_values = NULL; + val->parent->cache_values_count = 0; return True; } @@ -447,7 +467,7 @@ REG_KEY *reg_get_root(REG_HANDLE *h) if(ret) { ret->handle = h; - ret->path = strdup("\\"); + ret->path = talloc_strdup(ret->mem_ctx, "\\"); } return ret; @@ -462,19 +482,9 @@ 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; + /* Invalidate the cache */ + 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; + return ret; } diff --git a/source4/lib/registry/common/reg_objects.c b/source4/lib/registry/common/reg_objects.c index 8de0065da0..809829b3e8 100644 --- a/source4/lib/registry/common/reg_objects.c +++ b/source4/lib/registry/common/reg_objects.c @@ -35,11 +35,12 @@ REG_VAL* reg_val_dup( REG_VAL *val ) { REG_VAL *copy = NULL; + TALLOC_CTX *new_mem_ctx = talloc_init(val->name); if ( !val ) return NULL; - if ( !(copy = malloc( sizeof(REG_VAL) )) ) { + if ( !(copy = talloc( new_mem_ctx, sizeof(REG_VAL) )) ) { DEBUG(0,("dup_registry_value: malloc() failed!\n")); return NULL; } @@ -49,12 +50,13 @@ REG_VAL* reg_val_dup( REG_VAL *val ) memcpy( copy, val, sizeof(REG_VAL) ); if ( val->data_blk ) { - if ( !(copy->data_blk = memdup( val->data_blk, val->data_len )) ) { + if ( !(copy->data_blk = talloc_memdup( new_mem_ctx, val->data_blk, val->data_len )) ) { DEBUG(0,("dup_registry_value: memdup() failed for [%d] bytes!\n", val->data_len)); SAFE_FREE( copy ); } } + copy->mem_ctx = new_mem_ctx; return copy; } @@ -71,8 +73,7 @@ void reg_val_free( REG_VAL *val ) if(val->handle->functions->free_val_backend_data) val->handle->functions->free_val_backend_data(val); - SAFE_FREE( val->data_blk ); - SAFE_FREE( val ); + talloc_destroy( val->mem_ctx ); return; } @@ -139,7 +140,6 @@ void reg_key_free(REG_KEY *key) for(i = 0; i < key->cache_values_count; i++) { reg_val_free(key->cache_values[i]); } - SAFE_FREE(key->cache_values); } if(key->cache_subkeys) { @@ -147,12 +147,9 @@ void reg_key_free(REG_KEY *key) for(i = 0; i < key->cache_subkeys_count; i++) { reg_key_free(key->cache_subkeys[i]); } - SAFE_FREE(key->cache_subkeys); } - SAFE_FREE(key->path); - SAFE_FREE(key->name); - SAFE_FREE(key); + talloc_destroy(key->mem_ctx); } char *reg_val_get_path(REG_VAL *v) @@ -170,11 +167,14 @@ const char *reg_key_get_path(REG_KEY *k) /* For use by the backends _ONLY_ */ REG_KEY *reg_key_new_abs(const char *path, REG_HANDLE *h, void *data) { - REG_KEY *r = malloc(sizeof(REG_KEY)); + REG_KEY *r; + TALLOC_CTX *mem_ctx = talloc_init(path); + r = talloc(mem_ctx, sizeof(REG_KEY)); ZERO_STRUCTP(r); r->handle = h; - r->path = strdup(path); - r->name = strdup(strrchr(path, '\\')?strrchr(path,'\\')+1:path); + r->mem_ctx = mem_ctx; + r->path = talloc_strdup(mem_ctx, path); + r->name = talloc_strdup(mem_ctx, strrchr(path, '\\')?strrchr(path,'\\')+1:path); r->backend_data = data; r->ref = 1; return r; @@ -182,19 +182,25 @@ REG_KEY *reg_key_new_abs(const char *path, REG_HANDLE *h, void *data) REG_KEY *reg_key_new_rel(const char *name, REG_KEY *k, void *data) { - REG_KEY *r = malloc(sizeof(REG_KEY)); + REG_KEY *r; + TALLOC_CTX *mem_ctx = talloc_init(name); + r = talloc(mem_ctx, sizeof(REG_KEY)); ZERO_STRUCTP(r); r->handle = k->handle; - r->name = strdup(name); + r->name = talloc_strdup(mem_ctx, name); r->backend_data = data; + r->mem_ctx = mem_ctx; r->ref = 1; return r; } REG_VAL *reg_val_new(REG_KEY *parent, void *data) { - REG_VAL *r = malloc(sizeof(REG_VAL)); + REG_VAL *r; + TALLOC_CTX *mem_ctx = talloc_init("value"); + r = talloc(mem_ctx, sizeof(REG_VAL)); ZERO_STRUCTP(r); + r->mem_ctx = mem_ctx; r->handle = parent->handle; r->backend_data = data; r->ref = 1; diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index 2941c38cf4..060d053fc2 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -82,7 +82,7 @@ char *reg_val_data_string(REG_VAL *v) return ret; } -const char *reg_val_description(REG_VAL *val) +char *reg_val_description(REG_VAL *val) { char *ret, *ds = reg_val_data_string(val); asprintf(&ret, "%s = %s : %s", reg_val_name(val)?reg_val_name(val):"", str_regtype(reg_val_type(val)), ds); @@ -145,6 +145,9 @@ BOOL reg_split_path( char *path, char **base, char **new_path ) return True; } +/** + * Replace all \'s with /'s + */ char *reg_path_win2unix(char *path) { int i; @@ -153,7 +156,9 @@ char *reg_path_win2unix(char *path) } return path; } - +/** + * Replace all /'s with \'s + */ char *reg_path_unix2win(char *path) { int i; diff --git a/source4/lib/registry/common/registry.h b/source4/lib/registry/common/registry.h index 4b29006217..3565a7a585 100644 --- a/source4/lib/registry/common/registry.h +++ b/source4/lib/registry/common/registry.h @@ -40,6 +40,7 @@ struct reg_key_s { int cache_values_count; REG_KEY **cache_subkeys; int cache_subkeys_count; + TALLOC_CTX *mem_ctx; int ref; }; @@ -52,6 +53,7 @@ struct reg_val_s { REG_HANDLE *handle; REG_KEY *parent; void *backend_data; + TALLOC_CTX *mem_ctx; int ref; }; @@ -107,6 +109,7 @@ struct reg_handle_s { REG_SUBTREE *subtrees; char *location; void *backend_data; + TALLOC_CTX *mem_ctx; }; struct reg_init_function_entry { 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 5fec782e95..9cb15cd285 100644 --- a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c @@ -28,7 +28,7 @@ static BOOL reg_dir_add_key(REG_KEY *parent, const char *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); + SAFE_FREE(path); return (ret == 0); } @@ -41,22 +41,26 @@ static REG_KEY *reg_dir_open_key(REG_HANDLE *h, const char *name) { DIR *d; char *fullpath; + REG_KEY *ret; + TALLOC_CTX *mem_ctx = talloc_init("tmp"); if(!name) { DEBUG(0, ("NULL pointer passed as directory name!")); return NULL; } - asprintf(&fullpath, "%s%s", h->location, name); + fullpath = talloc_asprintf(mem_ctx, "%s%s", h->location, name); fullpath = reg_path_win2unix(fullpath); d = opendir(fullpath); if(!d) { DEBUG(3,("Unable to open '%s': %s\n", fullpath, strerror(errno))); - SAFE_FREE(fullpath); + talloc_destroy(mem_ctx); return NULL; } closedir(d); - - return reg_key_new_abs(name, h, fullpath); + ret = reg_key_new_abs(name, h, fullpath); + talloc_steal(mem_ctx, ret->mem_ctx, fullpath); + talloc_destroy(mem_ctx); + return ret; } static BOOL reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r) @@ -67,7 +71,7 @@ static BOOL reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r) REG_KEY **ar; DIR *d; (*count) = 0; - ar = malloc(sizeof(REG_KEY *) * max); + ar = talloc(k->mem_ctx, sizeof(REG_KEY *) * max); d = opendir(fullpath); @@ -78,8 +82,8 @@ static BOOL reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r) strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) { char *newfullpath; - asprintf(&newfullpath, "%s/%s", fullpath, e->d_name); - ar[(*count)] = reg_key_new_rel(e->d_name, k, newfullpath); + ar[(*count)] = reg_key_new_rel(e->d_name, k, NULL); + ar[(*count)]->backend_data = talloc_asprintf(ar[*count]->mem_ctx, "%s/%s", fullpath, e->d_name); if(ar[(*count)])(*count)++; if((*count) == max) { @@ -100,17 +104,12 @@ static BOOL reg_dir_open(REG_HANDLE *h, const char *loc, BOOL try) { return True; } -static void dir_free(REG_KEY *k) -{ - free(k->backend_data); -} - static REG_VAL *reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len) { REG_VAL *ret = reg_val_new(p, NULL); char *fullpath; FILE *fd; - ret->name = name?strdup(name):NULL; + ret->name = name?talloc_strdup(ret->mem_ctx, name):NULL; fullpath = reg_path_win2unix(strdup(reg_val_get_path(ret))); fd = fopen(fullpath, "w+"); @@ -134,7 +133,6 @@ static REG_OPS reg_backend_dir = { .del_key = reg_dir_del_key, .add_value = reg_dir_add_value, .del_value = reg_dir_del_value, - .free_key_backend_data = dir_free }; NTSTATUS reg_dir_init(void) diff --git a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c index 14da2f54e9..71d3361ce2 100644 --- a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c +++ b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c @@ -35,34 +35,35 @@ static BOOL reg_close_gconf(REG_HANDLE *h) static REG_KEY *gconf_open_key (REG_HANDLE *h, const char *name) { + REG_KEY *ret; char *fullpath = reg_path_win2unix(strdup(name)); /* Check if key exists */ if(!gconf_client_dir_exists((GConfClient *)h->backend_data, fullpath, NULL)) { - free(fullpath); + SAFE_FREE(fullpath); return NULL; } - free(fullpath); + ret = reg_key_new_abs(name, h, NULL); + ret->backend_data = talloc_strdup(ret->mem_ctx, fullpath); + SAFE_FREE(fullpath); - return reg_key_new_abs(name, h, NULL); + return ret; } static BOOL gconf_fetch_values(REG_KEY *p, int *count, REG_VAL ***vals) { GSList *entries; GSList *cur; - REG_VAL **ar = malloc(sizeof(REG_VAL *)); - char *fullpath = strdup(reg_key_get_path(p)); - fullpath = reg_path_win2unix(fullpath); + REG_VAL **ar = talloc(p->mem_ctx, sizeof(REG_VAL *)); + char *fullpath = p->backend_data; cur = entries = gconf_client_all_entries((GConfClient*)p->handle->backend_data, fullpath, NULL); - free(fullpath); (*count) = 0; while(cur) { GConfEntry *entry = cur->data; GConfValue *value = gconf_entry_get_value(entry); REG_VAL *newval = reg_val_new(p, NULL); - newval->name = strdup(strrchr(gconf_entry_get_key(entry), '/')+1); + newval->name = talloc_strdup(newval->mem_ctx, strrchr(gconf_entry_get_key(entry), '/')+1); if(value) { switch(value->type) { case GCONF_VALUE_INVALID: @@ -71,26 +72,26 @@ static BOOL gconf_fetch_values(REG_KEY *p, int *count, REG_VAL ***vals) case GCONF_VALUE_STRING: newval->data_type = REG_SZ; - newval->data_blk = strdup(gconf_value_get_string(value)); + newval->data_blk = talloc_strdup(newval->mem_ctx, gconf_value_get_string(value)); newval->data_len = strlen(newval->data_blk); break; case GCONF_VALUE_INT: newval->data_type = REG_DWORD; - newval->data_blk = malloc(sizeof(long)); + newval->data_blk = talloc(newval->mem_ctx, sizeof(long)); *((long *)newval->data_blk) = gconf_value_get_int(value); newval->data_len = sizeof(long); break; case GCONF_VALUE_FLOAT: - newval->data_blk = malloc(sizeof(double)); + newval->data_blk = talloc(newval->mem_ctx, sizeof(double)); newval->data_type = REG_BINARY; *((double *)newval->data_blk) = gconf_value_get_float(value); newval->data_len = sizeof(double); break; case GCONF_VALUE_BOOL: - newval->data_blk = malloc(sizeof(BOOL)); + newval->data_blk = talloc(newval->mem_ctx, sizeof(BOOL)); newval->data_type = REG_BINARY; *((BOOL *)newval->data_blk) = gconf_value_get_bool(value); newval->data_len = sizeof(BOOL); @@ -104,7 +105,7 @@ static BOOL gconf_fetch_values(REG_KEY *p, int *count, REG_VAL ***vals) } else newval->data_type = REG_NONE; ar[(*count)] = newval; - ar = realloc(ar, sizeof(REG_VAL *) * ((*count)+2)); + ar = talloc_realloc(p->mem_ctx, ar, sizeof(REG_VAL *) * ((*count)+2)); (*count)++; g_free(cur->data); cur = cur->next; @@ -120,14 +121,13 @@ static BOOL gconf_fetch_subkeys(REG_KEY *p, int *count, REG_KEY ***subs) GSList *dirs; GSList *cur; REG_KEY **ar = malloc(sizeof(REG_KEY *)); - char *fullpath = strdup(reg_key_get_path(p)); - fullpath = reg_path_win2unix(fullpath); + char *fullpath = p->backend_data; cur = dirs = gconf_client_all_dirs((GConfClient*)p->handle->backend_data, fullpath,NULL); - free(fullpath); (*count) = 0; while(cur) { - ar[(*count)] = reg_key_new_abs(reg_path_unix2win((char *)cur->data), p->handle, NULL); + ar[(*count)] = reg_key_new_abs(reg_path_unix2win((char *)cur->data), p->handle,NULL); + ar[(*count)]->backend_data = talloc_strdup(ar[*count]->mem_ctx, cur->data); ar = realloc(ar, sizeof(REG_KEY *) * ((*count)+2)); (*count)++; g_free(cur->data); @@ -142,11 +142,10 @@ static BOOL gconf_fetch_subkeys(REG_KEY *p, int *count, REG_KEY ***subs) static BOOL gconf_update_value(REG_VAL *val, int type, void *data, int len) { GError *error = NULL; - char *keypath = reg_path_win2unix(strdup(reg_key_get_path(val->parent))); + char *keypath = val->backend_data; char *valpath; if(val->name)asprintf(&valpath, "%s/%s", keypath, val->name); else valpath = strdup(keypath); - free(keypath); switch(type) { case REG_SZ: -- cgit From 2542ed0ac75d545eef3571bfb19fb39a5b71beb3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 5 Apr 2004 13:50:45 +0000 Subject: r46: Add CreateKey function (still working on it) (This used to be commit 9f13b7c60cc7e6edd095eee96625ee02cd0dd73b) --- .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 44 ++++++++++++---------- 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'source4/lib/registry') 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 796d957076..84c3cb8aee 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -39,7 +39,6 @@ static void init_winreg_String(struct winreg_String *name, const char *s) struct winreg_Open ## u r; \ struct winreg_OpenUnknown unknown; \ struct policy_handle *hnd = malloc(sizeof(struct policy_handle)); \ - TALLOC_CTX *mem_ctx = talloc_init("openhive"); \ \ unknown.unknown0 = 0x84e0; \ unknown.unknown1 = 0x0000; \ @@ -47,12 +46,10 @@ static void init_winreg_String(struct winreg_String *name, const char *s) r.in.access_required = SEC_RIGHTS_MAXIMUM_ALLOWED; \ r.out.handle = hnd;\ \ - if (!NT_STATUS_IS_OK(dcerpc_winreg_Open ## u(p, mem_ctx, &r))) {\ + if (!NT_STATUS_IS_OK(dcerpc_winreg_Open ## u(p, h->mem_ctx, &r))) {\ printf("Error executing open\n");\ return NULL;\ }\ -\ - talloc_destroy(mem_ctx);\ \ return hnd;\ } @@ -83,7 +80,7 @@ struct { static BOOL rpc_open_registry(REG_HANDLE *h, const char *location, BOOL try_full) { BOOL res = True; - struct rpc_data *mydata = malloc(sizeof(struct rpc_data)); + struct rpc_data *mydata = talloc(h->mem_ctx, sizeof(struct rpc_data)); char *binding = strdup(location); NTSTATUS status; @@ -124,7 +121,7 @@ static struct policy_handle *rpc_get_key_handle(REG_HANDLE *h, const char *path) char *end = strchr(path+1, '\\'); NTSTATUS status; struct winreg_OpenKey r; - struct policy_handle *key_handle = malloc(sizeof(struct policy_handle)); + struct policy_handle *key_handle = talloc(h->mem_ctx, sizeof(struct policy_handle)); TALLOC_CTX *mem_ctx; if(end) hivename = strndup(path+1, end-path-1); @@ -177,17 +174,16 @@ static BOOL rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys) struct winreg_Time tm; struct rpc_data *mydata = parent->handle->backend_data; int i; - REG_KEY **ar = malloc(sizeof(REG_KEY *)); + REG_KEY **ar = talloc(parent->mem_ctx, sizeof(REG_KEY *)); NTSTATUS status = NT_STATUS_OK; TALLOC_CTX *mem_ctx; /* List the hives */ if(parent->backend_data == parent->handle->backend_data) { - REG_KEY **ar = malloc(sizeof(REG_KEY *)); for(i = 0; known_hives[i].name; i++) { ar[i] = reg_key_new_rel(known_hives[i].name, parent, NULL); (*count)++; - ar = realloc(ar, sizeof(REG_KEY *) * ((*count)+1)); + ar = talloc_realloc(parent->mem_ctx, ar, sizeof(REG_KEY *) * ((*count)+1)); } *subkeys = ar; @@ -199,7 +195,6 @@ static BOOL rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys) if(!parent->backend_data) return False; - mem_ctx = talloc_init("enumkey"); (*count) = 0; r.in.handle = parent->backend_data; keyname.unknown = 0x0000020a; @@ -215,11 +210,11 @@ static BOOL rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys) r.in.enum_index = i; r.in.unknown = r.out.unknown = 0x0414; r.in.key_name_len = r.out.key_name_len = 0; - status = dcerpc_winreg_EnumKey(mydata->pipe, mem_ctx, &r); + status = dcerpc_winreg_EnumKey(mydata->pipe, parent->mem_ctx, &r); if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { ar[(*count)] = reg_key_new_rel(r.out.out_name->name, parent, NULL); (*count)++; - ar = realloc(ar, ((*count)+1) * sizeof(REG_KEY *)); + ar = talloc_realloc(parent->mem_ctx, ar, ((*count)+1) * sizeof(REG_KEY *)); } } @@ -271,29 +266,38 @@ static BOOL rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values) r.in.returned_len = &returned_len; r.out.result.v = 0; - mem_ctx = talloc_init("fetchvalues"); while(1) { - status = dcerpc_winreg_EnumValue(mydata->pipe, mem_ctx, &r); + status = dcerpc_winreg_EnumValue(mydata->pipe, parent->mem_ctx, &r); 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(r.out.name->name); + ar[(*count)]->name = talloc_strdup(ar[*count]->mem_ctx, r.out.name->name); ar[(*count)]->data_type = *r.out.type; ar[(*count)]->data_len = value.len; - ar[(*count)]->data_blk = malloc(value.len); + ar[(*count)]->data_blk = talloc(ar[*count]->mem_ctx, value.len); memcpy(ar[(*count)]->data_blk, value.buffer, value.len); (*count)++; - ar = realloc(ar, ((*count)+1) * sizeof(REG_VAL *)); + ar = talloc_realloc(parent->mem_ctx, ar, ((*count)+1) * sizeof(REG_VAL *)); } else break; } - talloc_destroy(mem_ctx); - *values = ar; return True; } +static BOOL rpc_add_key(REG_KEY *parent, const char *name) +{ + /* FIXME */ + return False; +} + +static BOOL rpc_del_key(REG_KEY *k) +{ + /* FIXME */ + return False; +} + static REG_OPS reg_backend_rpc = { .name = "rpc", .open_registry = rpc_open_registry, @@ -302,6 +306,8 @@ static REG_OPS reg_backend_rpc = { .open_key = rpc_open_key, .fetch_subkeys = rpc_fetch_subkeys, .fetch_values = rpc_fetch_values, + .add_key = rpc_add_key, + .del_key = rpc_del_key, }; NTSTATUS reg_rpc_init(void) -- cgit From b96025eb15e3648e77e0e6aa343e23ca2f1156da Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 5 Apr 2004 20:44:33 +0000 Subject: r61: - Implement first call in the winreg rpc server - Add some initial implementation of the ldb backend - More checks in the winreg torture test (This used to be commit ae2b63b6f1821bc4f693cb8e2a5f78718c483c24) --- .../lib/registry/reg_backend_ldb/reg_backend_ldb.c | 19 ++++++++++++++++++- .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index 75d5a95187..afa60c5c4a 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -43,9 +43,25 @@ static BOOL ldb_close_registry(REG_HANDLE *h) return True; } +static BOOL ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys) +{ + ldb_search(); +} + static REG_KEY *ldb_open_key(REG_HANDLE *h, const char *name) { - /* FIXME */ + struct ldb_context *c = h->backend_data; + char *path; + struct ldb_message **msg; + REG_KEY *key = NULL; + (dn=key=Systems, + if(ldb_search(c, NULL, LDP_SCOPE_BASE, "", NULL,&msg) > 0) { + key = reg_key_new_abs(name, h, base); + } + + ldap_search_free(c, msg); + + return key; } static REG_OPS reg_backend_ldb = { @@ -53,6 +69,7 @@ static REG_OPS reg_backend_ldb = { .open_registry = ldb_open_registry, .close_registry = ldb_close_registry, .open_key = ldb_open_key, + .fetch_subkeys = ldb_fetch_subkeys, }; NTSTATUS reg_ldb_init(void) 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 84c3cb8aee..ad4d537f9b 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -90,7 +90,7 @@ static BOOL rpc_open_registry(REG_HANDLE *h, const char *location, BOOL try_full DCERPC_WINREG_UUID, DCERPC_WINREG_VERSION, lp_workgroup(), - "jelwin", "dds"); + "tridge", "samba"); if(!NT_STATUS_IS_OK(status)) return False; -- cgit From 509bbf4383f2aad2f2b86b021430ef5a2df935c2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Apr 2004 17:42:03 +0000 Subject: r125: use AC_CONFIG_FILES() instead of AC_OUTPUT() we should have only one AC_OUTPUT() at the end of configure.in metze (This used to be commit 60aa14d463fcd7aa12529f1fad0db64f17e37aaf) --- source4/lib/registry/config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index 277fd30dd1..146ef92b95 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -13,4 +13,4 @@ SMB_MODULE(reg_dir, REG, STATIC, lib/registry/reg_backend_dir/reg_backend_dir.o) SMB_MODULE(reg_rpc, REG, STATIC, lib/registry/reg_backend_rpc/reg_backend_rpc.o) SMB_MODULE(reg_gconf, REG, NOT, lib/registry/reg_backend_gconf/reg_backend_gconf.o, [], [$GCONF_LIBS]) SMB_SUBSYSTEM(REG,lib/registry/common/reg_interface.o,[lib/registry/common/reg_objects.o lib/registry/common/reg_util.o],lib/registry/common/winregistry_proto.h,[]) -AC_OUTPUT(lib/registry/winregistry.pc) +AC_CONFIG_FILES(lib/registry/winregistry.pc) -- cgit From aebfb3b9f415d3c1f6b2a39aee27b072d48893cb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 8 Apr 2004 22:39:47 +0000 Subject: r128: Another registry update. Changes: - Start with the LDB backend - The API is now more windows-like, which should make it easier to use in rpc_server - Added a GTK+ front-end - Added some more IDL More updates will follow, especially in the RPC field.. (This used to be commit 3adffa021779b26047a20f16a3c0b53d74751560) --- source4/lib/registry/TODO | 18 +- source4/lib/registry/common/reg_interface.c | 368 +++++----- source4/lib/registry/common/reg_util.c | 22 +- source4/lib/registry/common/registry.h | 55 +- source4/lib/registry/config.m4 | 3 + .../lib/registry/reg_backend_dir/reg_backend_dir.c | 46 +- .../registry/reg_backend_gconf/reg_backend_gconf.c | 54 +- .../lib/registry/reg_backend_ldb/reg_backend_ldb.c | 75 +- .../lib/registry/reg_backend_nt4/reg_backend_nt4.c | 106 +-- .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 85 ++- .../registry/reg_backend_wine/reg_backend_wine.c | 1 + source4/lib/registry/tools/gregedit.c | 758 +++++++++++++++++++++ source4/lib/registry/tools/regshell.c | 1 + 13 files changed, 1266 insertions(+), 326 deletions(-) create mode 100644 source4/lib/registry/tools/gregedit.c (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/TODO b/source4/lib/registry/TODO index ac467d0078..fc741cea40 100644 --- a/source4/lib/registry/TODO +++ b/source4/lib/registry/TODO @@ -1,10 +1,6 @@ - support subtrees -- ../../, /bla/blie support in regshell -- use memory pools? -- get rid of all the nasty memory leaks.. -- security stuff -- clean up code -- rpc_server +- ..\..\, \bla\blie support in regshell +- finish rpc_server reg_backend_dir: - value support @@ -15,9 +11,15 @@ reg_backend_nt4: reg_backend_rpc: - value enum support - write support + - rewrite reg_backend_ldb: - - implement + - finish reg_backend_wine.c: - - implement + - finish + +gregedit.c: + - support for editing values / adding values / deleting values + - support for adding/deleting keys + - support for security descriptors diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index b6b38e9b62..9c78ae55fb 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -32,7 +32,7 @@ static struct reg_init_function_entry *reg_find_backend_entry(const char *name); /* Register new backend */ NTSTATUS registry_register(void *_function) { - REG_OPS *functions = _function; + struct registry_ops *functions = _function; struct reg_init_function_entry *entry = backends; if (!functions || !functions->name) { @@ -69,17 +69,19 @@ static struct reg_init_function_entry *reg_find_backend_entry(const char *name) } /* Open a registry file/host/etc */ -REG_HANDLE *reg_open(const char *backend, const char *location, BOOL try_full_load) +WERROR reg_open(const char *backend, const char *location, const char *credentials, REG_HANDLE **h) { struct reg_init_function_entry *entry; static BOOL reg_first_init = True; TALLOC_CTX *mem_ctx; REG_HANDLE *ret; + NTSTATUS status; + WERROR werr; if(reg_first_init) { - if (!NT_STATUS_IS_OK(register_subsystem("registry", registry_register))) { - return False; - } + status = register_subsystem("registry", registry_register); + if (!NT_STATUS_IS_OK(status)) + return WERR_GENERAL_FAILURE; static_init_reg; reg_first_init = False; @@ -89,7 +91,7 @@ REG_HANDLE *reg_open(const char *backend, const char *location, BOOL try_full_lo if (!entry) { DEBUG(0, ("No such registry backend '%s' loaded!\n", backend)); - return NULL; + return WERR_GENERAL_FAILURE; } mem_ctx = talloc_init(backend); @@ -99,31 +101,35 @@ REG_HANDLE *reg_open(const char *backend, const char *location, BOOL try_full_lo ret->functions = entry->functions; ret->backend_data = NULL; ret->mem_ctx = mem_ctx; + *h = ret; if(!entry->functions->open_registry) { - return ret; + return WERR_OK; } - if(entry->functions->open_registry(ret, location, try_full_load)) - return ret; + werr = entry->functions->open_registry(ret, location, credentials); + + if(W_ERROR_IS_OK(werr)) + return WERR_OK; talloc_destroy(mem_ctx); - return NULL; + return werr; } /* Open a key * First tries to use the open_key function from the backend * then falls back to get_subkey_by_name and later get_subkey_by_index */ -REG_KEY *reg_open_key(REG_KEY *parent, const char *name) +WERROR reg_open_key(REG_KEY *parent, const char *name, REG_KEY **result) { char *fullname; + WERROR status; REG_KEY *ret = NULL; TALLOC_CTX *mem_ctx; if(!parent) { DEBUG(0, ("Invalid parent key specified")); - return NULL; + return WERR_INVALID_PARAM; } if(!parent->handle->functions->open_key && @@ -136,10 +142,10 @@ REG_KEY *reg_open_key(REG_KEY *parent, const char *name) while(curbegin && *curbegin) { if(curend)*curend = '\0'; - curkey = reg_key_get_subkey_by_name(curkey, curbegin); - if(!curkey) { + status = reg_key_get_subkey_by_name(curkey, curbegin, result); + if(!NT_STATUS_IS_OK(status)) { SAFE_FREE(orig); - return NULL; + return status; } if(!curend) break; curbegin = curend + 1; @@ -147,255 +153,287 @@ REG_KEY *reg_open_key(REG_KEY *parent, const char *name) } SAFE_FREE(orig); - return curkey; + *result = curkey; + return WERR_OK; } mem_ctx = talloc_init("mem_ctx"); fullname = talloc_asprintf(mem_ctx, "%s%s%s", parent->path, parent->path[strlen(parent->path)-1] == '\\'?"":"\\", name); - +\ if(!parent->handle->functions->open_key) { DEBUG(0, ("Registry backend doesn't have get_subkey_by_name nor open_key!\n")); - return NULL; + return WERR_NOT_SUPPORTED; } - ret = parent->handle->functions->open_key(parent->handle, fullname); + status = parent->handle->functions->open_key(parent->handle, fullname, result); - if(ret) { - ret->handle = parent->handle; - ret->path = fullname; - talloc_steal(mem_ctx, ret->mem_ctx, fullname); + if(!NT_STATUS_IS_OK(status)) { + talloc_destroy(mem_ctx); + return status; } + + ret->handle = parent->handle; + ret->path = fullname; + talloc_steal(mem_ctx, ret->mem_ctx, fullname); talloc_destroy(mem_ctx); - return ret; + *result = ret; + + return WERR_OK; } -REG_VAL *reg_key_get_value_by_index(REG_KEY *key, int idx) +WERROR reg_key_get_value_by_index(REG_KEY *key, int idx, REG_VAL **val) { - REG_VAL *ret; - - if(!key) return NULL; + if(!key) return WERR_INVALID_PARAM; if(!key->handle->functions->get_value_by_index) { if(!key->cache_values) key->handle->functions->fetch_values(key, &key->cache_values_count, &key->cache_values); if(idx < key->cache_values_count && idx >= 0) { - ret = reg_val_dup(key->cache_values[idx]); + *val = reg_val_dup(key->cache_values[idx]); } else { - return NULL; + return WERR_NO_MORE_ITEMS; } } else { - ret = key->handle->functions->get_value_by_index(key, idx); + WERROR status = key->handle->functions->get_value_by_index(key, idx, val); + if(!W_ERROR_IS_OK(status)) + return status; } - if(ret) { - ret->parent = key; - ret->handle = key->handle; - } - - return ret; + (*val)->parent = key; + (*val)->handle = key->handle; + return WERR_OK; } -int reg_key_num_subkeys(REG_KEY *key) +WERROR reg_key_num_subkeys(REG_KEY *key, int *count) { - if(!key) return 0; + if(!key) return WERR_INVALID_PARAM; if(!key->handle->functions->num_subkeys) { if(!key->cache_subkeys) key->handle->functions->fetch_subkeys(key, &key->cache_subkeys_count, &key->cache_subkeys); - return key->cache_subkeys_count; + *count = key->cache_subkeys_count; + return WERR_OK; } - return key->handle->functions->num_subkeys(key); + return key->handle->functions->num_subkeys(key, count); } -int reg_key_num_values(REG_KEY *key) +WERROR reg_key_num_values(REG_KEY *key, int *count) { - if(!key) return 0; + if(!key) return WERR_INVALID_PARAM; if(!key->handle->functions->num_values) { if(!key->handle->functions->fetch_values) { DEBUG(1, ("Backend '%s' doesn't support enumerating values\n", key->handle->functions->name)); - return 0; + return WERR_NOT_SUPPORTED; } if(!key->cache_values) key->handle->functions->fetch_values(key, &key->cache_values_count, &key->cache_values); - return key->cache_values_count; + *count = key->cache_values_count; + return WERR_OK; } - return key->handle->functions->num_values(key); + return key->handle->functions->num_values(key, count); } -REG_KEY *reg_key_get_subkey_by_index(REG_KEY *key, int idx) +WERROR reg_key_get_subkey_by_index(REG_KEY *key, int idx, REG_KEY **subkey) { - REG_KEY *ret = NULL; - - if(!key) return NULL; + if(!key) return WERR_INVALID_PARAM; if(!key->handle->functions->get_subkey_by_index) { if(!key->cache_subkeys) key->handle->functions->fetch_subkeys(key, &key->cache_subkeys_count, &key->cache_subkeys); if(idx < key->cache_subkeys_count) { - ret = reg_key_dup(key->cache_subkeys[idx]); + *subkey = reg_key_dup(key->cache_subkeys[idx]); } else { - /* No such key ! */ - return NULL; + return WERR_NO_MORE_ITEMS; } } else { - ret = key->handle->functions->get_subkey_by_index(key, idx); + WERROR status = key->handle->functions->get_subkey_by_index(key, idx, subkey); + if(!NT_STATUS_IS_OK(status)) return status; } - if(ret && !ret->path) { - ret->path = talloc_asprintf(ret->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name); - ret->handle = key->handle; - } + (*subkey)->path = talloc_asprintf((*subkey)->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", (*subkey)->name); + (*subkey)->handle = key->handle; - return ret; + + return WERR_OK;; } -REG_KEY *reg_key_get_subkey_by_name(REG_KEY *key, const char *name) +WERROR reg_key_get_subkey_by_name(REG_KEY *key, const char *name, REG_KEY **subkey) { - int i, max; + int i; REG_KEY *ret = NULL; + WERROR error = WERR_OK; - if(!key) return NULL; + if(!key) return WERR_INVALID_PARAM; if(key->handle->functions->get_subkey_by_name) { - ret = key->handle->functions->get_subkey_by_name(key,name); + error = key->handle->functions->get_subkey_by_name(key,name,subkey); } else { - max = reg_key_num_subkeys(key); - for(i = 0; i < max; i++) { - REG_KEY *v = reg_key_get_subkey_by_index(key, i); - if(v && !strcmp(v->name, name)) { - ret = v; + for(i = 0; W_ERROR_IS_OK(error); i++) { + error = reg_key_get_subkey_by_index(key, i, subkey); + if(W_ERROR_IS_OK(error) && !strcmp((*subkey)->name, name)) { break; } - reg_key_free(v); + reg_key_free(*subkey); } - } - if(ret && !ret->path) { - ret->path = talloc_asprintf(ret->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name); - ret->handle = key->handle; } + + if(!W_ERROR_IS_OK(error) && W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) + return error; + + ret->path = talloc_asprintf(ret->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name); + ret->handle = key->handle; + + *subkey = ret; - return ret; + return WERR_OK; } -REG_VAL *reg_key_get_value_by_name(REG_KEY *key, const char *name) +WERROR reg_key_get_value_by_name(REG_KEY *key, const char *name, REG_VAL **val) { int i, max; REG_VAL *ret = NULL; + WERROR error = WERR_OK; - if(!key) return NULL; + if(!key) return WERR_INVALID_PARAM; if(key->handle->functions->get_value_by_name) { - ret = key->handle->functions->get_value_by_name(key,name); + error = key->handle->functions->get_value_by_name(key,name, val); } else { - max = reg_key_num_values(key); - for(i = 0; i < max; i++) { - REG_VAL *v = reg_key_get_value_by_index(key, i); - if(v && StrCaseCmp(v->name, name)) { - ret = v; + for(i = 0; W_ERROR_IS_OK(error); i++) { + error = reg_key_get_value_by_index(key, i, val); + if(W_ERROR_IS_OK(error) && StrCaseCmp((*val)->name, name)) { break; } - reg_val_free(v); + reg_val_free(*val); } } + + if(!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) + return error; - if(ret) { - ret->parent = key; - ret->handle = key->handle; - } + (*val)->parent = key; + (*val)->handle = key->handle; - return ret; + return WERR_OK; } -BOOL reg_key_del(REG_KEY *key) +WERROR reg_key_del(REG_KEY *key) { - if(key->handle->functions->del_key) { - if(key->handle->functions->del_key(key)) { - /* Invalidate cache */ - key->cache_subkeys = NULL; - key->cache_subkeys_count = 0; - return True; - } - } + WERROR error; + if(!key) return WERR_INVALID_PARAM; + + + if(!key->handle->functions->del_key) + return WERR_NOT_SUPPORTED; + + error = key->handle->functions->del_key(key); + if(!W_ERROR_IS_OK(error)) return error; - return False; + /* Invalidate cache */ + key->cache_subkeys = NULL; + key->cache_subkeys_count = 0; + return WERR_OK; } -BOOL reg_sync(REG_HANDLE *h, const char *location) +WERROR reg_sync(REG_KEY *h, const char *location) { - if(!h->functions->sync) - return True; + if(!h->handle->functions->sync_key) + return WERR_OK; - return h->functions->sync(h, location); + return h->handle->functions->sync_key(h, location); } -BOOL reg_key_del_recursive(REG_KEY *key) +WERROR reg_key_del_recursive(REG_KEY *key) { BOOL succeed = True; + WERROR error = WERR_OK; int i; /* Delete all values for specified key */ - for(i = 0; i < reg_key_num_values(key); i++) { - if(!reg_val_del(reg_key_get_value_by_index(key, i))) - succeed = False; + for(i = 0; W_ERROR_IS_OK(error); i++) { + REG_VAL *val; + error = reg_key_get_value_by_index(key, i, &val); + if(!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) + return error; + + if(W_ERROR_IS_OK(error)) { + error = reg_val_del(val); + if(!W_ERROR_IS_OK(error)) return error; + } } + error = WERR_OK; + /* Delete all keys below this one */ - for(i = 0; i < reg_key_num_subkeys(key); i++) { - if(!reg_key_del_recursive(reg_key_get_subkey_by_index(key, i))) - succeed = False; - } + for(i = 0; W_ERROR_IS_OK(error); i++) { + REG_KEY *subkey; + + error = reg_key_get_subkey_by_index(key, i, &subkey); + if(!W_ERROR_IS_OK(error)) return error; - if(succeed)reg_key_del(key); + error = reg_key_del_recursive(subkey); + if(!W_ERROR_IS_OK(error)) return error; + } - return succeed; + return reg_key_del(key); } -BOOL reg_val_del(REG_VAL *val) +WERROR reg_val_del(REG_VAL *val) { + WERROR error; + if (!val) return WERR_INVALID_PARAM; + if (!val->handle->functions->del_value) { DEBUG(1, ("Backend '%s' doesn't support method del_value\n", val->handle->functions->name)); - return False; + return WERR_NOT_SUPPORTED; } - if(val->handle->functions->del_value(val)) { - val->parent->cache_values = NULL; - val->parent->cache_values_count = 0; - return True; - } - return False; + error = val->handle->functions->del_value(val); + + if(!W_ERROR_IS_OK(error)) return error; + + val->parent->cache_values = NULL; + val->parent->cache_values_count = 0; + + return WERR_OK; } -BOOL reg_key_add_name_recursive(REG_KEY *parent, const char *path) +WERROR reg_key_add_name_recursive(REG_KEY *parent, const char *path) { REG_KEY *cur, *prevcur = parent; + WERROR error; 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; - } + + error = reg_key_get_subkey_by_name(prevcur, begin, &cur); + + /* Key is not there, add it */ + if(W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) { + error = reg_key_add_name(prevcur, begin, 0, NULL, &cur); + if(!W_ERROR_IS_OK(error)) return error; + } + + if(!W_ERROR_IS_OK(error)) { + if(end) *end = '\\'; + return error; } if(!end) break; @@ -403,28 +441,36 @@ BOOL reg_key_add_name_recursive(REG_KEY *parent, const char *path) begin = end+1; prevcur = cur; } - return True; + return WERR_OK; } -BOOL reg_key_add_name(REG_KEY *parent, const char *name) +WERROR reg_key_add_name(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *desc, REG_KEY **newkey) { - if (!parent) return False; + WERROR error; + + if (!parent) return WERR_INVALID_PARAM; if (!parent->handle->functions->add_key) { DEBUG(1, ("Backend '%s' doesn't support method add_key\n", parent->handle->functions->name)); - return False; + return WERR_NOT_SUPPORTED; } - if(parent->handle->functions->add_key(parent, name)) { - parent->cache_subkeys = NULL; - parent->cache_subkeys_count = 0; - return True; - } - return False; + error = parent->handle->functions->add_key(parent, name, access_mask, desc, newkey); + + if(!W_ERROR_IS_OK(error)) return error; + + (*newkey)->handle = parent->handle; + (*newkey)->backend_data = talloc_asprintf((*newkey)->mem_ctx, "%s\\%s", reg_key_get_path(parent), name); + + parent->cache_subkeys = NULL; + parent->cache_subkeys_count = 0; + return WERR_OK; } -BOOL reg_val_update(REG_VAL *val, int type, void *data, int len) +WERROR reg_val_update(REG_VAL *val, int type, void *data, int len) { + WERROR error; + /* A 'real' update function has preference */ if (val->handle->functions->update_value) return val->handle->functions->update_value(val, type, data, len); @@ -433,18 +479,19 @@ BOOL reg_val_update(REG_VAL *val, int type, void *data, int len) if (val->handle->functions->add_value && val->handle->functions->del_value) { REG_VAL *new; - if(!val->handle->functions->del_value(val)) - return False; + if(!W_ERROR_IS_OK(error = val->handle->functions->del_value(val))) + return error; - new = val->handle->functions->add_value(val->parent, val->name, type, data, len); + error = val->handle->functions->add_value(val->parent, val->name, type, data, len); + if(!W_ERROR_IS_OK(error)) return error; memcpy(val, new, sizeof(REG_VAL)); val->parent->cache_values = NULL; val->parent->cache_values_count = 0; - return True; + return WERR_OK; } DEBUG(1, ("Backend '%s' doesn't support method update_value\n", val->handle->functions->name)); - return False; + return WERR_NOT_SUPPORTED; } void reg_free(REG_HANDLE *h) @@ -454,37 +501,44 @@ void reg_free(REG_HANDLE *h) h->functions->close_registry(h); } -REG_KEY *reg_get_root(REG_HANDLE *h) +WERROR reg_get_root(REG_HANDLE *h, REG_KEY **key) { - REG_KEY *ret = NULL; + WERROR ret; if(h->functions->open_root_key) { - ret = h->functions->open_root_key(h); + ret = h->functions->open_root_key(h, key); } else if(h->functions->open_key) { - ret = h->functions->open_key(h, "\\"); + ret = h->functions->open_key(h, "\\", key); } else { DEBUG(0, ("Backend '%s' has neither open_root_key nor open_key method implemented\n", h->functions->name)); + ret = WERR_NOT_SUPPORTED; } - if(ret) { - ret->handle = h; - ret->path = talloc_strdup(ret->mem_ctx, "\\"); + if(W_ERROR_IS_OK(ret)) { + (*key)->handle = h; + (*key)->path = talloc_strdup((*key)->mem_ctx, "\\"); } return ret; } -REG_VAL *reg_key_add_value(REG_KEY *key, const char *name, int type, void *value, size_t vallen) +WERROR reg_key_add_value(REG_KEY *key, const char *name, int type, void *value, size_t vallen) { - REG_VAL *ret; + WERROR ret = WERR_OK; if(!key->handle->functions->add_value) - return NULL; + return WERR_NOT_SUPPORTED; ret = key->handle->functions->add_value(key, name, type, value, vallen); - ret->parent = key; - ret->handle = key->handle; + + if(!W_ERROR_IS_OK(ret)) return ret; /* Invalidate the cache */ key->cache_values = NULL; key->cache_values_count = 0; return ret; } + +WERROR reg_save(REG_HANDLE *h, const char *location) +{ + /* FIXME */ + return WERR_NOT_SUPPORTED; +} diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index 060d053fc2..5ca104fc2e 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -96,22 +96,26 @@ BOOL reg_val_set_string(REG_VAL *val, char *str) return False; } -REG_VAL *reg_key_get_subkey_val(REG_KEY *key, const char *subname, const char *valname) +WERROR reg_key_get_subkey_val(REG_KEY *key, const char *subname, const char *valname, REG_VAL **val) { - REG_KEY *k = reg_key_get_subkey_by_name(key, subname); - if(!k) return NULL; + REG_KEY *k; + WERROR error = reg_key_get_subkey_by_name(key, subname, &k); + if(!W_ERROR_IS_OK(error)) return error; - return reg_key_get_value_by_name(k, valname); + return reg_key_get_value_by_name(k, valname, val); } -BOOL reg_key_set_subkey_val(REG_KEY *key, const char *subname, const char *valname, uint32 type, uint8 *data, int real_len) +WERROR reg_key_set_subkey_val(REG_KEY *key, const char *subname, const char *valname, uint32 type, uint8 *data, int real_len) { - REG_KEY *k = reg_key_get_subkey_by_name(key, subname); + REG_KEY *k; REG_VAL *v; - if(!k) return False; + WERROR error; - v = reg_key_get_value_by_name(k, valname); - if(!v) return False; + error = reg_key_get_subkey_by_name(key, subname, &k); + if(!W_ERROR_IS_OK(error)) return error; + + error = reg_key_get_value_by_name(k, valname, &v); + if(!W_ERROR_IS_OK(error)) return error; return reg_val_update(v, type, data, real_len); } diff --git a/source4/lib/registry/common/registry.h b/source4/lib/registry/common/registry.h index 3565a7a585..6e12de258d 100644 --- a/source4/lib/registry/common/registry.h +++ b/source4/lib/registry/common/registry.h @@ -57,42 +57,55 @@ struct reg_val_s { int ref; }; +/* FIXME */ +typedef void (*key_notification_function) (); +typedef void (*value_notification_function) (); + + /* * Container for function pointers to enumeration routines * for virtual registry view */ -struct reg_ops_s { +struct registry_ops { const char *name; - BOOL (*open_registry) (REG_HANDLE *, const char *location, BOOL try_complete_load); - BOOL (*sync)(REG_HANDLE *, const char *location); - BOOL (*close_registry) (REG_HANDLE *); + WERROR (*open_registry) (REG_HANDLE *, const char *location, const char *credentials); + WERROR (*sync_key)(REG_KEY *, const char *location); + WERROR (*close_registry) (REG_HANDLE *); /* Either implement these */ - REG_KEY *(*open_root_key) (REG_HANDLE *); - int (*num_subkeys) (REG_KEY *); - int (*num_values) (REG_KEY *); - REG_KEY *(*get_subkey_by_index) (REG_KEY *, int idx); - REG_KEY *(*get_subkey_by_name) (REG_KEY *, const char *name); - REG_VAL *(*get_value_by_index) (REG_KEY *, int idx); - REG_VAL *(*get_value_by_name) (REG_KEY *, const char *name); + WERROR (*open_root_key) (REG_HANDLE *, REG_KEY **); + WERROR (*num_subkeys) (REG_KEY *, int *count); + WERROR (*num_values) (REG_KEY *, int *count); + WERROR (*get_subkey_by_index) (REG_KEY *, int idx, REG_KEY **); + WERROR (*get_subkey_by_name) (REG_KEY *, const char *name, REG_KEY **); + WERROR (*get_value_by_index) (REG_KEY *, int idx, REG_VAL **); + WERROR (*get_value_by_name) (REG_KEY *, const char *name, REG_VAL **); /* Or these */ - REG_KEY *(*open_key) (REG_HANDLE *, const char *name); - BOOL (*fetch_subkeys) (REG_KEY *, int *count, REG_KEY ***); - BOOL (*fetch_values) (REG_KEY *, int *count, REG_VAL ***); + WERROR (*open_key) (REG_HANDLE *, const char *name, REG_KEY **); + WERROR (*fetch_subkeys) (REG_KEY *, int *count, REG_KEY ***); + WERROR (*fetch_values) (REG_KEY *, int *count, REG_VAL ***); + + /* Security control */ + WERROR (*key_get_sec_desc) (REG_KEY *, SEC_DESC **); + WERROR (*key_set_sec_desc) (REG_KEY *, SEC_DESC *); + + /* Notification */ + WERROR (*request_key_change_notify) (REG_KEY *, key_notification_function); + WERROR (*request_value_change_notify) (REG_VAL *, value_notification_function); /* Key management */ - BOOL (*add_key)(REG_KEY *, const char *name); - BOOL (*del_key)(REG_KEY *); + WERROR (*add_key)(REG_KEY *, const char *name, uint32 access_mask, SEC_DESC *, REG_KEY **); + WERROR (*del_key)(REG_KEY *); /* Value management */ - REG_VAL *(*add_value)(REG_KEY *, const char *name, int type, void *data, int len); - BOOL (*del_value)(REG_VAL *); + WERROR (*add_value)(REG_KEY *, const char *name, int type, void *data, int len); + WERROR (*del_value)(REG_VAL *); /* If update is not available, value will first be deleted and then added * again */ - BOOL (*update_value)(REG_VAL *, int type, void *data, int len); + WERROR (*update_value)(REG_VAL *, int type, void *data, int len); void (*free_key_backend_data) (REG_KEY *); void (*free_val_backend_data) (REG_VAL *); @@ -105,7 +118,7 @@ typedef struct reg_sub_tree_s { } REG_SUBTREE; struct reg_handle_s { - REG_OPS *functions; + struct registry_ops *functions; REG_SUBTREE *subtrees; char *location; void *backend_data; @@ -114,7 +127,7 @@ struct reg_handle_s { struct reg_init_function_entry { /* Function to create a member of the pdb_methods list */ - REG_OPS *functions; + struct registry_ops *functions; struct reg_init_function_entry *prev, *next; }; diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index 146ef92b95..90dc50728b 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -8,9 +8,12 @@ LIBWINREG=libwinregistry PKG_CHECK_MODULES(GCONF, gconf-2.0, [ SMB_MODULE_DEFAULT(reg_gconf,STATIC) CFLAGS="$CFLAGS $GCONF_CFLAGS";], [AC_MSG_WARN([GConf not found, not building reg_gconf])]) +PKG_CHECK_MODULES(GTK, glib-2.0 gtk+-2.0, [ CFLAGS="$CFLAGS $GTK_CFLAGS"; ], [ AC_MSG_WARN([Will be unable to build gregedit])]) + SMB_MODULE(reg_nt4, REG, STATIC, lib/registry/reg_backend_nt4/reg_backend_nt4.o) SMB_MODULE(reg_dir, REG, STATIC, lib/registry/reg_backend_dir/reg_backend_dir.o) SMB_MODULE(reg_rpc, REG, STATIC, lib/registry/reg_backend_rpc/reg_backend_rpc.o) SMB_MODULE(reg_gconf, REG, NOT, lib/registry/reg_backend_gconf/reg_backend_gconf.o, [], [$GCONF_LIBS]) +SMB_MODULE(reg_ldb, REG, STATIC, lib/registry/reg_backend_ldb/reg_backend_ldb.o) SMB_SUBSYSTEM(REG,lib/registry/common/reg_interface.o,[lib/registry/common/reg_objects.o lib/registry/common/reg_util.o],lib/registry/common/winregistry_proto.h,[]) AC_CONFIG_FILES(lib/registry/winregistry.pc) 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 9cb15cd285..4daaf3d628 100644 --- a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c @@ -21,7 +21,7 @@ #include "includes.h" #include "lib/registry/common/registry.h" -static BOOL reg_dir_add_key(REG_KEY *parent, const char *name) +static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *desc) { char *path; int ret; @@ -29,15 +29,16 @@ static BOOL reg_dir_add_key(REG_KEY *parent, const char *name) path = reg_path_win2unix(path); ret = mkdir(path, 0700); SAFE_FREE(path); - return (ret == 0); + if(ret == 0)return WERR_OK; + return WERR_INVALID_PARAM; } -static BOOL reg_dir_del_key(REG_KEY *k) +static WERROR reg_dir_del_key(REG_KEY *k) { - return (rmdir((char *)k->backend_data) == 0); + return (rmdir((char *)k->backend_data) == 0)?WERR_OK:WERR_GENERAL_FAILURE; } -static REG_KEY *reg_dir_open_key(REG_HANDLE *h, const char *name) +static WERROR reg_dir_open_key(REG_HANDLE *h, const char *name, REG_KEY **subkey) { DIR *d; char *fullpath; @@ -45,7 +46,7 @@ static REG_KEY *reg_dir_open_key(REG_HANDLE *h, const char *name) TALLOC_CTX *mem_ctx = talloc_init("tmp"); if(!name) { DEBUG(0, ("NULL pointer passed as directory name!")); - return NULL; + return WERR_INVALID_PARAM; } fullpath = talloc_asprintf(mem_ctx, "%s%s", h->location, name); fullpath = reg_path_win2unix(fullpath); @@ -54,16 +55,17 @@ static REG_KEY *reg_dir_open_key(REG_HANDLE *h, const char *name) if(!d) { DEBUG(3,("Unable to open '%s': %s\n", fullpath, strerror(errno))); talloc_destroy(mem_ctx); - return NULL; + return WERR_BADFILE; } closedir(d); ret = reg_key_new_abs(name, h, fullpath); talloc_steal(mem_ctx, ret->mem_ctx, fullpath); talloc_destroy(mem_ctx); - return ret; + *subkey = ret; + return WERR_OK; } -static BOOL reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r) +static WERROR reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r) { struct dirent *e; int max = 200; @@ -75,7 +77,7 @@ static BOOL reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r) d = opendir(fullpath); - if(!d) return False; + if(!d) return WERR_INVALID_PARAM; while((e = readdir(d))) { if(e->d_type == DT_DIR && @@ -96,35 +98,35 @@ static BOOL reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r) closedir(d); *r = ar; - return True; + return WERR_OK; } -static BOOL reg_dir_open(REG_HANDLE *h, const char *loc, BOOL try) { - if(!loc) return False; - return True; +static WERROR reg_dir_open(REG_HANDLE *h, const char *loc, const char *credentials) { + if(!loc) return WERR_INVALID_PARAM; + return WERR_OK; } -static REG_VAL *reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len) +static WERROR reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len, REG_VAL **value) { - REG_VAL *ret = reg_val_new(p, NULL); char *fullpath; FILE *fd; - ret->name = name?talloc_strdup(ret->mem_ctx, name):NULL; - fullpath = reg_path_win2unix(strdup(reg_val_get_path(ret))); + *value = reg_val_new(p, NULL); + (*value)->name = name?talloc_strdup((*value)->mem_ctx, name):NULL; + fullpath = reg_path_win2unix(strdup(reg_val_get_path(*value))); fd = fopen(fullpath, "w+"); /* FIXME */ - return NULL; + return WERR_NOT_SUPPORTED; } -static BOOL reg_dir_del_value(REG_VAL *v) +static WERROR reg_dir_del_value(REG_VAL *v) { /* FIXME*/ - return False; + return WERR_NOT_SUPPORTED; } -static REG_OPS reg_backend_dir = { +static struct registry_ops reg_backend_dir = { .name = "dir", .open_registry = reg_dir_open, .open_key = reg_dir_open_key, diff --git a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c index 71d3361ce2..1acb3cbcec 100644 --- a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c +++ b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c @@ -22,18 +22,26 @@ #include "lib/registry/common/registry.h" #include -static BOOL reg_open_gconf(REG_HANDLE *h, const char *location, BOOL try_complete_load) +static WERROR gerror_to_werror(GError *error) +{ + if(error == NULL) return WERR_OK; + /* FIXME */ + return WERR_FOOBAR; +} + +static WERROR reg_open_gconf(REG_HANDLE *h, const char *location, const char *credentials) { h->backend_data = (void *)gconf_client_get_default(); - return True; + if(!h->backend_data) return WERR_FOOBAR; + return WERR_OK; } -static BOOL reg_close_gconf(REG_HANDLE *h) +static WERROR reg_close_gconf(REG_HANDLE *h) { - return True; + return WERR_OK; } -static REG_KEY *gconf_open_key (REG_HANDLE *h, const char *name) +static WERROR gconf_open_key (REG_HANDLE *h, const char *name, REG_KEY **key) { REG_KEY *ret; char *fullpath = reg_path_win2unix(strdup(name)); @@ -41,16 +49,17 @@ static REG_KEY *gconf_open_key (REG_HANDLE *h, const char *name) /* Check if key exists */ if(!gconf_client_dir_exists((GConfClient *)h->backend_data, fullpath, NULL)) { SAFE_FREE(fullpath); - return NULL; + return WERR_DEST_NOT_FOUND; } ret = reg_key_new_abs(name, h, NULL); ret->backend_data = talloc_strdup(ret->mem_ctx, fullpath); SAFE_FREE(fullpath); - return ret; + *key = ret; + return WERR_OK; } -static BOOL gconf_fetch_values(REG_KEY *p, int *count, REG_VAL ***vals) +static WERROR gconf_fetch_values(REG_KEY *p, int *count, REG_VAL ***vals) { GSList *entries; GSList *cur; @@ -113,22 +122,24 @@ static BOOL gconf_fetch_values(REG_KEY *p, int *count, REG_VAL ***vals) g_slist_free(entries); *vals = ar; - return True; + return WERR_OK; } -static BOOL gconf_fetch_subkeys(REG_KEY *p, int *count, REG_KEY ***subs) +static WERROR gconf_fetch_subkeys(REG_KEY *p, int *count, REG_KEY ***subs) { GSList *dirs; GSList *cur; - REG_KEY **ar = malloc(sizeof(REG_KEY *)); + REG_KEY **ar = talloc_array_p(p->mem_ctx, REG_KEY *, 1); char *fullpath = p->backend_data; cur = dirs = gconf_client_all_dirs((GConfClient*)p->handle->backend_data, fullpath,NULL); (*count) = 0; while(cur) { - ar[(*count)] = reg_key_new_abs(reg_path_unix2win((char *)cur->data), p->handle,NULL); - ar[(*count)]->backend_data = talloc_strdup(ar[*count]->mem_ctx, cur->data); - ar = realloc(ar, sizeof(REG_KEY *) * ((*count)+2)); + char *winpath = reg_path_unix2win(strdup((char *)cur->data)); + ar[(*count)] = reg_key_new_abs(winpath, p->handle,NULL); + free(winpath); + ar[(*count)]->backend_data = reg_path_win2unix(talloc_strdup(ar[*count]->mem_ctx, cur->data)); + ar = talloc_realloc_p(p->mem_ctx, ar, REG_KEY *, (*count)+2); (*count)++; g_free(cur->data); cur = cur->next; @@ -136,10 +147,10 @@ static BOOL gconf_fetch_subkeys(REG_KEY *p, int *count, REG_KEY ***subs) g_slist_free(dirs); *subs = ar; - return True; + return WERR_OK; } -static BOOL gconf_update_value(REG_VAL *val, int type, void *data, int len) +static WERROR gconf_update_value(REG_VAL *val, int type, void *data, int len) { GError *error = NULL; char *keypath = val->backend_data; @@ -152,22 +163,23 @@ static BOOL gconf_update_value(REG_VAL *val, int type, void *data, int len) case REG_EXPAND_SZ: gconf_client_set_string((GConfClient *)val->handle->backend_data, valpath, data, &error); free(valpath); - return (error == NULL); + return gerror_to_werror(error); case REG_DWORD: gconf_client_set_int((GConfClient *)val->handle->backend_data, valpath, *((int *)data), &error); free(valpath); - return (error == NULL); + return gerror_to_werror(error); default: DEBUG(0, ("Unsupported type: %d\n", type)); free(valpath); - return False; + return WERR_NOT_SUPPORTED; } - return False; + + return WERR_NOT_SUPPORTED; } -static REG_OPS reg_backend_gconf = { +static struct registry_ops reg_backend_gconf = { .name = "gconf", .open_registry = reg_open_gconf, .close_registry = reg_close_gconf, diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index afa60c5c4a..3cc1651519 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -20,51 +20,96 @@ #include "includes.h" #include "lib/registry/common/registry.h" +#include "lib/ldb/include/ldb.h" + +char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path) +{ + char *ret = talloc_strdup(mem_ctx, "(dn="); + char *begin = (char *)path; + char *end = NULL; + + while(begin) { + end = strchr(begin, '\\'); + if(end)end = '\0'; + if(end - begin != 0) ret = talloc_asprintf_append(mem_ctx, ret, "key=%s,", begin); + + if(end) { + *end = '\\'; + begin = end+1; + } else begin = NULL; + } + + ret[strlen(ret)-1] = ')'; + return ret; +} /* * Saves the dn as private_data for every key/val */ -static BOOL ldb_open_registry(REG_HANDLE *handle, const char *location, BOOL try_full_load) +static WERROR ldb_open_registry(REG_HANDLE *handle, const char *location, const char *credentials) { struct ldb_context *c; c = ldb_connect(location, 0, NULL); - if(!c) return False; + if(!c) return WERR_FOOBAR; handle->backend_data = c; - return True; + return WERR_OK; } -static BOOL ldb_close_registry(REG_HANDLE *h) +static WERROR ldb_close_registry(REG_HANDLE *h) { - ldb_close(h); - return True; + ldb_close((struct ldb_context *)h->backend_data); + return WERR_OK; } -static BOOL ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys) +static WERROR ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys) { - ldb_search(); + struct ldb_context *c = k->handle->backend_data; + char *path; + struct ldb_message **msg; + char *ldap_path; + TALLOC_CTX *mem_ctx = talloc_init("ldb_path"); + REG_KEY *key = NULL; + ldap_path = reg_path_to_ldb(mem_ctx, reg_key_get_path(k)); + + if(ldb_search(c, NULL, LDB_SCOPE_ONELEVEL, ldap_path, NULL,&msg) > 0) { + key = reg_key_new_abs(reg_key_get_path(k), k->handle, ldap_path); + talloc_steal(mem_ctx, key->mem_ctx, ldap_path); + /* FIXME */ + } + + ldap_search_free(c, msg); + talloc_destroy(mem_ctx); + return WERR_OK; } -static REG_KEY *ldb_open_key(REG_HANDLE *h, const char *name) + + +static WERROR ldb_open_key(REG_HANDLE *h, const char *name, REG_KEY **key) { struct ldb_context *c = h->backend_data; char *path; struct ldb_message **msg; - REG_KEY *key = NULL; - (dn=key=Systems, - if(ldb_search(c, NULL, LDP_SCOPE_BASE, "", NULL,&msg) > 0) { - key = reg_key_new_abs(name, h, base); + char *ldap_path; + TALLOC_CTX *mem_ctx = talloc_init("ldb_path"); + ldap_path = reg_path_to_ldb(mem_ctx, name); + + if(ldb_search(c, NULL, LDB_SCOPE_BASE, ldap_path, NULL,&msg) > 0) { + *key = reg_key_new_abs(name, h, ldap_path); + talloc_steal(mem_ctx, (*key)->mem_ctx, ldap_path); + /* FIXME */ } ldap_search_free(c, msg); + talloc_destroy(mem_ctx); - return key; + return WERR_OK;; } -static REG_OPS reg_backend_ldb = { +static struct registry_ops reg_backend_ldb = { .name = "ldb", .open_registry = ldb_open_registry, .close_registry = ldb_close_registry, diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index ef2565bda8..9d90523a75 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -881,7 +881,7 @@ static KEY_SEC_DESC *process_sk(REG_HANDLE *regf, SK_HDR *sk_hdr, int sk_off, in /* * Process a VK header and return a value */ -static REG_VAL *vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size) +static WERROR vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size, REG_VAL **value) { char val_name[1024]; REGF *regf = parent->handle->backend_data; @@ -889,12 +889,12 @@ static REG_VAL *vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size) const char *val_type; REG_VAL *tmp = NULL; - if (!vk_hdr) return NULL; + if (!vk_hdr) return WERR_INVALID_PARAM; if ((vk_id = SVAL(&vk_hdr->VK_ID,0)) != str_to_dword("vk")) { DEBUG(0, ("Unrecognized VK header ID: %0X, block: %0X, %s\n", vk_id, (int)vk_hdr, parent->handle->location)); - return NULL; + return WERR_GENERAL_FAILURE; } nam_len = SVAL(&vk_hdr->nam_len,0); @@ -943,7 +943,8 @@ static REG_VAL *vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size) tmp->data_len = dat_len; } - return tmp; + *value = tmp; + return WERR_OK; } static BOOL vl_verify(VL_TYPE vl, int count, int size) @@ -956,63 +957,67 @@ static BOOL vl_verify(VL_TYPE vl, int count, int size) return True; } -static BOOL lf_verify(REG_HANDLE *h, LF_HDR *lf_hdr, int size) +static WERROR lf_verify(REG_HANDLE *h, LF_HDR *lf_hdr, int size) { int lf_id; if ((lf_id = SVAL(&lf_hdr->LF_ID,0)) != str_to_dword("lf")) { DEBUG(0, ("Unrecognized LF Header format: %0X, Block: %0X, %s.\n", lf_id, (int)lf_hdr, h->location)); - return False; + return WERR_INVALID_PARAM; } - return True; + return WERR_OK; } -static int lf_num_entries(REG_HANDLE *h, LF_HDR *lf_hdr, int size) +static WERROR lf_num_entries(REG_HANDLE *h, LF_HDR *lf_hdr, int size, int *count) { - int count; + WERROR error; - if(!lf_verify(h, lf_hdr, size)) return 0; + error = lf_verify(h, lf_hdr, size); + if(!W_ERROR_IS_OK(error)) return error; SMB_REG_ASSERT(size < 0); - count = SVAL(&lf_hdr->key_count,0); - DEBUG(2, ("Key Count: %u\n", count)); - if (count <= 0) return 0; + *count = SVAL(&lf_hdr->key_count,0); + DEBUG(2, ("Key Count: %u\n", *count)); + if (*count <= 0) return WERR_INVALID_PARAM; - return count; + return WERR_OK; } -static REG_KEY *nk_to_key(REG_HANDLE *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent); +static WERROR nk_to_key(REG_HANDLE *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent, REG_KEY **); /* * Process an LF Header and return a list of sub-keys */ -static REG_KEY *lf_get_entry(REG_KEY *parent, LF_HDR *lf_hdr, int size, int n) +static WERROR lf_get_entry(REG_KEY *parent, LF_HDR *lf_hdr, int size, int n, REG_KEY **key) { REGF *regf = parent->handle->backend_data; int count, nk_off; NK_HDR *nk_hdr; + WERROR error; - if (!lf_hdr) return NULL; + if (!lf_hdr) return WERR_INVALID_PARAM; - if(!lf_verify(parent->handle, lf_hdr, size)) return NULL; + error = lf_verify(parent->handle, lf_hdr, size); + if(!W_ERROR_IS_OK(error)) return error; SMB_REG_ASSERT(size < 0); count = SVAL(&lf_hdr->key_count,0); DEBUG(2, ("Key Count: %u\n", count)); - if (count <= 0 || n > count) return NULL; + if (count <= 0) return WERR_GENERAL_FAILURE; + if (n >= count) return WERR_NO_MORE_ITEMS; nk_off = IVAL(&lf_hdr->hr[n].nk_off,0); DEBUG(2, ("NK Offset: %0X\n", nk_off)); nk_hdr = (NK_HDR *)LOCN(regf->base, nk_off); - return nk_to_key(parent->handle, nk_hdr, BLK_SIZE(nk_hdr), parent); + return nk_to_key(parent->handle, nk_hdr, BLK_SIZE(nk_hdr), parent, key); } -static REG_KEY *nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent) +static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent, REG_KEY **key) { REGF *regf = h->backend_data; REG_KEY *tmp = NULL, *own; @@ -1022,12 +1027,12 @@ static REG_KEY *nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *pare int type; char key_name[1024], cls_name[1024]; - if (!nk_hdr) return NULL; + if (!nk_hdr) return WERR_INVALID_PARAM; if ((nk_id = SVAL(&nk_hdr->NK_ID,0)) != str_to_dword("nk")) { DEBUG(0, ("Unrecognized NK Header format: %08X, Block: %0X. %s\n", nk_id, (int)nk_hdr, parent->handle->location)); - return NULL; + return WERR_INVALID_PARAM; } SMB_REG_ASSERT(size < 0); @@ -1047,7 +1052,7 @@ static REG_KEY *nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *pare DEBUG(0, ("Incorrect NK_HDR size: %d, %0X\n", -size, (int)nk_hdr)); DEBUG(0, ("Sizeof NK_HDR: %d, name_len %d, clsname_len %d\n", sizeof(NK_HDR), name_len, clsname_len)); - /*return NULL;*/ + return WERR_GENERAL_FAILURE; } DEBUG(2, ("NK HDR: Name len: %d, class name len: %d\n", name_len, clsname_len)); @@ -1062,7 +1067,7 @@ static REG_KEY *nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *pare type = (SVAL(&nk_hdr->type,0)==0x2C?REG_ROOT_KEY:REG_SUB_KEY); if(type == REG_ROOT_KEY && parent) { DEBUG(0,("Root key encountered below root level!\n")); - return NULL; + return WERR_GENERAL_FAILURE; } if(type == REG_ROOT_KEY) tmp = reg_key_new_abs(key_name, h, nk_hdr); @@ -1121,7 +1126,8 @@ static REG_KEY *nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *pare } - return tmp; + *key = tmp; + return WERR_OK; } /* @@ -1559,7 +1565,7 @@ error: return NULL; } -static BOOL nt_close_registry (REG_HANDLE *h) +static WERROR nt_close_registry (REG_HANDLE *h) { REGF *regf = h->backend_data; if (regf->base) munmap(regf->base, regf->sbuf.st_size); @@ -1570,10 +1576,10 @@ static BOOL nt_close_registry (REG_HANDLE *h) regf->sk_count = regf->sk_map_size = 0; free(regf); - return False; + return WERR_OK; } -static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load) +static WERROR nt_open_registry (REG_HANDLE *h, const char *location, const char *credentials) { REGF *regf = (REGF *)malloc(sizeof(REGF)); REGF_HDR *regf_hdr; @@ -1582,7 +1588,7 @@ static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load memset(regf, 0, sizeof(REGF)); regf->mem_ctx = talloc_init("regf"); - regf->owner_sid_str = def_owner_sid_str; + regf->owner_sid_str = credentials; h->backend_data = regf; DEBUG(5, ("Attempting to load registry file\n")); @@ -1591,7 +1597,7 @@ static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load if ((regf_hdr = nt_get_regf_hdr(h)) == NULL) { DEBUG(0, ("Unable to get header\n")); - return False; + return WERR_GENERAL_FAILURE; } /* Now process that header and start to read the rest in */ @@ -1599,7 +1605,7 @@ static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load if ((regf_id = IVAL(®f_hdr->REGF_ID,0)) != str_to_dword("regf")) { DEBUG(0, ("Unrecognized NT registry header id: %0X, %s\n", regf_id, h->location)); - return False; + return WERR_GENERAL_FAILURE; } /* @@ -1608,7 +1614,7 @@ static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load if (!valid_regf_hdr(regf_hdr)) { DEBUG(0, ("Registry file header does not validate: %s\n", h->location)); - return False; + return WERR_GENERAL_FAILURE; } /* Update the last mod date, and then go get the first NK record and on */ @@ -1625,7 +1631,7 @@ static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load if ((hbin_id = IVAL(&hbin_hdr->HBIN_ID,0)) != str_to_dword("hbin")) { DEBUG(0, ("Unrecognized registry hbin hdr ID: %0X, %s\n", hbin_id, h->location)); - return False; + return WERR_GENERAL_FAILURE; } /* @@ -1655,15 +1661,15 @@ static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load h->backend_data = regf; - return True; + return WERR_OK; } -static REG_KEY *nt_get_root_key(REG_HANDLE *h) +static WERROR nt_get_root_key(REG_HANDLE *h, REG_KEY **key) { - return nk_to_key(h, ((REGF *)h->backend_data)->first_key, BLK_SIZE(((REGF *)h->backend_data)->first_key), NULL); + return nk_to_key(h, ((REGF *)h->backend_data)->first_key, BLK_SIZE(((REGF *)h->backend_data)->first_key), NULL, key); } -static int nt_num_subkeys(REG_KEY *k) +static WERROR nt_num_subkeys(REG_KEY *k, int *num) { REGF *regf = k->handle->backend_data; LF_HDR *lf_hdr; @@ -1671,19 +1677,23 @@ static int nt_num_subkeys(REG_KEY *k) NK_HDR *nk_hdr = k->backend_data; lf_off = IVAL(&nk_hdr->lf_off,0); DEBUG(2, ("SubKey list offset: %0X\n", lf_off)); - if(lf_off == -1) return 0; + if(lf_off == -1) { + *num = 0; + return WERR_OK; + } lf_hdr = (LF_HDR *)LOCN(regf->base, lf_off); - return lf_num_entries(k->handle, lf_hdr, BLK_SIZE(lf_hdr)); + return lf_num_entries(k->handle, lf_hdr, BLK_SIZE(lf_hdr), num); } -static int nt_num_values(REG_KEY *k) +static WERROR nt_num_values(REG_KEY *k, int *count) { NK_HDR *nk_hdr = k->backend_data; - return IVAL(&nk_hdr->val_cnt,0); + *count = IVAL(&nk_hdr->val_cnt,0); + return WERR_OK; } -static REG_VAL *nt_value_by_index(REG_KEY *k, int n) +static WERROR nt_value_by_index(REG_KEY *k, int n, REG_VAL **value) { VL_TYPE *vl; int val_off, vk_off; @@ -1696,10 +1706,10 @@ static REG_VAL *nt_value_by_index(REG_KEY *k, int n) vk_off = IVAL(&vl[n],0); vk_hdr = (VK_HDR *)LOCN(regf->base, vk_off); - return vk_to_val(k, vk_hdr, BLK_SIZE(vk_hdr)); + return vk_to_val(k, vk_hdr, BLK_SIZE(vk_hdr), value); } -static REG_KEY *nt_key_by_index(REG_KEY *k, int n) +static WERROR nt_key_by_index(REG_KEY *k, int n, REG_KEY **subkey) { REGF *regf = k->handle->backend_data; int lf_off; @@ -1714,13 +1724,13 @@ static REG_KEY *nt_key_by_index(REG_KEY *k, int n) if (lf_off != -1) { lf_hdr = (LF_HDR *)LOCN(regf->base, lf_off); - return lf_get_entry(k, lf_hdr, BLK_SIZE(lf_hdr), n); + return lf_get_entry(k, lf_hdr, BLK_SIZE(lf_hdr), n, subkey); } - return NULL; + return WERR_NO_MORE_ITEMS; } -static REG_OPS reg_backend_nt4 = { +static struct registry_ops reg_backend_nt4 = { .name = "nt4", .open_registry = nt_open_registry, .close_registry = nt_close_registry, 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 ad4d537f9b..e61301d6f2 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -77,12 +77,18 @@ struct { { NULL, NULL } }; -static BOOL rpc_open_registry(REG_HANDLE *h, const char *location, BOOL try_full) +static WERROR rpc_open_registry(REG_HANDLE *h, const char *location, const char *credentials) { - BOOL res = True; struct rpc_data *mydata = talloc(h->mem_ctx, sizeof(struct rpc_data)); char *binding = strdup(location); NTSTATUS status; + char *user, *pass; + + if(!credentials || !location) return WERR_INVALID_PARAM; + + user = talloc_strdup(h->mem_ctx, credentials); + pass = strchr(user, '%'); + *pass = '\0'; pass++; ZERO_STRUCTP(mydata); @@ -90,26 +96,26 @@ static BOOL rpc_open_registry(REG_HANDLE *h, const char *location, BOOL try_full DCERPC_WINREG_UUID, DCERPC_WINREG_VERSION, lp_workgroup(), - "tridge", "samba"); + user, pass); - if(!NT_STATUS_IS_OK(status)) return False; h->backend_data = mydata; - return True; + return ntstatus_to_werror(status); } -static REG_KEY *rpc_open_root(REG_HANDLE *h) +static WERROR rpc_open_root(REG_HANDLE *h, REG_KEY **k) { /* There's not really a 'root' key here */ - return reg_key_new_abs("\\", h, h->backend_data); + *k = reg_key_new_abs("\\", h, h->backend_data); + return WERR_OK; } -static BOOL rpc_close_registry(REG_HANDLE *h) +static WERROR rpc_close_registry(REG_HANDLE *h) { dcerpc_pipe_close(((struct rpc_data *)h->backend_data)->pipe); free(h->backend_data); - return True; + return WERR_OK; } static struct policy_handle *rpc_get_key_handle(REG_HANDLE *h, const char *path) @@ -161,12 +167,15 @@ static struct policy_handle *rpc_get_key_handle(REG_HANDLE *h, const char *path) return key_handle; } -static REG_KEY *rpc_open_key(REG_HANDLE *h, const char *name) +static WERROR rpc_open_key(REG_HANDLE *h, const char *name, REG_KEY **key) { - return reg_key_new_abs(name, h, rpc_get_key_handle(h, name)); + struct policy_handle *pol = rpc_get_key_handle(h, name); + if(!pol) return WERR_DEST_NOT_FOUND; + *key = reg_key_new_abs(name, h, pol); + return WERR_OK; } -static BOOL rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys) +static WERROR rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys) { struct winreg_EnumKey r; struct winreg_EnumKeyNameRequest keyname; @@ -188,12 +197,12 @@ static BOOL rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys) *subkeys = ar; - return True; + return WERR_OK; } if(!parent->backend_data) parent->backend_data = rpc_get_key_handle(parent->handle, reg_key_get_path(parent)); - if(!parent->backend_data) return False; + if(!parent->backend_data) return WERR_GENERAL_FAILURE; (*count) = 0; r.in.handle = parent->backend_data; @@ -219,10 +228,10 @@ static BOOL rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys) } *subkeys = ar; - return True; + return r.out.result; } -static BOOL rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values) +static WERROR rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values) { struct winreg_EnumValue r; struct winreg_Uint8buf value; @@ -238,12 +247,12 @@ static BOOL rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values) /* Root */ if(parent->backend_data == parent->handle->backend_data) { *values = ar; - return True; + return WERR_OK; } if(!parent->backend_data) parent->backend_data = rpc_get_key_handle(parent->handle, reg_key_get_path(parent)); - if(!parent->backend_data) return False; + if(!parent->backend_data) return WERR_GENERAL_FAILURE; r.in.handle = parent->backend_data; r.in.enum_index = 0; @@ -283,22 +292,48 @@ static BOOL rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values) *values = ar; - return True; + return r.out.result; } -static BOOL rpc_add_key(REG_KEY *parent, const char *name) +static WERROR rpc_add_key(REG_KEY *parent, const char *name) { /* FIXME */ - return False; + return WERR_NOT_SUPPORTED; } -static BOOL rpc_del_key(REG_KEY *k) +static struct policy_handle*get_hive(REG_KEY *k) { - /* FIXME */ - return False; + int i; + struct rpc_data *mydata = k->handle->backend_data; + for(i = 0; known_hives[i].name; i++) { + if(!strncmp(known_hives[i].name, reg_key_get_path(k)+1, strlen(known_hives[i].name))) + return mydata->hives[i]; + } + return NULL; +} + +static WERROR rpc_del_key(REG_KEY *k) +{ + NTSTATUS status; + struct rpc_data *mydata = k->handle->backend_data; + struct winreg_DeleteKey r; + char *hivepath; + struct policy_handle *hive = get_hive(k); + + printf("first: %s\n", reg_key_get_path(k)); + hivepath = strchr(reg_key_get_path(k), '\\'); + hivepath = strchr(hivepath+1, '\\'); + printf("asfter: %s\n", hivepath+1); + + r.in.handle = hive; + init_winreg_String(&r.in.key, hivepath+1); + + status = dcerpc_winreg_DeleteKey(mydata->pipe, k->mem_ctx, &r); + + return r.out.result; } -static REG_OPS reg_backend_rpc = { +static struct registry_ops reg_backend_rpc = { .name = "rpc", .open_registry = rpc_open_registry, .close_registry = rpc_close_registry, diff --git a/source4/lib/registry/reg_backend_wine/reg_backend_wine.c b/source4/lib/registry/reg_backend_wine/reg_backend_wine.c index 6c8d7885cb..fd7d04bcf0 100644 --- a/source4/lib/registry/reg_backend_wine/reg_backend_wine.c +++ b/source4/lib/registry/reg_backend_wine/reg_backend_wine.c @@ -20,6 +20,7 @@ #include "includes.h" #include "lib/registry/common/registry.h" +#include "windows/registry.h" static REG_OPS reg_backend_wine = { .name = "wine", diff --git a/source4/lib/registry/tools/gregedit.c b/source4/lib/registry/tools/gregedit.c new file mode 100644 index 0000000000..b62fd7ec04 --- /dev/null +++ b/source4/lib/registry/tools/gregedit.c @@ -0,0 +1,758 @@ +/* + Unix SMB/CIFS implementation. + Gtk registry frontend + + Copyright (C) Jelmer Vernooij 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include "includes.h" + +GtkWidget *openfilewin; +GtkWidget *savefilewin; +GtkTreeStore *store_keys; +GtkListStore *store_vals; +GtkWidget *tree_keys; +GtkWidget *aboutwin; +GtkWidget *mainwin; + +GtkWidget *rpcwin; +GtkWidget *rpcwin_host; +GtkWidget *rpcwin_user; +GtkWidget *rpcwin_password; +GtkWidget *save; +GtkWidget *save_as; +GtkWidget* create_openfilewin (void); +GtkWidget* create_savefilewin (void); +static GtkWidget* create_aboutwin (void); +REG_HANDLE *registry = NULL; + +static void gtk_show_werror(WERROR err) +{ + GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(mainwin), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "Registry error: %s\n", win_errstr(err)); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); +} + +static void treeview_add_val(REG_VAL *val) +{ + GtkTreeIter iter; + gtk_list_store_append(store_vals, &iter); + gtk_list_store_set (store_vals, + &iter, + 0, + reg_val_name(val), + 1, + str_regtype(reg_val_type(val)), + 2, + reg_val_data_string(val), + 3, + val, + -1); +} + +static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath *arg2) +{ + GtkTreeIter iter, tmpiter; + REG_KEY *k, *sub; + char *name; + GValue value; + WERROR error; + int i; + + /* See if this row has ever had a name gtk_tree_store_set()'ed to it. + If not, read the directory contents */ + gtk_tree_model_get(GTK_TREE_MODEL(store_keys), parent, + 0, &name, -1); + + if(!name) return; + + gtk_tree_model_get(GTK_TREE_MODEL(store_keys), parent, 1, &k, -1); + + g_assert(k); + + for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(k, i, &sub)); i++) { + /* Replace the blank child with the first directory entry + You may be tempted to remove the blank child node and then + append a new one. Don't. If you remove the blank child + node GTK gets confused and won't expand the parent row. */ + + if(i == 0) { + gtk_tree_model_iter_children(GTK_TREE_MODEL(store_keys), + &iter, parent); + } else { + gtk_tree_store_append(store_keys, &iter, parent); + } + gtk_tree_store_set (store_keys, + &iter, + 0, + reg_key_name(sub), + 1, + sub, + -1); + + gtk_tree_store_append(store_keys, &tmpiter, &iter); + } + + /* Remove placeholder child */ + if(i == 0) { + gtk_tree_model_iter_children(GTK_TREE_MODEL(store_keys), + &iter, parent); + gtk_tree_store_remove(store_keys, &iter); + } + + if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) gtk_show_werror(error); +} + +static void registry_load_root() +{ + REG_KEY *root; + GtkTreeIter iter, tmpiter; + WERROR error; + if(!registry) return; + + error = reg_get_root(registry, &root); + if(!W_ERROR_IS_OK(error)) { + gtk_show_werror(error); + return; + } + + gtk_tree_store_clear(store_keys); + + /* Add the root */ + gtk_tree_store_append(store_keys, &iter, NULL); + gtk_tree_store_set (store_keys, + &iter, + 0, + reg_key_name(root), + 1, + root, + -1); + + gtk_tree_store_append(store_keys, &tmpiter, &iter); + + gtk_widget_set_sensitive( save, True ); + gtk_widget_set_sensitive( save_as, True ); +} + +GtkWidget* create_rpcwin (void) +{ + GtkWidget *dialog_vbox1; + GtkWidget *table1; + GtkWidget *label1; + GtkWidget *label2; + GtkWidget *label3; + GtkWidget *dialog_action_area1; + GtkWidget *cancelbutton1; + GtkWidget *okbutton1; + + rpcwin = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (rpcwin), "Connect to remote server"); + + dialog_vbox1 = GTK_DIALOG (rpcwin)->vbox; + gtk_widget_show (dialog_vbox1); + + table1 = gtk_table_new (3, 2, FALSE); + gtk_widget_show (table1); + gtk_box_pack_start (GTK_BOX (dialog_vbox1), table1, TRUE, TRUE, 0); + + label1 = gtk_label_new ("Host:"); + gtk_widget_show (label1); + gtk_table_attach (GTK_TABLE (table1), label1, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label1), 0, 0.5); + + label2 = gtk_label_new ("User:"); + gtk_widget_show (label2); + gtk_table_attach (GTK_TABLE (table1), label2, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label2), 0, 0.5); + + label3 = gtk_label_new ("Password:"); + gtk_widget_show (label3); + gtk_table_attach (GTK_TABLE (table1), label3, 0, 1, 2, 3, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label3), 0, 0.5); + + rpcwin_host = gtk_entry_new (); + gtk_widget_show (rpcwin_host); + gtk_table_attach (GTK_TABLE (table1), rpcwin_host, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + rpcwin_user = gtk_entry_new (); + gtk_widget_show (rpcwin_user); + gtk_table_attach (GTK_TABLE (table1), rpcwin_user, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + rpcwin_password = gtk_entry_new (); + gtk_widget_show (rpcwin_password); + gtk_table_attach (GTK_TABLE (table1), rpcwin_password, 1, 2, 2, 3, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_entry_set_visibility (GTK_ENTRY (rpcwin_password), FALSE); + + dialog_action_area1 = GTK_DIALOG (rpcwin)->action_area; + gtk_widget_show (dialog_action_area1); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END); + + cancelbutton1 = gtk_button_new_from_stock ("gtk-cancel"); + gtk_widget_show (cancelbutton1); + gtk_dialog_add_action_widget (GTK_DIALOG (rpcwin), cancelbutton1, GTK_RESPONSE_CANCEL); + GTK_WIDGET_SET_FLAGS (cancelbutton1, GTK_CAN_DEFAULT); + + okbutton1 = gtk_button_new_from_stock ("gtk-ok"); + gtk_widget_show (okbutton1); + gtk_dialog_add_action_widget (GTK_DIALOG (rpcwin), okbutton1, GTK_RESPONSE_OK); + GTK_WIDGET_SET_FLAGS (okbutton1, GTK_CAN_DEFAULT); + + return rpcwin; +} + + +static void on_open_nt4_activate (GtkMenuItem *menuitem, gpointer user_data) +{ + gint result = gtk_dialog_run(GTK_DIALOG(create_openfilewin())); + char *filename; + WERROR error; + switch(result) { + case GTK_RESPONSE_OK: + filename = strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(openfilewin))); + error = reg_open("nt4", filename, NULL, ®istry); + if(!W_ERROR_IS_OK(error)) { + gtk_show_werror(error); + return; + } + registry_load_root(); + break; + default: + break; + } + + gtk_widget_destroy(openfilewin); +} + +void on_open_gconf_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + WERROR error = reg_open("gconf", NULL, NULL, ®istry); + if(!W_ERROR_IS_OK(error)) { + gtk_show_werror(error); + return; + } + + registry_load_root(); +} + +void +on_open_remote_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + char *location, *credentials; + gint result = gtk_dialog_run(GTK_DIALOG(create_rpcwin())); + WERROR error; + switch(result) { + case GTK_RESPONSE_OK: + asprintf(&location, "ncacn_np:%s", gtk_entry_get_text(GTK_ENTRY(rpcwin_host))); + asprintf(&credentials, "%s%%%s", gtk_entry_get_text(GTK_ENTRY(rpcwin_user)), gtk_entry_get_text(GTK_ENTRY(rpcwin_password))); + error = reg_open("rpc", location, credentials, ®istry); + if(!W_ERROR_IS_OK(error)) { + gtk_show_werror(error); + return; + } + free(location); free(credentials); + registry_load_root(); + break; + default: + break; + } + + gtk_widget_destroy(rpcwin); +} + + +void +on_save_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + WERROR error = reg_save(registry, NULL); + if(!W_ERROR_IS_OK(error)) { + gtk_show_werror(error); + } +} + + +void +on_save_as_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + gint result; + WERROR error; + create_savefilewin(); + result = gtk_dialog_run(GTK_DIALOG(savefilewin)); + switch(result) { + case GTK_RESPONSE_OK: + error = reg_save(registry, gtk_file_selection_get_filename(GTK_FILE_SELECTION(savefilewin))); + if(!W_ERROR_IS_OK(error)) { + gtk_show_werror(error); + } + break; + + default: + break; + + } + gtk_widget_destroy(savefilewin); +} + + +void +on_quit_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + gtk_main_quit(); +} + + +void +on_cut_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + /* FIXME */ +} + + +void +on_copy_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + /* FIXME */ +} + + +void +on_paste_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + /* FIXME */ +} + + +void +on_delete_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + /* FIXME */ +} + + +void +on_about_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + gtk_dialog_run(GTK_DIALOG(create_aboutwin())); + gtk_widget_destroy(aboutwin); +} + +void on_key_activate (GtkTreeView *treeview, + GtkTreePath *path, + gpointer user_data) +{ + int i; + REG_KEY *k; + REG_VAL *val; + WERROR error; + +//FIXME gtk_tree_model_get(GTK_TREE_MODEL(store_keys), iter, 1, &k, -1); + + gtk_list_store_clear(store_vals); + + for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(k, i, &val)); i++) { + treeview_add_val(val); + } + + if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) gtk_show_werror(error); + + return; +} + +GtkWidget* create_mainwin (void) +{ + GtkWidget *vbox1; + GtkWidget *menubar; + GtkWidget *menu_file; + GtkWidget *menu_file_menu; + GtkWidget *open_nt4; + GtkWidget *open_gconf; + GtkWidget *open_remote; + GtkWidget *separatormenuitem1; + GtkWidget *quit; + GtkWidget *men_edit; + GtkWidget *men_edit_menu; + GtkWidget *cut; + GtkWidget *copy; + GtkWidget *paste; + GtkWidget *delete; + GtkCellRenderer *renderer; + GtkTreeViewColumn *curcol; + GtkWidget *help; + GtkWidget *help_menu; + GtkWidget *about; + GtkWidget *hbox1; + GtkWidget *scrolledwindow1; + GtkWidget *scrolledwindow2; + GtkWidget *tree_vals; + GtkWidget *statusbar; + GtkAccelGroup *accel_group; + GtkTreeIter iter, child; + + accel_group = gtk_accel_group_new (); + + mainwin = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (mainwin), "Registry editor"); + gtk_window_set_default_size (GTK_WINDOW (mainwin), 642, 562); + + vbox1 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox1); + gtk_container_add (GTK_CONTAINER (mainwin), vbox1); + + menubar = gtk_menu_bar_new (); + gtk_widget_show (menubar); + gtk_box_pack_start (GTK_BOX (vbox1), menubar, FALSE, FALSE, 0); + + menu_file = gtk_menu_item_new_with_mnemonic ("_File"); + gtk_widget_show (menu_file); + gtk_container_add (GTK_CONTAINER (menubar), menu_file); + + menu_file_menu = gtk_menu_new (); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_file), menu_file_menu); + + open_nt4 = gtk_image_menu_item_new_with_mnemonic("_Open NT4 file"); + gtk_widget_show (open_nt4); + gtk_container_add (GTK_CONTAINER (menu_file_menu), open_nt4); + + open_gconf = gtk_image_menu_item_new_with_mnemonic ("_Open GConf"); + gtk_widget_show (open_gconf); + gtk_container_add (GTK_CONTAINER (menu_file_menu), open_gconf); + + open_remote = gtk_menu_item_new_with_mnemonic ("_Open Remote"); + gtk_widget_show (open_remote); + gtk_container_add (GTK_CONTAINER (menu_file_menu), open_remote); + + save = gtk_image_menu_item_new_from_stock ("gtk-save", accel_group); + gtk_widget_show (save); + gtk_widget_set_sensitive( save, False ); + gtk_container_add (GTK_CONTAINER (menu_file_menu), save); + + save_as = gtk_image_menu_item_new_from_stock ("gtk-save-as", accel_group); + gtk_widget_show (save_as); + gtk_widget_set_sensitive( save_as, False ); + gtk_container_add (GTK_CONTAINER (menu_file_menu), save_as); + + separatormenuitem1 = gtk_menu_item_new (); + gtk_widget_show (separatormenuitem1); + gtk_container_add (GTK_CONTAINER (menu_file_menu), separatormenuitem1); + gtk_widget_set_sensitive (separatormenuitem1, FALSE); + + quit = gtk_image_menu_item_new_from_stock ("gtk-quit", accel_group); + gtk_widget_show (quit); + gtk_container_add (GTK_CONTAINER (menu_file_menu), quit); + + men_edit = gtk_menu_item_new_with_mnemonic ("_Edit"); + gtk_widget_show (men_edit); + gtk_container_add (GTK_CONTAINER (menubar), men_edit); + + men_edit_menu = gtk_menu_new (); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (men_edit), men_edit_menu); + + cut = gtk_image_menu_item_new_from_stock ("gtk-cut", accel_group); + gtk_widget_show (cut); + gtk_widget_set_sensitive(cut, False); + gtk_container_add (GTK_CONTAINER (men_edit_menu), cut); + + copy = gtk_image_menu_item_new_from_stock ("gtk-copy", accel_group); + gtk_widget_show (copy); + gtk_widget_set_sensitive(copy, False); + gtk_container_add (GTK_CONTAINER (men_edit_menu), copy); + + paste = gtk_image_menu_item_new_from_stock ("gtk-paste", accel_group); + gtk_widget_show (paste); + gtk_widget_set_sensitive(paste, False); + gtk_container_add (GTK_CONTAINER (men_edit_menu), paste); + + delete = gtk_image_menu_item_new_from_stock ("gtk-delete", accel_group); + gtk_widget_show (delete); + gtk_widget_set_sensitive(delete, False); + gtk_container_add (GTK_CONTAINER (men_edit_menu), delete); + + help = gtk_menu_item_new_with_mnemonic ("_Help"); + gtk_widget_show (help); + gtk_container_add (GTK_CONTAINER (menubar), help); + + help_menu = gtk_menu_new (); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (help), help_menu); + + about = gtk_menu_item_new_with_mnemonic ("_About"); + gtk_widget_show (about); + gtk_container_add (GTK_CONTAINER (help_menu), about); + + hbox1 = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hbox1); + gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0); + + scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow1); + gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow1, TRUE, TRUE, 0); + + tree_keys = gtk_tree_view_new (); + + /* Column names */ + curcol = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title(curcol, "Name"); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(curcol, renderer, True); + + gtk_tree_view_append_column(GTK_TREE_VIEW(tree_keys), curcol); + + gtk_tree_view_column_add_attribute(curcol, renderer, "text", 0); + gtk_widget_show (tree_keys); + gtk_container_add (GTK_CONTAINER (scrolledwindow1), tree_keys); + store_keys = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER); + gtk_tree_view_set_model(GTK_TREE_VIEW(tree_keys), GTK_TREE_MODEL(store_keys)); + g_object_unref(store_keys); + + g_signal_connect ((gpointer) tree_keys, "row-activated", + G_CALLBACK (on_key_activate), + NULL); + + g_signal_connect ((gpointer) tree_keys, "row-expanded", + G_CALLBACK (expand_key), + NULL); + + scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolledwindow2); + gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow2, TRUE, TRUE, 0); + + tree_vals = gtk_tree_view_new (); + /* Column names */ + curcol = gtk_tree_view_column_new_with_attributes ("Name", gtk_cell_renderer_text_new(), NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(tree_vals), curcol); + + + curcol = gtk_tree_view_column_new_with_attributes ("Type", gtk_cell_renderer_text_new(), NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(tree_vals), curcol); + + curcol = gtk_tree_view_column_new_with_attributes ("Value", gtk_cell_renderer_text_new(), NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(tree_vals), curcol); + gtk_widget_show (tree_vals); + gtk_container_add (GTK_CONTAINER (scrolledwindow2), tree_vals); + + store_vals = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); + gtk_tree_view_set_model(GTK_TREE_VIEW(tree_vals), GTK_TREE_MODEL(store_vals)); + g_object_unref(store_vals); + + statusbar = gtk_statusbar_new (); + gtk_widget_show (statusbar); + gtk_box_pack_start (GTK_BOX (vbox1), statusbar, FALSE, FALSE, 0); + gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (statusbar), FALSE); + + g_signal_connect ((gpointer) open_nt4, "activate", + G_CALLBACK (on_open_nt4_activate), + NULL); + g_signal_connect ((gpointer) open_gconf, "activate", + G_CALLBACK (on_open_gconf_activate), + NULL); + g_signal_connect ((gpointer) open_remote, "activate", + G_CALLBACK (on_open_remote_activate), + NULL); + g_signal_connect ((gpointer) save, "activate", + G_CALLBACK (on_save_activate), + NULL); + g_signal_connect ((gpointer) save_as, "activate", + G_CALLBACK (on_save_as_activate), + NULL); + g_signal_connect ((gpointer) quit, "activate", + G_CALLBACK (on_quit_activate), + NULL); + g_signal_connect ((gpointer) cut, "activate", + G_CALLBACK (on_cut_activate), + NULL); + g_signal_connect ((gpointer) copy, "activate", + G_CALLBACK (on_copy_activate), + NULL); + g_signal_connect ((gpointer) paste, "activate", + G_CALLBACK (on_paste_activate), + NULL); + g_signal_connect ((gpointer) delete, "activate", + G_CALLBACK (on_delete_activate), + NULL); + g_signal_connect ((gpointer) about, "activate", + G_CALLBACK (on_about_activate), + NULL); + + gtk_window_add_accel_group (GTK_WINDOW (mainwin), accel_group); + + return mainwin; +} + +static GtkWidget* create_aboutwin (void) +{ + GtkWidget *dialog_vbox1; + GtkWidget *image1; + GtkWidget *label1; + GtkWidget *label2; + GtkWidget *dialog_action_area1; + GtkWidget *closebutton1; + + aboutwin = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (aboutwin), "About GRegEdit"); + gtk_window_set_resizable (GTK_WINDOW (aboutwin), FALSE); + + dialog_vbox1 = GTK_DIALOG (aboutwin)->vbox; + gtk_widget_show (dialog_vbox1); + + /* FIXME: Samba logo ? + image1 = create_pixmap (aboutwin, "samba.png"); + gtk_widget_show (image1); + gtk_box_pack_start (GTK_BOX (dialog_vbox1), image1, FALSE, TRUE, 0); */ + + label1 = gtk_label_new ("GRegEdit 0.1"); + gtk_widget_show (label1); + gtk_box_pack_start (GTK_BOX (dialog_vbox1), label1, FALSE, FALSE, 0); + gtk_label_set_use_markup (GTK_LABEL (label1), TRUE); + + label2 = gtk_label_new_with_mnemonic ("(C) 2004 Jelmer Vernooij \nPart of Samba\nhttp://www.samba.org/\n"); + gtk_widget_show (label2); + gtk_box_pack_start (GTK_BOX (dialog_vbox1), label2, TRUE, FALSE, 0); + gtk_label_set_use_markup (GTK_LABEL (label2), TRUE); + + dialog_action_area1 = GTK_DIALOG (aboutwin)->action_area; + gtk_widget_show (dialog_action_area1); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END); + + closebutton1 = gtk_button_new_from_stock ("gtk-close"); + gtk_widget_show (closebutton1); + gtk_dialog_add_action_widget (GTK_DIALOG (aboutwin), closebutton1, GTK_RESPONSE_CLOSE); + GTK_WIDGET_SET_FLAGS (closebutton1, GTK_CAN_DEFAULT); + + return aboutwin; +} + + +GtkWidget* create_openfilewin (void) +{ + GtkWidget *ok_button; + GtkWidget *cancel_button; + + openfilewin = gtk_file_selection_new ("Select File"); + gtk_container_set_border_width (GTK_CONTAINER (openfilewin), 10); + + ok_button = GTK_FILE_SELECTION (openfilewin)->ok_button; + gtk_widget_show (ok_button); + GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT); + + cancel_button = GTK_FILE_SELECTION (openfilewin)->cancel_button; + gtk_widget_show (cancel_button); + GTK_WIDGET_SET_FLAGS (cancel_button, GTK_CAN_DEFAULT); + + return openfilewin; +} + +GtkWidget* create_savefilewin (void) +{ + GtkWidget *ok_button; + GtkWidget *cancel_button; + + savefilewin = gtk_file_selection_new ("Select File"); + gtk_container_set_border_width (GTK_CONTAINER (savefilewin), 10); + + ok_button = GTK_FILE_SELECTION (savefilewin)->ok_button; + gtk_widget_show (ok_button); + GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT); + + cancel_button = GTK_FILE_SELECTION (savefilewin)->cancel_button; + gtk_widget_show (cancel_button); + GTK_WIDGET_SET_FLAGS (cancel_button, GTK_CAN_DEFAULT); + + return savefilewin; +} + +int main (int argc, char *argv[]) +{ + poptContext pc; + const char *backend = NULL, *credentials = NULL, *location; + int opt; + struct poptOption long_options[] = { + POPT_AUTOHELP + {"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL}, + {"credentials", 'c', POPT_ARG_STRING, &credentials, 0, "credentials (user%%password)", NULL}, + POPT_TABLEEND + }; + + gtk_init (&argc, &argv); + + pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); + + while((opt = poptGetNextOpt(pc)) != -1) { + } + + location = poptGetArg(pc); + + if(location) { + WERROR error; + + if(!backend) { + if(credentials)backend = "rpc"; + else backend = "nt4"; + } + + error = reg_open(backend, location, credentials, ®istry); + if(!W_ERROR_IS_OK(error)) { + gtk_show_werror(error); + return -1; + } + mainwin = create_mainwin (); + registry_load_root(); + } else + mainwin = create_mainwin (); + + gtk_widget_show (mainwin); + + gtk_main (); + + if(registry)reg_free(registry); + return 0; +} diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 9074d1c716..e6b5fa51ee 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -201,6 +201,7 @@ int main (int argc, char **argv) REG_HANDLE *h; struct poptOption long_options[] = { POPT_AUTOHELP + POPT_COMMON_SAMBA {"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL}, POPT_TABLEEND }; -- cgit From 9cbbf2d55253783adaeceac9bc2f8c9ffe40aa94 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 9 Apr 2004 00:02:20 +0000 Subject: r129: Convert other utilities to new API (This used to be commit 95c9852b1607335eb24025081a251139449fb695) --- source4/lib/registry/tools/regdiff.c | 93 ++++++++++++++++++++++++----------- source4/lib/registry/tools/regpatch.c | 77 ++++++++++++++++++++--------- source4/lib/registry/tools/regshell.c | 47 +++++++++++------- source4/lib/registry/tools/regtree.c | 33 ++++++++----- 4 files changed, 169 insertions(+), 81 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 5e2b97cb98..94cdf8c8af 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -24,41 +24,71 @@ void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) { int i, numkeys1, numvals1, numvals2, numkeys2; + REG_KEY *t1,*t2; + REG_VAL *v1, *v2; + WERROR error1, error2; - 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))) { + for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_subkey_by_index(oldkey, i, &t1)); i++) { + error2 = reg_key_get_subkey_by_name(newkey, reg_key_name(t1), &t2); + if(W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { fprintf(out, "-%s\n", reg_key_get_path(t1)+1); + } else if(!W_ERROR_IS_OK(error2)) { + DEBUG(0, ("Error occured while getting subkey by name: %d\n", error2)); } } - 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) { + if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { + DEBUG(0, ("Error occured while getting subkey by index: %d\n", error1)); + return; + } + + for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_subkey_by_index(newkey, i, &t1)); i++) { + error2 = reg_key_get_subkey_by_name(oldkey, reg_key_name(t1), &t2); + if(W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { fprintf(out, "\n[%s]\n", reg_key_get_path(t1)+1); + } else if(!W_ERROR_IS_OK(error2)) { + DEBUG(0, ("Error occured while getting subkey by name: %d\n", error2)); } writediff(t2, t1, out); } - numvals2 = reg_key_num_values(newkey); - for(i = 0; i < numvals2; i++) { - REG_VAL *t1 = reg_key_get_value_by_index(newkey, i); - REG_VAL *t2 = reg_key_get_value_by_name(oldkey, reg_val_name(t1)); - if(!t2 || reg_val_size(t2) != reg_val_size(t1) || memcmp(reg_val_data_blk(t1), reg_val_data_blk(t2), reg_val_size(t1))) { - fprintf(out, "\"%s\"=%s:%s\n", reg_val_name(t1), str_regtype(reg_val_type(t1)), reg_val_data_string(t1)); + if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { + DEBUG(0, ("Error occured while getting subkey by index: %d\n", error1)); + return; + } + + for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(newkey, i, &v1)); i++) { + error2 = reg_key_get_value_by_name(oldkey, reg_val_name(v1), &v2); + if ((W_ERROR_IS_OK(error2) && reg_val_size(v2) != reg_val_size(v1) || memcmp(reg_val_data_blk(v1), reg_val_data_blk(v2), reg_val_size(v1))) + || W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { + fprintf(out, "\"%s\"=%s:%s\n", reg_val_name(v1), str_regtype(reg_val_type(v1)), reg_val_data_string(v1)); + } + + if(!W_ERROR_IS_OK(error2) && !W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { + DEBUG(0, ("Error occured while getting value by name: %d\n", error2)); } } - numvals1 = reg_key_num_values(oldkey); - for(i = 0; i < numvals1; i++) { - REG_VAL *t1 = reg_key_get_value_by_index(oldkey, i); - if(!reg_key_get_value_by_name(newkey, reg_val_name(t1))) { - fprintf(out, "\"%s\"=-\n", reg_val_name(t1)); + if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { + DEBUG(0, ("Error occured while getting value by index: %d\n", error1)); + return; + } + + + for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(oldkey, i, &v1)); i++) { + error2 = reg_key_get_value_by_name(newkey, reg_val_name(v1), &v2); + if(W_ERROR_IS_OK(error2)) { + } else if(W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { + fprintf(out, "\"%s\"=-\n", reg_val_name(v1)); + } else { + DEBUG(0, ("Error occured while getting value by name: %d\n", error2)); } } + + if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { + DEBUG(0, ("Error occured while getting value by index: %d\n", error1)); + return; + } } int main (int argc, char **argv) @@ -69,15 +99,18 @@ int main (int argc, char **argv) REG_KEY *root; const char *backend1 = NULL, *backend2 = NULL; const char *location2; + const char *credentials1= NULL, *credentials2 = NULL; char *outputfile = NULL; FILE *fd = stdout; REG_HANDLE *h2; REG_KEY *root1 = NULL, *root2; int from_null = 0; int fullpath = 0, no_values = 0; + WERROR error; struct poptOption long_options[] = { POPT_AUTOHELP {"backend", 'b', POPT_ARG_STRING, NULL, 'b', "backend to use", NULL}, + {"credentials", 'c', POPT_ARG_STRING, NULL, 'c', "credentials", NULL}, {"output", 'o', POPT_ARG_STRING, &outputfile, 'o', "output file to use", NULL }, {"null", 'n', POPT_ARG_NONE, &from_null, 'n', "Diff from NULL" }, POPT_TABLEEND @@ -87,7 +120,11 @@ int main (int argc, char **argv) while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { - case 'b': + case 'c': + if(!credentials1 && !from_null) credentials1 = poptGetOptArg(pc); + else if(!credentials2) credentials2 = poptGetOptArg(pc); + break; + case 'b': if(!backend1 && !from_null) backend1 = poptGetOptArg(pc); else if(!backend2) backend2 = poptGetOptArg(pc); break; @@ -106,13 +143,13 @@ int main (int argc, char **argv) if(!backend1) backend1 = "dir"; - h1 = reg_open(backend1, location1, True); - if(!h1) { + error = reg_open(backend1, location1, credentials1, &h1); + if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location1, backend1); return 1; } - root1 = reg_get_root(h1); + if(!W_ERROR_IS_OK(reg_get_root(h1, &root1))) return 1; } location2 = poptGetArg(pc); @@ -123,14 +160,14 @@ int main (int argc, char **argv) if(!backend2) backend2 = "dir"; - h2 = reg_open(backend2, location2, True); - if(!h2) { + error = reg_open(backend2, location2, credentials2, &h2); + if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location2, backend2); return 1; } - root2 = reg_get_root(h2); - if(!root2) { + error = reg_get_root(h2, &root2); + if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Can't open root key for '%s:%s'\n", backend2, location2); return 1; } diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 27f578e37f..9a51b0f7ff 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -664,11 +664,13 @@ static CMD_FILE *cmd_file_create(const char *file) char *str_type(unsigned char type); -int nt_apply_reg_command_file(REG_HANDLE *regf, const char *cmd_file_name) +int nt_apply_reg_command_file(REG_KEY *root, const char *cmd_file_name) { CMD *cmd; - int modified = 0; + BOOL modified = False; CMD_FILE *cmd_file = NULL; + REG_KEY *tmp = NULL; + WERROR error; cmd_file = cmd_file_create(cmd_file_name); while ((cmd = cmd_file->cmd_ops.get_cmd(cmd_file->fd)) != NULL) { @@ -677,17 +679,22 @@ int nt_apply_reg_command_file(REG_HANDLE *regf, const char *cmd_file_name) * Now, apply the requests to the tree ... */ switch (cmd->cmd) { - case CMD_ADD_KEY: { - REG_KEY *tmp = NULL; - tmp = reg_open_key(reg_get_root(regf), cmd->key); + case CMD_ADD_KEY: + error = reg_open_key(root, cmd->key, &tmp); + /* 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); + if (W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) { + if(W_ERROR_IS_OK(reg_key_add_name_recursive(root, cmd->key))) { + error = reg_open_key(root, cmd->key, &tmp); + if(!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error finding new key '%s' after it has been added\n", cmd->key)); + continue; + } } else { DEBUG(0, ("Error adding new key '%s'\n", cmd->key)); + continue; } - modified = 1; + modified = True; } while (cmd->val_count) { @@ -695,15 +702,21 @@ int nt_apply_reg_command_file(REG_HANDLE *regf, const char *cmd_file_name) 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; + error = reg_key_get_value_by_name( tmp, val->name, ®_val); + if(W_ERROR_IS_OK(error)) { + error = reg_val_del(reg_val); + } + if(!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error removing value '%s'\n", val->name)); + } + modified = True; } else { - /* FIXME - reg_val = nt_add_reg_value(tmp, val->name, val->type, - val->val); */ - modified = 1; + if(!W_ERROR_IS_OK(reg_key_add_value(tmp, val->name, val->type, val->val, strlen(val->val)))) { + DEBUG(0, ("Error adding new value '%s'\n", val->name)); + continue; + } + modified = True; } cmd->val_spec_list = val->next; @@ -712,7 +725,6 @@ int nt_apply_reg_command_file(REG_HANDLE *regf, const char *cmd_file_name) } break; - } case CMD_DEL_KEY: /* @@ -720,8 +732,18 @@ int nt_apply_reg_command_file(REG_HANDLE *regf, const char *cmd_file_name) * Find the key if it exists, and delete it ... */ - reg_key_del_recursive(reg_open_key(reg_get_root(regf), cmd->key)); - modified = 1; + error = reg_open_key(root, cmd->key, &tmp); + if(!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Unable to open key '%s'\n", cmd->key)); + continue; + } + + error = reg_key_del_recursive(tmp); + if(!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Unable to delete key '%s'\n", cmd->key)); + continue; + } + modified = True; break; } } @@ -737,13 +759,16 @@ int main (int argc, char **argv) poptContext pc; REG_KEY *root; const char *location; + const char *credentials = NULL; const char *patch; - char *backend = "dir"; + const char *backend = "dir"; REG_HANDLE *h; int fullpath = 0, no_values = 0; + WERROR error; struct poptOption long_options[] = { POPT_AUTOHELP {"backend", 'b', POPT_ARG_STRING, &backend, 'b', "backend to use", NULL}, + {"credentials", 'c', POPT_ARG_STRING, &credentials, 'c', "credentials (user%password", NULL}, POPT_TABLEEND }; @@ -760,7 +785,7 @@ int main (int argc, char **argv) return 1; } - h = reg_open(backend, location, True); + error = reg_open(backend, location, credentials, &h); if(!h) { fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location, backend); return 1; @@ -770,7 +795,15 @@ int main (int argc, char **argv) if(!patch) patch = "/dev/stdin"; poptFreeContext(pc); - nt_apply_reg_command_file(h, patch); + error = reg_get_root(h, &root); + if(!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error opening root!\n")); + return 1; + } + + nt_apply_reg_command_file(root, patch); + + reg_free(h); return 0; } diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index e6b5fa51ee..d60ca1ff46 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -40,10 +40,14 @@ static REG_KEY *cmd_set(REG_KEY *cur, int argc, char **argv) static REG_KEY *cmd_ck(REG_KEY *cur, int argc, char **argv) { REG_KEY *new; + WERROR error; if(argc < 2) { new = cur; } else { - new = reg_open_key(cur, argv[1]); + error = reg_open_key(cur, argv[1], &new); + if(!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error opening specified key\n")); + } } if(!new) new = cur; @@ -56,28 +60,32 @@ static REG_KEY *cmd_ck(REG_KEY *cur, int argc, char **argv) static REG_KEY *cmd_ls(REG_KEY *cur, int argc, char **argv) { int i, num; - num = reg_key_num_subkeys(cur); - for(i = 0; i < num; i++) { - REG_KEY *sub = reg_key_get_subkey_by_index(cur, i); + WERROR error; + REG_VAL *value; + REG_KEY *sub; + for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(cur, i, &sub)); i++) { printf("K %s\n", reg_key_name(sub)); } - num = reg_key_num_values(cur); - for(i = 0; i < num; i++) { - REG_VAL *sub = reg_key_get_value_by_index(cur, i); - printf("V %s %s %s\n", reg_val_name(sub), str_regtype(reg_val_type(sub)), reg_val_data_string(sub)); + if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { + DEBUG(0, ("Error occured while browsing thru keys\n")); + } + + for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(cur, i, &value)); i++) { + printf("V \"%s\" %s %s\n", reg_val_name(value), str_regtype(reg_val_type(value)), reg_val_data_string(value)); } return NULL; } static REG_KEY *cmd_mkkey(REG_KEY *cur, int argc, char **argv) { + REG_KEY *tmp; if(argc < 2) { fprintf(stderr, "Usage: mkkey \n"); return NULL; } - if(!reg_key_add_name(cur, argv[1])) { + if(!W_ERROR_IS_OK(reg_key_add_name(cur, argv[1], 0, NULL, &tmp))) { fprintf(stderr, "Error adding new subkey '%s'\n", argv[1]); return NULL; } @@ -95,13 +103,12 @@ static REG_KEY *cmd_rmkey(REG_KEY *cur, int argc, char **argv) return NULL; } - key = reg_open_key(cur, argv[1]); - if(!key) { + if(!W_ERROR_IS_OK(reg_open_key(cur, argv[1], &key))) { fprintf(stderr, "No such subkey '%s'\n", argv[1]); return NULL; } - if(!reg_key_del(key)) { + if(!W_ERROR_IS_OK(reg_key_del(key))) { fprintf(stderr, "Error deleting '%s'\n", argv[1]); } else { fprintf(stderr, "Successfully deleted '%s'\n", argv[1]); @@ -118,13 +125,12 @@ static REG_KEY *cmd_rmval(REG_KEY *cur, int argc, char **argv) return NULL; } - val = reg_key_get_value_by_name(cur, argv[1]); - if(!val) { + if(!W_ERROR_IS_OK(reg_key_get_value_by_name(cur, argv[1], &val))) { fprintf(stderr, "No such value '%s'\n", argv[1]); return NULL; } - if(!reg_val_del(val)) { + if(!W_ERROR_IS_OK(reg_val_del(val))) { fprintf(stderr, "Error deleting value '%s'\n", argv[1]); } else { fprintf(stderr, "Successfully deleted value '%s'\n", argv[1]); @@ -196,13 +202,16 @@ int main (int argc, char **argv) uint32 setparms, checkparms; int opt; char *backend = "dir"; + char *credentials = NULL; REG_KEY *curkey = NULL;; poptContext pc; + WERROR error; REG_HANDLE *h; struct poptOption long_options[] = { POPT_AUTOHELP POPT_COMMON_SAMBA {"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL}, + {"credentials", 'c', POPT_ARG_STRING, &credentials, 0, "credentials", NULL}, POPT_TABLEEND }; @@ -211,8 +220,8 @@ int main (int argc, char **argv) while((opt = poptGetNextOpt(pc)) != -1) { } - h = reg_open(backend, poptPeekArg(pc), True); - if(!h) { + error = reg_open(backend, poptPeekArg(pc), credentials, &h); + if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open '%s' with backend '%s'\n", poptGetArg(pc), backend); return 1; } @@ -220,9 +229,9 @@ int main (int argc, char **argv) setup_logging("regtree", True); - curkey = reg_get_root(h); + error = reg_get_root(h, &curkey); - if(!curkey) return 1; + if(!W_ERROR_IS_OK(error)) return 1; while(True) { char *line, *prompt; diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 80cbccf48f..548a702d48 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -23,31 +23,38 @@ void print_tree(int l, REG_KEY *p, int fullpath, int novals) { - int num_subkeys, i, num_values; + REG_KEY *subkey; + REG_VAL *value; + WERROR error; + int i; for(i = 0; i < l; i++) putchar(' '); if(fullpath) printf("%s\n", reg_key_get_path(p)); else printf("%s\n", reg_key_name(p)); - num_subkeys = reg_key_num_subkeys(p); - for(i = 0; i < num_subkeys; i++) { - REG_KEY *subkey = reg_key_get_subkey_by_index(p, i); + for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(p, i, &subkey)); i++) { print_tree(l+1, subkey, fullpath, novals); reg_key_free(subkey); } + if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { + DEBUG(0, ("Error occured while fetching subkeys for '%s'\n", reg_key_get_path(p))); + } + if(!novals) { - num_values = reg_key_num_values(p); - for(i = 0; i < num_values; i++) { + for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(p, i, &value)); i++) { int j; char *desc; - REG_VAL *value = reg_key_get_value_by_index(p, i); for(j = 0; j < l+1; j++) putchar(' '); desc = reg_val_description(value); printf("%s\n", desc); free(desc); reg_val_free(value); } + + if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { + DEBUG(0, ("Error occured while fetching subkeys for '%s'\n", reg_key_get_path(p))); + } } } @@ -55,15 +62,17 @@ int main (int argc, char **argv) { uint32 setparms, checkparms; int opt; - char *backend = "dir"; + char *backend = "dir", *credentials = NULL; poptContext pc; REG_KEY *root; REG_HANDLE *h; + WERROR error; int fullpath = 0, no_values = 0; struct poptOption long_options[] = { POPT_AUTOHELP {"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL}, {"fullpath", 'f', POPT_ARG_NONE, &fullpath, 0, "show full paths", NULL}, + {"credentials", 'c', POPT_ARG_NONE, &credentials, 0, "credentials (user%password)", NULL}, {"no-values", 'V', POPT_ARG_NONE, &no_values, 0, "don't show values", NULL}, POPT_TABLEEND }; @@ -75,15 +84,15 @@ int main (int argc, char **argv) setup_logging("regtree", True); - h = reg_open(backend, poptPeekArg(pc), True); - if(!h) { + error = reg_open(backend, poptPeekArg(pc), credentials, &h); + if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open '%s' with backend '%s'\n", poptGetArg(pc), backend); return 1; } poptFreeContext(pc); - root = reg_get_root(h); - if(!root) return 1; + error = reg_get_root(h, &root); + if(!W_ERROR_IS_OK(error)) return 1; print_tree(0, root, fullpath, no_values); -- cgit From 42889e5e1e276c8957cc666991364c6f0b6bdc79 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 9 Apr 2004 08:06:39 +0000 Subject: r134: - added ldb to the build of smbd - fixed build of the ldb registry backend (This used to be commit 0b66590330603efaa816fd2348c05a994a1580ef) --- source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index 3cc1651519..9e561b1e6c 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -20,7 +20,6 @@ #include "includes.h" #include "lib/registry/common/registry.h" -#include "lib/ldb/include/ldb.h" char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path) { @@ -81,7 +80,7 @@ static WERROR ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys) /* FIXME */ } - ldap_search_free(c, msg); + ldb_search_free(c, msg); talloc_destroy(mem_ctx); return WERR_OK; } @@ -103,7 +102,7 @@ static WERROR ldb_open_key(REG_HANDLE *h, const char *name, REG_KEY **key) /* FIXME */ } - ldap_search_free(c, msg); + ldb_search_free(c, msg); talloc_destroy(mem_ctx); return WERR_OK;; -- cgit From 491ce98cc4b794f5c23eabc88004e9540c011fd5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 Apr 2004 14:24:47 +0000 Subject: r162: Minor bugfixes: - Don't keep windows open after errors - Don't build ldb backend by default (This used to be commit 1bb64782c6585c02b8792d23b97d3da60aac844c) --- source4/lib/registry/config.m4 | 2 +- source4/lib/registry/tools/gregedit.c | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index 90dc50728b..c00b7cc507 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -14,6 +14,6 @@ SMB_MODULE(reg_nt4, REG, STATIC, lib/registry/reg_backend_nt4/reg_backend_nt4.o) SMB_MODULE(reg_dir, REG, STATIC, lib/registry/reg_backend_dir/reg_backend_dir.o) SMB_MODULE(reg_rpc, REG, STATIC, lib/registry/reg_backend_rpc/reg_backend_rpc.o) SMB_MODULE(reg_gconf, REG, NOT, lib/registry/reg_backend_gconf/reg_backend_gconf.o, [], [$GCONF_LIBS]) -SMB_MODULE(reg_ldb, REG, STATIC, lib/registry/reg_backend_ldb/reg_backend_ldb.o) +SMB_MODULE(reg_ldb, REG, NOT, lib/registry/reg_backend_ldb/reg_backend_ldb.o) SMB_SUBSYSTEM(REG,lib/registry/common/reg_interface.o,[lib/registry/common/reg_objects.o lib/registry/common/reg_util.o],lib/registry/common/winregistry_proto.h,[]) AC_CONFIG_FILES(lib/registry/winregistry.pc) diff --git a/source4/lib/registry/tools/gregedit.c b/source4/lib/registry/tools/gregedit.c index b62fd7ec04..2d145e699a 100644 --- a/source4/lib/registry/tools/gregedit.c +++ b/source4/lib/registry/tools/gregedit.c @@ -242,7 +242,6 @@ GtkWidget* create_rpcwin (void) return rpcwin; } - static void on_open_nt4_activate (GtkMenuItem *menuitem, gpointer user_data) { gint result = gtk_dialog_run(GTK_DIALOG(create_openfilewin())); @@ -254,7 +253,7 @@ static void on_open_nt4_activate (GtkMenuItem *menuitem, gpointer user_data) error = reg_open("nt4", filename, NULL, ®istry); if(!W_ERROR_IS_OK(error)) { gtk_show_werror(error); - return; + break; } registry_load_root(); break; @@ -291,7 +290,7 @@ on_open_remote_activate (GtkMenuItem *menuitem, error = reg_open("rpc", location, credentials, ®istry); if(!W_ERROR_IS_OK(error)) { gtk_show_werror(error); - return; + break; } free(location); free(credentials); registry_load_root(); -- cgit From 6df152f96495e68426a52bf62be2c44900b7e8cf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 Apr 2004 15:34:18 +0000 Subject: r164: Viewing remote registries with gregedit works now (This used to be commit 697560a117ba19bb44539d6d63cc9143127e29d1) --- source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c | 4 ++-- source4/lib/registry/tools/regtree.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') 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 e61301d6f2..7c30302e84 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -47,7 +47,7 @@ static void init_winreg_String(struct winreg_String *name, const char *s) r.out.handle = hnd;\ \ if (!NT_STATUS_IS_OK(dcerpc_winreg_Open ## u(p, h->mem_ctx, &r))) {\ - printf("Error executing open\n");\ + DEBUG(0,("Error executing open\n"));\ return NULL;\ }\ \ @@ -89,7 +89,7 @@ static WERROR rpc_open_registry(REG_HANDLE *h, const char *location, const char user = talloc_strdup(h->mem_ctx, credentials); pass = strchr(user, '%'); *pass = '\0'; pass++; - + ZERO_STRUCTP(mydata); status = dcerpc_pipe_connect(&mydata->pipe, binding, diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 548a702d48..b8a5f50496 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -72,7 +72,7 @@ int main (int argc, char **argv) POPT_AUTOHELP {"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL}, {"fullpath", 'f', POPT_ARG_NONE, &fullpath, 0, "show full paths", NULL}, - {"credentials", 'c', POPT_ARG_NONE, &credentials, 0, "credentials (user%password)", NULL}, + {"credentials", 'c', POPT_ARG_STRING, &credentials, 0, "credentials (user%password)", NULL}, {"no-values", 'V', POPT_ARG_NONE, &no_values, 0, "don't show values", NULL}, POPT_TABLEEND }; @@ -86,7 +86,7 @@ int main (int argc, char **argv) error = reg_open(backend, poptPeekArg(pc), credentials, &h); if(!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Unable to open '%s' with backend '%s'\n", poptGetArg(pc), backend); + fprintf(stderr, "Unable to open '%s' with backend '%s':%s \n", poptGetArg(pc), backend, win_errstr(error)); return 1; } poptFreeContext(pc); -- cgit From 07afafd45df34c4617c9e3e31bcd3130a9e255e3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 Apr 2004 16:04:06 +0000 Subject: r165: Add support for viewing registry values in gregedit (This used to be commit 1d8a6d762aa4dab54bb58959cb1e7957a76e5b6e) --- source4/lib/registry/TODO | 3 ++ source4/lib/registry/tools/gregedit.c | 63 ++++++++++++++++++++--------------- 2 files changed, 40 insertions(+), 26 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/TODO b/source4/lib/registry/TODO index fc741cea40..f84b1c5339 100644 --- a/source4/lib/registry/TODO +++ b/source4/lib/registry/TODO @@ -19,6 +19,9 @@ reg_backend_ldb: reg_backend_wine.c: - finish +regshell: + - support for security descriptors + gregedit.c: - support for editing values / adding values / deleting values - support for adding/deleting keys diff --git a/source4/lib/registry/tools/gregedit.c b/source4/lib/registry/tools/gregedit.c index 2d145e699a..51fad4287d 100644 --- a/source4/lib/registry/tools/gregedit.c +++ b/source4/lib/registry/tools/gregedit.c @@ -63,23 +63,6 @@ static void gtk_show_werror(WERROR err) gtk_widget_destroy (dialog); } -static void treeview_add_val(REG_VAL *val) -{ - GtkTreeIter iter; - gtk_list_store_append(store_vals, &iter); - gtk_list_store_set (store_vals, - &iter, - 0, - reg_val_name(val), - 1, - str_regtype(reg_val_type(val)), - 2, - reg_val_data_string(val), - 3, - val, - -1); -} - static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath *arg2) { GtkTreeIter iter, tmpiter; @@ -394,18 +377,32 @@ void on_key_activate (GtkTreeView *treeview, REG_KEY *k; REG_VAL *val; WERROR error; + GtkTreeIter parent; -//FIXME gtk_tree_model_get(GTK_TREE_MODEL(store_keys), iter, 1, &k, -1); + gtk_tree_model_get_iter(GTK_TREE_MODEL(store_keys), &parent, path); + gtk_tree_model_get(GTK_TREE_MODEL(store_keys), &parent, 1, &k, -1); + + g_assert(k); gtk_list_store_clear(store_vals); for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(k, i, &val)); i++) { - treeview_add_val(val); + GtkTreeIter iter; + gtk_list_store_append(store_vals, &iter); + gtk_list_store_set (store_vals, + &iter, + 0, + reg_val_name(val), + 1, + str_regtype(reg_val_type(val)), + 2, + reg_val_data_string(val), + 3, + val, + -1); } if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) gtk_show_werror(error); - - return; } GtkWidget* create_mainwin (void) @@ -567,15 +564,29 @@ GtkWidget* create_mainwin (void) tree_vals = gtk_tree_view_new (); /* Column names */ - curcol = gtk_tree_view_column_new_with_attributes ("Name", gtk_cell_renderer_text_new(), NULL); + + curcol = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title(curcol, "Name"); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(curcol, renderer, True); gtk_tree_view_append_column(GTK_TREE_VIEW(tree_vals), curcol); + gtk_tree_view_column_add_attribute(curcol, renderer, "text", 0); - - curcol = gtk_tree_view_column_new_with_attributes ("Type", gtk_cell_renderer_text_new(), NULL); + curcol = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title(curcol, "Type"); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(curcol, renderer, True); gtk_tree_view_append_column(GTK_TREE_VIEW(tree_vals), curcol); - - curcol = gtk_tree_view_column_new_with_attributes ("Value", gtk_cell_renderer_text_new(), NULL); + gtk_tree_view_column_add_attribute(curcol, renderer, "text", 1); + + curcol = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title(curcol, "Value"); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(curcol, renderer, True); gtk_tree_view_append_column(GTK_TREE_VIEW(tree_vals), curcol); + gtk_tree_view_column_add_attribute(curcol, renderer, "text", 2); + + gtk_widget_show (tree_vals); gtk_container_add (GTK_CONTAINER (scrolledwindow2), tree_vals); -- cgit From c60c5ebb910a77f6f3f345093794637714eb66e2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 Apr 2004 16:37:06 +0000 Subject: r166: Fix enumerating values in nt4 backend (This used to be commit 1a7de762c60177b6e250f81cdeb3466fce148bff) --- source4/lib/registry/common/reg_interface.c | 1 + source4/lib/registry/common/registry.h | 1 + source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c | 4 ++++ 3 files changed, 6 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 9c78ae55fb..5e6b4fbac8 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -98,6 +98,7 @@ WERROR reg_open(const char *backend, const char *location, const char *credentia ret = talloc(mem_ctx, sizeof(REG_HANDLE)); ZERO_STRUCTP(ret); ret->location = location?talloc_strdup(mem_ctx, location):NULL; + ret->credentials = credentials?talloc_strdup(mem_ctx, credentials):NULL; ret->functions = entry->functions; ret->backend_data = NULL; ret->mem_ctx = mem_ctx; diff --git a/source4/lib/registry/common/registry.h b/source4/lib/registry/common/registry.h index 6e12de258d..9d7e17cf56 100644 --- a/source4/lib/registry/common/registry.h +++ b/source4/lib/registry/common/registry.h @@ -121,6 +121,7 @@ struct reg_handle_s { struct registry_ops *functions; REG_SUBTREE *subtrees; char *location; + char *credentials; void *backend_data; TALLOC_CTX *mem_ctx; }; diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index 9d90523a75..a7e5051ce4 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -1697,12 +1697,16 @@ static WERROR nt_value_by_index(REG_KEY *k, int n, REG_VAL **value) { VL_TYPE *vl; int val_off, vk_off; + int val_count; VK_HDR *vk_hdr; REGF *regf = k->handle->backend_data; NK_HDR *nk_hdr = k->backend_data; + val_count = IVAL(&nk_hdr->val_cnt,0); val_off = IVAL(&nk_hdr->val_off,0); vl = (VL_TYPE *)LOCN(regf->base, val_off); DEBUG(2, ("Val List Offset: %0X\n", val_off)); + if(n < 0) return WERR_INVALID_PARAM; + if(n >= val_count) return WERR_NO_MORE_ITEMS; vk_off = IVAL(&vl[n],0); vk_hdr = (VK_HDR *)LOCN(regf->base, vk_off); -- cgit From 639afabf404d469638bc521b8a7f37e541ccf834 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 Apr 2004 23:16:47 +0000 Subject: r168: - Cleanups in rpc backend - Small fixess in nt4 and dir backends - Start on w95 file backend (This used to be commit aa739e8d3c7108f6f2089af2d8d522feacc7f698) --- source4/lib/registry/common/reg_interface.c | 49 ++++- source4/lib/registry/common/registry.h | 4 +- source4/lib/registry/config.m4 | 1 + .../lib/registry/reg_backend_dir/reg_backend_dir.c | 15 +- .../lib/registry/reg_backend_nt4/reg_backend_nt4.c | 33 ++-- .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 216 +++++++-------------- .../lib/registry/reg_backend_w95/reg_backend_w95.c | 170 ++++++++++++++++ source4/lib/registry/tools/gregedit.c | 11 +- 8 files changed, 307 insertions(+), 192 deletions(-) create mode 100644 source4/lib/registry/reg_backend_w95/reg_backend_w95.c (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 5e6b4fbac8..917b03cf32 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -214,7 +214,11 @@ WERROR reg_key_num_subkeys(REG_KEY *key, int *count) { if(!key) return WERR_INVALID_PARAM; - if(!key->handle->functions->num_subkeys) { + if(key->handle->functions->num_subkeys) { + return key->handle->functions->num_subkeys(key, count); + } + + if(key->handle->functions->fetch_subkeys) { if(!key->cache_subkeys) key->handle->functions->fetch_subkeys(key, &key->cache_subkeys_count, &key->cache_subkeys); @@ -222,7 +226,20 @@ WERROR reg_key_num_subkeys(REG_KEY *key, int *count) return WERR_OK; } - return key->handle->functions->num_subkeys(key, count); + if(key->handle->functions->get_subkey_by_index) { + int i; + WERROR error; + REG_KEY *dest; + for(i = 0; W_ERROR_IS_OK(error = key->handle->functions->get_subkey_by_index(key, i, &dest)); i++) { + reg_key_free(dest); + } + + *count = i; + if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) return WERR_OK; + return error; + } + + return WERR_NOT_SUPPORTED; } WERROR reg_key_num_values(REG_KEY *key, int *count) @@ -306,8 +323,7 @@ WERROR reg_key_get_subkey_by_name(REG_KEY *key, const char *name, REG_KEY **subk WERROR reg_key_get_value_by_name(REG_KEY *key, const char *name, REG_VAL **val) { - int i, max; - REG_VAL *ret = NULL; + int i; WERROR error = WERR_OK; if(!key) return WERR_INVALID_PARAM; @@ -361,7 +377,6 @@ WERROR reg_sync(REG_KEY *h, const char *location) WERROR reg_key_del_recursive(REG_KEY *key) { - BOOL succeed = True; WERROR error = WERR_OK; int i; @@ -543,3 +558,27 @@ WERROR reg_save(REG_HANDLE *h, const char *location) /* FIXME */ return WERR_NOT_SUPPORTED; } + +WERROR reg_key_get_parent(REG_KEY *key, REG_KEY **parent) +{ + char *parent_name; + char *last; + REG_KEY *root; + WERROR error; + + error = reg_get_root(key->handle, &root); + if(!W_ERROR_IS_OK(error)) return error; + + parent_name = strdup(reg_key_get_path(key)); + last = strrchr(parent_name, '\\'); + + if(!last) { + SAFE_FREE(parent_name); + return WERR_FOOBAR; + } + *last = '\0'; + + error = reg_open_key(root, parent_name, parent); + SAFE_FREE(parent_name); + return error; +} diff --git a/source4/lib/registry/common/registry.h b/source4/lib/registry/common/registry.h index 9d7e17cf56..208bcae1e1 100644 --- a/source4/lib/registry/common/registry.h +++ b/source4/lib/registry/common/registry.h @@ -58,8 +58,8 @@ struct reg_val_s { }; /* FIXME */ -typedef void (*key_notification_function) (); -typedef void (*value_notification_function) (); +typedef void (*key_notification_function) (void); +typedef void (*value_notification_function) (void); /* diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index c00b7cc507..d8acb26397 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -11,6 +11,7 @@ PKG_CHECK_MODULES(GCONF, gconf-2.0, [ SMB_MODULE_DEFAULT(reg_gconf,STATIC) PKG_CHECK_MODULES(GTK, glib-2.0 gtk+-2.0, [ CFLAGS="$CFLAGS $GTK_CFLAGS"; ], [ AC_MSG_WARN([Will be unable to build gregedit])]) SMB_MODULE(reg_nt4, REG, STATIC, lib/registry/reg_backend_nt4/reg_backend_nt4.o) +SMB_MODULE(reg_w95, REG, STATIC, lib/registry/reg_backend_w95/reg_backend_w95.o) SMB_MODULE(reg_dir, REG, STATIC, lib/registry/reg_backend_dir/reg_backend_dir.o) SMB_MODULE(reg_rpc, REG, STATIC, lib/registry/reg_backend_rpc/reg_backend_rpc.o) SMB_MODULE(reg_gconf, REG, NOT, lib/registry/reg_backend_gconf/reg_backend_gconf.o, [], [$GCONF_LIBS]) 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 4daaf3d628..375daa319b 100644 --- a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c @@ -21,7 +21,7 @@ #include "includes.h" #include "lib/registry/common/registry.h" -static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *desc) +static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *desc, REG_KEY **result) { char *path; int ret; @@ -29,7 +29,7 @@ static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32 access_m path = reg_path_win2unix(path); ret = mkdir(path, 0700); SAFE_FREE(path); - if(ret == 0)return WERR_OK; + if(ret == 0)return WERR_OK; /* FIXME */ return WERR_INVALID_PARAM; } @@ -83,7 +83,6 @@ static WERROR reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r) if(e->d_type == DT_DIR && strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) { - char *newfullpath; ar[(*count)] = reg_key_new_rel(e->d_name, k, NULL); ar[(*count)]->backend_data = talloc_asprintf(ar[*count]->mem_ctx, "%s/%s", fullpath, e->d_name); if(ar[(*count)])(*count)++; @@ -106,16 +105,8 @@ static WERROR reg_dir_open(REG_HANDLE *h, const char *loc, const char *credentia return WERR_OK; } -static WERROR reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len, REG_VAL **value) +static WERROR reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len) { - char *fullpath; - FILE *fd; - *value = reg_val_new(p, NULL); - (*value)->name = name?talloc_strdup((*value)->mem_ctx, name):NULL; - fullpath = reg_path_win2unix(strdup(reg_val_get_path(*value))); - - fd = fopen(fullpath, "w+"); - /* FIXME */ return WERR_NOT_SUPPORTED; } diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index a7e5051ce4..fd91b4fbe6 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -165,7 +165,7 @@ Offset Size Contents To determine the number of values, you have to look at the owner-nk-record! -Der vk-Record +The vk-Record ============= Offset Size Contents 0x0000 Word ID: ASCII-"vk" = 0x6B76 @@ -473,7 +473,7 @@ typedef struct regf_struct_s { int fd; struct stat sbuf; char *base; - int modified; + BOOL modified; NTTIME last_mod_time; NK_HDR *first_key; int sk_count, sk_map_size; @@ -485,7 +485,6 @@ typedef struct regf_struct_s { * keys when we are preparing to write them to a file */ HBIN_BLK *blk_head, *blk_tail, *free_space; - TALLOC_CTX *mem_ctx; } REGF; DWORD str_to_dword(const char *a) { @@ -886,7 +885,6 @@ static WERROR vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size, REG_VAL **val char val_name[1024]; REGF *regf = parent->handle->backend_data; int nam_len, dat_len, flag, dat_type, dat_off, vk_id; - const char *val_type; REG_VAL *tmp = NULL; if (!vk_hdr) return WERR_INVALID_PARAM; @@ -1021,7 +1019,7 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent { REGF *regf = h->backend_data; REG_KEY *tmp = NULL, *own; - int name_len, clsname_len, sk_off, own_off; + int namlen, clsname_len, sk_off, own_off; unsigned int nk_id; SK_HDR *sk_hdr; int type; @@ -1037,32 +1035,32 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent SMB_REG_ASSERT(size < 0); - name_len = SVAL(&nk_hdr->nam_len,0); + namlen = SVAL(&nk_hdr->nam_len,0); clsname_len = SVAL(&nk_hdr->clsnam_len,0); /* * The value of -size should be ge - * (sizeof(NK_HDR) - 1 + name_len) + * (sizeof(NK_HDR) - 1 + namlen) * The -1 accounts for the fact that we included the first byte of * the name in the structure. clsname_len is the length of the thing * pointed to by clsnam_off */ - if (-size < (sizeof(NK_HDR) - 1 + name_len)) { + if (-size < (sizeof(NK_HDR) - 1 + namlen)) { DEBUG(0, ("Incorrect NK_HDR size: %d, %0X\n", -size, (int)nk_hdr)); DEBUG(0, ("Sizeof NK_HDR: %d, name_len %d, clsname_len %d\n", - sizeof(NK_HDR), name_len, clsname_len)); + sizeof(NK_HDR), namlen, clsname_len)); return WERR_GENERAL_FAILURE; } - DEBUG(2, ("NK HDR: Name len: %d, class name len: %d\n", name_len, clsname_len)); + DEBUG(2, ("NK HDR: Name len: %d, class name len: %d\n", namlen, clsname_len)); /* Fish out the key name and process the LF list */ - SMB_REG_ASSERT(name_len < sizeof(key_name)); + SMB_REG_ASSERT(namlen < sizeof(key_name)); - strncpy(key_name, nk_hdr->key_nam, name_len); - key_name[name_len] = '\0'; + strncpy(key_name, nk_hdr->key_nam, namlen); + key_name[namlen] = '\0'; type = (SVAL(&nk_hdr->type,0)==0x2C?REG_ROOT_KEY:REG_SUB_KEY); if(type == REG_ROOT_KEY && parent) { @@ -1088,7 +1086,7 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent clsnamep = (smb_ucs2_t *)LOCN(regf->base, clsnam_off); DEBUG(2, ("Class Name Offset: %0X\n", clsnam_off)); - tmp->class_name = talloc_strdup_w(regf->mem_ctx, clsnamep); + tmp->class_name = talloc_strdup_w(h->mem_ctx, clsnamep); DEBUGADD(2,(" Class Name: %s\n", cls_name)); @@ -1572,22 +1570,17 @@ static WERROR nt_close_registry (REG_HANDLE *h) regf->base = NULL; close(regf->fd); /* Ignore the error :-) */ - free(regf->sk_map); - regf->sk_count = regf->sk_map_size = 0; - - free(regf); return WERR_OK; } static WERROR nt_open_registry (REG_HANDLE *h, const char *location, const char *credentials) { - REGF *regf = (REGF *)malloc(sizeof(REGF)); + REGF *regf = (REGF *)talloc_p(h->mem_ctx, REGF); REGF_HDR *regf_hdr; unsigned int regf_id, hbin_id; HBIN_HDR *hbin_hdr; memset(regf, 0, sizeof(REGF)); - regf->mem_ctx = talloc_init("regf"); regf->owner_sid_str = credentials; h->backend_data = regf; 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 7c30302e84..f17bdbb3f5 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -20,6 +20,13 @@ #include "includes.h" #include "lib/registry/common/registry.h" +/** + * This is the RPC backend for the registry library. + * + * This backend is a little special. The root key is 'virtual'. All + * of its subkeys are the hives available on the remote server. + */ + static void init_winreg_String(struct winreg_String *name, const char *s) { name->name = s; @@ -35,7 +42,6 @@ static void init_winreg_String(struct winreg_String *name, const char *s) #define openhive(u) static struct policy_handle *open_ ## u(struct dcerpc_pipe *p, REG_HANDLE *h) \ { \ - NTSTATUS status; \ struct winreg_Open ## u r; \ struct winreg_OpenUnknown unknown; \ struct policy_handle *hnd = malloc(sizeof(struct policy_handle)); \ @@ -66,7 +72,7 @@ struct rpc_data { }; struct { - char *name; + const char *name; struct policy_handle *(*open) (struct dcerpc_pipe *p, REG_HANDLE *h); } known_hives[] = { { "HKEY_LOCAL_MACHINE", open_HKLM }, @@ -98,7 +104,6 @@ static WERROR rpc_open_registry(REG_HANDLE *h, const char *location, const char lp_workgroup(), user, pass); - h->backend_data = mydata; return ntstatus_to_werror(status); @@ -118,64 +123,66 @@ static WERROR rpc_close_registry(REG_HANDLE *h) return WERR_OK; } -static struct policy_handle *rpc_get_key_handle(REG_HANDLE *h, const char *path) +static WERROR rpc_key_put_policy_handle(REG_KEY *k) { - char *hivename; - int i = 0; - struct rpc_data *mydata = h->backend_data; - struct policy_handle *hive = NULL; - char *end = strchr(path+1, '\\'); - NTSTATUS status; + struct policy_handle *key_handle, *hive = NULL; struct winreg_OpenKey r; - struct policy_handle *key_handle = talloc(h->mem_ctx, sizeof(struct policy_handle)); - TALLOC_CTX *mem_ctx; - - if(end) hivename = strndup(path+1, end-path-1); - else hivename = strdup(path+1); + int i; + struct rpc_data *mydata = k->handle->backend_data; + char *realkeyname, *hivename; + if(k->backend_data) return WERR_OK; + + /* First, ensure the handle to the hive is opened */ + realkeyname = strchr(k->path, '\\'); + if(realkeyname) hivename = strndup(k->path+1, realkeyname-k->path-1); + else hivename = strdup(k->path+1); for(i = 0; known_hives[i].name; i++) { if(!strcmp(hivename, known_hives[i].name)) { - if(!mydata->hives[i]) mydata->hives[i] = known_hives[i].open(mydata->pipe, h); + if(!mydata->hives[i]) mydata->hives[i] = known_hives[i].open(mydata->pipe, k->handle); hive = mydata->hives[i]; + break; } } if(!hive) { DEBUG(0, ("No such hive: %s\n", hivename)); - return NULL; + return WERR_FOOBAR; } - DEBUG(2, ("Opening %s, hive: %s\n", path, hivename)); + if(realkeyname[0] == '\\')realkeyname++; - if(!end || !(*end) || !(*(end+1))) return hive; + if(!realkeyname || !(*realkeyname)) { + k->backend_data = hive; + return WERR_OK; + } + + key_handle = talloc(k->mem_ctx, sizeof(struct policy_handle)); + + /* Then, open the handle using the hive */ memset(&r, 0, sizeof(struct winreg_OpenKey)); r.in.handle = hive; - init_winreg_String(&r.in.keyname, end+1); + init_winreg_String(&r.in.keyname, realkeyname); r.in.unknown = 0x00000000; r.in.access_mask = 0x02000000; r.out.handle = key_handle; - - mem_ctx = talloc_init("openkey"); - status = dcerpc_winreg_OpenKey(mydata->pipe, mem_ctx, &r); - talloc_destroy(mem_ctx); - - if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { - return NULL; - } - return key_handle; + dcerpc_winreg_OpenKey(mydata->pipe, k->mem_ctx, &r); + + if(W_ERROR_IS_OK(r.out.result)) k->backend_data = key_handle; + + return r.out.result; } static WERROR rpc_open_key(REG_HANDLE *h, const char *name, REG_KEY **key) { - struct policy_handle *pol = rpc_get_key_handle(h, name); - if(!pol) return WERR_DEST_NOT_FOUND; - *key = reg_key_new_abs(name, h, pol); - return WERR_OK; + WERROR error; + *key = reg_key_new_abs(name, h, NULL); + return rpc_key_put_policy_handle(*key); } -static WERROR rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys) +static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey) { struct winreg_EnumKey r; struct winreg_EnumKeyNameRequest keyname; @@ -183,28 +190,22 @@ static WERROR rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys) struct winreg_Time tm; struct rpc_data *mydata = parent->handle->backend_data; int i; - REG_KEY **ar = talloc(parent->mem_ctx, sizeof(REG_KEY *)); - NTSTATUS status = NT_STATUS_OK; + NTSTATUS status; TALLOC_CTX *mem_ctx; - /* List the hives */ - if(parent->backend_data == parent->handle->backend_data) { - for(i = 0; known_hives[i].name; i++) { - ar[i] = reg_key_new_rel(known_hives[i].name, parent, NULL); - (*count)++; - ar = talloc_realloc(parent->mem_ctx, ar, sizeof(REG_KEY *) * ((*count)+1)); - } + /* If parent is the root key, list the hives */ + if(parent->backend_data == mydata) { + if(!known_hives[n].name) return WERR_NO_MORE_ITEMS; - *subkeys = ar; + *subkey = reg_key_new_rel(known_hives[n].name, parent, known_hives[n].open(mydata->pipe, parent->handle)); return WERR_OK; } - if(!parent->backend_data) parent->backend_data = rpc_get_key_handle(parent->handle, reg_key_get_path(parent)); - - if(!parent->backend_data) return WERR_GENERAL_FAILURE; + if(!parent->backend_data) { + rpc_key_put_policy_handle(parent); + } - (*count) = 0; r.in.handle = parent->backend_data; keyname.unknown = 0x0000020a; init_winreg_String(&keyname.key_name, NULL); @@ -215,134 +216,59 @@ static WERROR rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys) r.in.last_changed_time = &tm; r.out.result.v = 0; - for(i = 0; NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result); i++) { - r.in.enum_index = i; - r.in.unknown = r.out.unknown = 0x0414; - r.in.key_name_len = r.out.key_name_len = 0; - status = dcerpc_winreg_EnumKey(mydata->pipe, parent->mem_ctx, &r); - if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { - ar[(*count)] = reg_key_new_rel(r.out.out_name->name, parent, NULL); - (*count)++; - ar = talloc_realloc(parent->mem_ctx, ar, ((*count)+1) * sizeof(REG_KEY *)); - } - } - - *subkeys = ar; - return r.out.result; -} - -static WERROR rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values) -{ - struct winreg_EnumValue r; - struct winreg_Uint8buf value; - struct winreg_String valuename; - struct rpc_data *mydata = parent->handle->backend_data; - TALLOC_CTX *mem_ctx; - uint32 type, requested_len, returned_len; - NTSTATUS status = NT_STATUS_OK; - REG_VAL **ar = malloc(sizeof(REG_VAL *)); - - (*count) = 0; - - /* Root */ - if(parent->backend_data == parent->handle->backend_data) { - *values = ar; - return WERR_OK; + r.in.enum_index = n; + r.in.unknown = r.out.unknown = 0x0414; + r.in.key_name_len = r.out.key_name_len = 0; + status = dcerpc_winreg_EnumKey(mydata->pipe, parent->mem_ctx, &r); + if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { + *subkey = reg_key_new_rel(r.out.out_name->name, parent, NULL); } - - if(!parent->backend_data) parent->backend_data = rpc_get_key_handle(parent->handle, reg_key_get_path(parent)); - - if(!parent->backend_data) return WERR_GENERAL_FAILURE; - - r.in.handle = parent->backend_data; - r.in.enum_index = 0; - - init_winreg_String(&valuename, NULL); - r.in.name = r.out.name = &valuename; - - type = 0; - r.in.type = r.out.type = &type; - value.max_len = 0x7fff; - value.offset = 0; - value.len = 0; - value.buffer = NULL; - - r.in.value = r.out.value = &value; - - requested_len = value.max_len; - r.in.requested_len = &requested_len; - returned_len = 0; - r.in.returned_len = &returned_len; - r.out.result.v = 0; - - while(1) { - status = dcerpc_winreg_EnumValue(mydata->pipe, parent->mem_ctx, &r); - 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 = talloc_strdup(ar[*count]->mem_ctx, r.out.name->name); - ar[(*count)]->data_type = *r.out.type; - ar[(*count)]->data_len = value.len; - ar[(*count)]->data_blk = talloc(ar[*count]->mem_ctx, value.len); - memcpy(ar[(*count)]->data_blk, value.buffer, value.len); - (*count)++; - ar = talloc_realloc(parent->mem_ctx, ar, ((*count)+1) * sizeof(REG_VAL *)); - } else break; - } - - *values = ar; return r.out.result; } -static WERROR rpc_add_key(REG_KEY *parent, const char *name) +static WERROR rpc_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *sec, REG_KEY **key) { + rpc_key_put_policy_handle(parent); /* FIXME */ return WERR_NOT_SUPPORTED; } -static struct policy_handle*get_hive(REG_KEY *k) -{ - int i; - struct rpc_data *mydata = k->handle->backend_data; - for(i = 0; known_hives[i].name; i++) { - if(!strncmp(known_hives[i].name, reg_key_get_path(k)+1, strlen(known_hives[i].name))) - return mydata->hives[i]; - } - return NULL; -} + static WERROR rpc_del_key(REG_KEY *k) { NTSTATUS status; struct rpc_data *mydata = k->handle->backend_data; struct winreg_DeleteKey r; - char *hivepath; - struct policy_handle *hive = get_hive(k); + REG_KEY *parent; + WERROR error = reg_key_get_parent(k, &parent); + if(!W_ERROR_IS_OK(error)) return error; + rpc_key_put_policy_handle(parent); - printf("first: %s\n", reg_key_get_path(k)); - hivepath = strchr(reg_key_get_path(k), '\\'); - hivepath = strchr(hivepath+1, '\\'); - printf("asfter: %s\n", hivepath+1); - - r.in.handle = hive; - init_winreg_String(&r.in.key, hivepath+1); + r.in.handle = parent->backend_data; + init_winreg_String(&r.in.key, k->name); status = dcerpc_winreg_DeleteKey(mydata->pipe, k->mem_ctx, &r); return r.out.result; } +static void rpc_close_key(REG_KEY *k) +{ + reg_key_free(k); +} + static struct registry_ops reg_backend_rpc = { .name = "rpc", .open_registry = rpc_open_registry, .close_registry = rpc_close_registry, .open_root_key = rpc_open_root, .open_key = rpc_open_key, - .fetch_subkeys = rpc_fetch_subkeys, - .fetch_values = rpc_fetch_values, + .get_subkey_by_index = rpc_get_subkey_by_index, .add_key = rpc_add_key, .del_key = rpc_del_key, + .free_key_backend_data = rpc_close_key, }; NTSTATUS reg_rpc_init(void) diff --git a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c new file mode 100644 index 0000000000..79ebd54510 --- /dev/null +++ b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c @@ -0,0 +1,170 @@ +/* + Samba Unix/Linux SMB client utility libeditreg.c + Copyright (C) 2004 Jelmer Vernooij, jelmer@samba.org + + Backend for Windows '95 registry files. Explanation of file format + comes from http://www.cs.mun.ca/~michael/regutils/. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "includes.h" +#include "lib/registry/common/registry.h" + +/** + * The registry starts with a header that contains pointers to + * the rgdb. + * + * After the main header follows the RGKN header (key index table) */ + +typedef unsigned int DWORD; +typedef unsigned short WORD; + +typedef struct regc_block { + DWORD REGC_ID; /* REGC */ + DWORD uk1; + DWORD rgdb_offset; + DWORD chksum; + WORD num_rgdb; + WORD flags; + DWORD uk2; + DWORD uk3; + DWORD uk4; + DWORD uk5; +} REGC_HDR; + +typedef struct rgkn_block { + DWORD RGKN_ID; /* RGKN */ + DWORD size; + DWORD root_offset; + DWORD free_offset; + DWORD flags; + DWORD chksum; + DWORD uk1; + DWORD uk2; +} RGKN_HDR; + +typedef struct rgkn_key { + DWORD inuse; + DWORD hash; + DWORD next_free; + DWORD parent; + DWORD child; + DWORD next; + WORD id; + WORD rgdb; +} RGKN_KEY; + +typedef struct rgdb_block { + DWORD RGDB_ID; /* RGDB */ + DWORD size; + DWORD unused_size; + WORD flags; + WORD section; + DWORD free_offset; /* -1 if there is no free space */ + WORD max_id; + WORD first_free_id; + DWORD uk1; + DWORD chksum; +} RGDB_HDR; + +typedef struct rgdb_key { + DWORD inuse; + DWORD hash; + DWORD next_free; + DWORD parent; + DWORD child; + DWORD next; + WORD id; + WORD rgdb; +} RGDB_KEY; + +typedef struct rgdb_value { + DWORD type; + DWORD uk1; + DWORD name_len; + DWORD data_len; +} RGDB_VALUE; + +typedef struct regc_struct_s { + int fd; + struct stat sbuf; + BOOL modified; + char *base; +} REGC; + +static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *credentials) +{ + REGC *regc = talloc_p(h->mem_ctx, REGC); + REGC_HDR *regc_hdr; + RGKN_HDR *rgkn_hdr; + DWORD regc_id, rgkn_id; + memset(regc, 0, sizeof(REGC)); + h->backend_data = regc; + + if((regc->fd = open(location, O_RDONLY, 0000)) < 0) { + return WERR_FOOBAR; + } + + if(fstat(regc->fd, ®c->sbuf) < 0) { + return WERR_FOOBAR; + } + + regc->base = mmap(0, regc->sbuf.st_size, PROT_READ, MAP_SHARED, regc->fd, 0); + regc_hdr = (REGC_HDR *)regc->base; + + if ((int)regc->base == 1) { + return WERR_FOOBAR; + } + + if ((regc_id = IVAL(®c_hdr->REGC_ID,0)) != str_to_dword("REGC")) { + DEBUG(0, ("Unrecognized Windows 95 registry header id: %0X, %s\n", + regc_id, location)); + return WERR_FOOBAR; + } + + rgkn_hdr = (RGKN_HDR *)regc->base + sizeof(REGC_HDR); + + if ((rgkn_id = IVAL(&rgkn_hdr->RGKN_ID,0)) != str_to_dword("RGKN")) { + DEBUG(0, ("Unrecognized Windows 95 registry key index id: %0X, %s\n", + rgkn_id, location)); + return WERR_FOOBAR; + } + + //rgkn = (RGKN_KEY *)regc->base + sizeof(REGC_HDR) + sizeof(RGKN_HDR); + + /* FIXME */ + + return WERR_OK; +} + +static WERROR w95_close_reg(REG_HANDLE *h) +{ + REGC *regc = h->backend_data; + if (regc->base) munmap(regc->base, regc->sbuf.st_size); + regc->base = NULL; + close(regc->fd); + return WERR_OK; +} + +static struct registry_ops reg_backend_w95 = { + .name = "w95", + .open_registry = w95_open_reg, + .close_registry = w95_close_reg, +}; + +NTSTATUS reg_w95_init(void) +{ + return register_backend("registry", ®_backend_w95); +} diff --git a/source4/lib/registry/tools/gregedit.c b/source4/lib/registry/tools/gregedit.c index 51fad4287d..4fbb1b2705 100644 --- a/source4/lib/registry/tools/gregedit.c +++ b/source4/lib/registry/tools/gregedit.c @@ -84,6 +84,7 @@ static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath * g_assert(k); for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(k, i, &sub)); i++) { + int count; /* Replace the blank child with the first directory entry You may be tempted to remove the blank child node and then append a new one. Don't. If you remove the blank child @@ -103,14 +104,8 @@ static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath * sub, -1); - gtk_tree_store_append(store_keys, &tmpiter, &iter); - } - - /* Remove placeholder child */ - if(i == 0) { - gtk_tree_model_iter_children(GTK_TREE_MODEL(store_keys), - &iter, parent); - gtk_tree_store_remove(store_keys, &iter); + if(W_ERROR_IS_OK(reg_key_num_subkeys(sub, &count)) && count > 0) + gtk_tree_store_append(store_keys, &tmpiter, &iter); } if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) gtk_show_werror(error); -- cgit From 9d6a284567b832eee6fd47ac48c3471e69c0cc17 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 Apr 2004 23:34:23 +0000 Subject: r169: Fix gregedit (This used to be commit 32036375de58327a673a5a85cedb01e8ddfa503a) --- source4/lib/registry/common/reg_objects.c | 27 ++------------------------- source4/lib/registry/tools/gregedit.c | 12 ++++++------ 2 files changed, 8 insertions(+), 31 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_objects.c b/source4/lib/registry/common/reg_objects.c index 809829b3e8..78260e198f 100644 --- a/source4/lib/registry/common/reg_objects.c +++ b/source4/lib/registry/common/reg_objects.c @@ -34,31 +34,8 @@ REG_VAL* reg_val_dup( REG_VAL *val ) { - REG_VAL *copy = NULL; - TALLOC_CTX *new_mem_ctx = talloc_init(val->name); - - if ( !val ) - return NULL; - - if ( !(copy = talloc( new_mem_ctx, sizeof(REG_VAL) )) ) { - DEBUG(0,("dup_registry_value: malloc() failed!\n")); - return NULL; - } - - /* copy all the non-pointer initial data */ - - memcpy( copy, val, sizeof(REG_VAL) ); - if ( val->data_blk ) - { - if ( !(copy->data_blk = talloc_memdup( new_mem_ctx, val->data_blk, val->data_len )) ) { - DEBUG(0,("dup_registry_value: memdup() failed for [%d] bytes!\n", - val->data_len)); - SAFE_FREE( copy ); - } - } - copy->mem_ctx = new_mem_ctx; - - return copy; + val->ref++; + return val; } /********************************************************************** diff --git a/source4/lib/registry/tools/gregedit.c b/source4/lib/registry/tools/gregedit.c index 4fbb1b2705..0c9084ad3e 100644 --- a/source4/lib/registry/tools/gregedit.c +++ b/source4/lib/registry/tools/gregedit.c @@ -65,19 +65,20 @@ static void gtk_show_werror(WERROR err) static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath *arg2) { - GtkTreeIter iter, tmpiter; + GtkTreeIter firstiter, iter, tmpiter; REG_KEY *k, *sub; char *name; GValue value; WERROR error; int i; + gtk_tree_model_iter_children(GTK_TREE_MODEL(store_keys), &firstiter, parent); + /* See if this row has ever had a name gtk_tree_store_set()'ed to it. If not, read the directory contents */ - gtk_tree_model_get(GTK_TREE_MODEL(store_keys), parent, - 0, &name, -1); + gtk_tree_model_get(GTK_TREE_MODEL(store_keys), &firstiter, 0, &name, -1); - if(!name) return; + if(name) return; gtk_tree_model_get(GTK_TREE_MODEL(store_keys), parent, 1, &k, -1); @@ -91,8 +92,7 @@ static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath * node GTK gets confused and won't expand the parent row. */ if(i == 0) { - gtk_tree_model_iter_children(GTK_TREE_MODEL(store_keys), - &iter, parent); + iter = firstiter; } else { gtk_tree_store_append(store_keys, &iter, parent); } -- cgit From 24cd656ab0cd6501e321661883ae564c8d548298 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 12 Apr 2004 11:02:38 +0000 Subject: r174: Win95 registry files (like USER.DAT) can now be partially parsed (This used to be commit dd31d3bcbfbb0ef7a96a1b86c1b4c54b650e9fd5) --- .../lib/registry/reg_backend_nt4/reg_backend_nt4.c | 2 +- .../lib/registry/reg_backend_w95/reg_backend_w95.c | 127 ++++++++++++++------- source4/lib/registry/tools/gregedit.c | 16 ++- 3 files changed, 100 insertions(+), 45 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index fd91b4fbe6..74d7bbd3b1 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -487,7 +487,7 @@ typedef struct regf_struct_s { HBIN_BLK *blk_head, *blk_tail, *free_space; } REGF; -DWORD str_to_dword(const char *a) { +static DWORD str_to_dword(const char *a) { int i; unsigned long ret = 0; for(i = strlen(a)-1; i >= 0; i--) { diff --git a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c index 79ebd54510..8b20b830e1 100644 --- a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c @@ -31,18 +31,17 @@ typedef unsigned int DWORD; typedef unsigned short WORD; -typedef struct regc_block { - DWORD REGC_ID; /* REGC */ +typedef struct creg_block { + DWORD CREG_ID; /* CREG */ DWORD uk1; DWORD rgdb_offset; DWORD chksum; WORD num_rgdb; WORD flags; - DWORD uk2; - DWORD uk3; - DWORD uk4; - DWORD uk5; -} REGC_HDR; + DWORD uk2; + DWORD uk3; + DWORD uk4; +} CREG_HDR; typedef struct rgkn_block { DWORD RGKN_ID; /* RGKN */ @@ -56,7 +55,7 @@ typedef struct rgkn_block { } RGKN_HDR; typedef struct rgkn_key { - DWORD inuse; + DWORD type; DWORD hash; DWORD next_free; DWORD parent; @@ -80,7 +79,7 @@ typedef struct rgdb_block { } RGDB_HDR; typedef struct rgdb_key { - DWORD inuse; + DWORD type; DWORD hash; DWORD next_free; DWORD parent; @@ -97,64 +96,112 @@ typedef struct rgdb_value { DWORD data_len; } RGDB_VALUE; -typedef struct regc_struct_s { +typedef struct creg_struct_s { int fd; - struct stat sbuf; BOOL modified; char *base; -} REGC; + struct stat sbuf; + CREG_HDR *creg_hdr; + RGKN_HDR *rgkn_hdr; + char *rgkn; +} CREG; + +static DWORD str_to_dword(const char *a) { + int i; + unsigned long ret = 0; + for(i = strlen(a)-1; i >= 0; i--) { + ret = ret * 0x100 + a[i]; + } + return ret; +} + +#define LOCN(creg, o) (((creg)->base + sizeof(CREG_HDR) + o)) static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *credentials) { - REGC *regc = talloc_p(h->mem_ctx, REGC); - REGC_HDR *regc_hdr; - RGKN_HDR *rgkn_hdr; - DWORD regc_id, rgkn_id; - memset(regc, 0, sizeof(REGC)); - h->backend_data = regc; - - if((regc->fd = open(location, O_RDONLY, 0000)) < 0) { + CREG *creg = talloc_p(h->mem_ctx, CREG); + DWORD creg_id, rgkn_id; + memset(creg, 0, sizeof(CREG)); + h->backend_data = creg; + DWORD i, nfree = 0; + DWORD offset; + + if((creg->fd = open(location, O_RDONLY, 0000)) < 0) { return WERR_FOOBAR; } - if(fstat(regc->fd, ®c->sbuf) < 0) { + if (fstat(creg->fd, &creg->sbuf) < 0) { return WERR_FOOBAR; - } + } - regc->base = mmap(0, regc->sbuf.st_size, PROT_READ, MAP_SHARED, regc->fd, 0); - regc_hdr = (REGC_HDR *)regc->base; + creg->base = mmap(0, creg->sbuf.st_size, PROT_READ, MAP_SHARED, creg->fd, 0); + + if ((int)creg->base == 1) { + DEBUG(0,("Could not mmap file: %s, %s\n", location, strerror(errno))); + return WERR_FOOBAR; + } - if ((int)regc->base == 1) { - return WERR_FOOBAR; - } - - if ((regc_id = IVAL(®c_hdr->REGC_ID,0)) != str_to_dword("REGC")) { - DEBUG(0, ("Unrecognized Windows 95 registry header id: %0X, %s\n", - regc_id, location)); + creg->creg_hdr = (CREG_HDR *)creg->base; + + if ((creg_id = IVAL(&creg->creg_hdr->CREG_ID,0)) != str_to_dword("CREG")) { + DEBUG(0, ("Unrecognized Windows 95 registry header id: 0x%0X, %s\n", + creg_id, location)); return WERR_FOOBAR; } - rgkn_hdr = (RGKN_HDR *)regc->base + sizeof(REGC_HDR); + creg->rgkn_hdr = (RGKN_HDR *)LOCN(creg, 0); - if ((rgkn_id = IVAL(&rgkn_hdr->RGKN_ID,0)) != str_to_dword("RGKN")) { - DEBUG(0, ("Unrecognized Windows 95 registry key index id: %0X, %s\n", + if ((rgkn_id = IVAL(&creg->rgkn_hdr->RGKN_ID,0)) != str_to_dword("RGKN")) { + DEBUG(0, ("Unrecognized Windows 95 registry key index id: 0x%0X, %s\n", rgkn_id, location)); return WERR_FOOBAR; } - //rgkn = (RGKN_KEY *)regc->base + sizeof(REGC_HDR) + sizeof(RGKN_HDR); +#if 0 + for(i = 0; i < creg->rgkn_hdr->size; i+=sizeof(RGKN_KEY)) { + RGKN_KEY *key = (RGKN_KEY *)LOCN(creg, sizeof(RGKN_HDR) + i); + if(nfree > 0) { + nfree--; + } else if(key->type == 0) { + DEBUG(0,("Not used\n")); + /* Not used */ + } else if(key->type == 0x80000000) { + DEBUG(0,("Regular key\n")); + /* Regular key */ + } else { + DEBUG(0,("Invalid key type in RGKN: %0X\n", key->type)); + } + } - /* FIXME */ + curpos += creg->rgkn_hdr->size + sizeof(RGKN_HDR); +#endif + offset = creg->rgkn_hdr->size; + + DEBUG(0, ("Reading %d rgdb entries\n", creg->creg_hdr->num_rgdb)); + for(i = 0; i < creg->creg_hdr->num_rgdb; i++) { + RGDB_HDR *rgdb_hdr = (RGDB_HDR *)LOCN(creg, offset); + + if(strncmp((char *)&(rgdb_hdr->RGDB_ID), "RGDB", 4)) { + DEBUG(0, ("unrecognized rgdb entry: %4s, %s\n", + &rgdb_hdr->RGDB_ID, location)); + return WERR_FOOBAR; + } else { + DEBUG(0, ("Valid rgdb entry\n")); + } + + offset+=rgdb_hdr->size; + } + return WERR_OK; } static WERROR w95_close_reg(REG_HANDLE *h) { - REGC *regc = h->backend_data; - if (regc->base) munmap(regc->base, regc->sbuf.st_size); - regc->base = NULL; - close(regc->fd); + CREG *creg = h->backend_data; + if (creg->base) munmap(creg->base, creg->sbuf.st_size); + creg->base = NULL; + close(creg->fd); return WERR_OK; } diff --git a/source4/lib/registry/tools/gregedit.c b/source4/lib/registry/tools/gregedit.c index 0c9084ad3e..10e5f45468 100644 --- a/source4/lib/registry/tools/gregedit.c +++ b/source4/lib/registry/tools/gregedit.c @@ -220,7 +220,7 @@ GtkWidget* create_rpcwin (void) return rpcwin; } -static void on_open_nt4_activate (GtkMenuItem *menuitem, gpointer user_data) +static void on_open_file_activate (GtkMenuItem *menuitem, gpointer user_data) { gint result = gtk_dialog_run(GTK_DIALOG(create_openfilewin())); char *filename; @@ -228,7 +228,7 @@ static void on_open_nt4_activate (GtkMenuItem *menuitem, gpointer user_data) switch(result) { case GTK_RESPONSE_OK: filename = strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(openfilewin))); - error = reg_open("nt4", filename, NULL, ®istry); + error = reg_open(user_data, filename, NULL, ®istry); if(!W_ERROR_IS_OK(error)) { gtk_show_werror(error); break; @@ -407,6 +407,7 @@ GtkWidget* create_mainwin (void) GtkWidget *menu_file; GtkWidget *menu_file_menu; GtkWidget *open_nt4; + GtkWidget *open_w95; GtkWidget *open_gconf; GtkWidget *open_remote; GtkWidget *separatormenuitem1; @@ -455,6 +456,10 @@ GtkWidget* create_mainwin (void) gtk_widget_show (open_nt4); gtk_container_add (GTK_CONTAINER (menu_file_menu), open_nt4); + open_w95 = gtk_image_menu_item_new_with_mnemonic("_Open Win9x file"); + gtk_widget_show (open_w95); + gtk_container_add (GTK_CONTAINER (menu_file_menu), open_w95); + open_gconf = gtk_image_menu_item_new_with_mnemonic ("_Open GConf"); gtk_widget_show (open_gconf); gtk_container_add (GTK_CONTAINER (menu_file_menu), open_gconf); @@ -595,8 +600,11 @@ GtkWidget* create_mainwin (void) gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (statusbar), FALSE); g_signal_connect ((gpointer) open_nt4, "activate", - G_CALLBACK (on_open_nt4_activate), - NULL); + G_CALLBACK (on_open_file_activate), + "nt4"); + g_signal_connect ((gpointer) open_w95, "activate", + G_CALLBACK (on_open_file_activate), + "w95"); g_signal_connect ((gpointer) open_gconf, "activate", G_CALLBACK (on_open_gconf_activate), NULL); -- cgit From 49d54f0298de9dcee8d0fcb7e193429b80a8c8b1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 12 Apr 2004 17:43:22 +0000 Subject: r181: Parsing windows '95 registry files now works (including values) (This used to be commit 4d6ce648567060b9922343971d7aafd545341439) --- source4/lib/registry/common/reg_interface.c | 8 +- .../lib/registry/reg_backend_w95/reg_backend_w95.c | 225 +++++++++++++++++---- 2 files changed, 188 insertions(+), 45 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 917b03cf32..696a504d87 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -268,7 +268,10 @@ WERROR reg_key_get_subkey_by_index(REG_KEY *key, int idx, REG_KEY **subkey) { if(!key) return WERR_INVALID_PARAM; - if(!key->handle->functions->get_subkey_by_index) { + if(key->handle->functions->get_subkey_by_index) { + WERROR status = key->handle->functions->get_subkey_by_index(key, idx, subkey); + if(!NT_STATUS_IS_OK(status)) return status; + } else if(key->handle->functions->fetch_subkeys) { if(!key->cache_subkeys) key->handle->functions->fetch_subkeys(key, &key->cache_subkeys_count, &key->cache_subkeys); @@ -278,8 +281,7 @@ WERROR reg_key_get_subkey_by_index(REG_KEY *key, int idx, REG_KEY **subkey) return WERR_NO_MORE_ITEMS; } } else { - WERROR status = key->handle->functions->get_subkey_by_index(key, idx, subkey); - if(!NT_STATUS_IS_OK(status)) return status; + return WERR_NOT_SUPPORTED; } (*subkey)->path = talloc_asprintf((*subkey)->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", (*subkey)->name); diff --git a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c index 8b20b830e1..0b6b6db358 100644 --- a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c @@ -26,7 +26,19 @@ * The registry starts with a header that contains pointers to * the rgdb. * - * After the main header follows the RGKN header (key index table) */ + * After the main header follows the RGKN header (key index table). + * The RGKN keys are listed after each other. They are put into + * blocks, the first having a length of 0x2000 bytes, the others + * being 0x1000 bytes long. + * + * After the RGKN header follow one or more RGDB blocks. These blocks + * contain keys. A key is followed by its name and its values. + * + * Values are followed by their name and then their data. + * + * Basically the idea is that the RGKN contains the associations between + * the keys and the RGDB contains the actual data. + */ typedef unsigned int DWORD; typedef unsigned short WORD; @@ -54,17 +66,22 @@ typedef struct rgkn_block { DWORD uk2; } RGKN_HDR; -typedef struct rgkn_key { - DWORD type; - DWORD hash; - DWORD next_free; - DWORD parent; - DWORD child; - DWORD next; +typedef struct reg_id { WORD id; WORD rgdb; +} REG_ID; + +typedef struct rgkn_key { + DWORD type; /* 0x00000000 = normal key, 0x80000000 = free block */ + DWORD hash; /* Contains either hash or size of free blocks that follows */ + DWORD next_free; + DWORD parent_offset; + DWORD first_child_offset; + DWORD next_offset; + REG_ID id; } RGKN_KEY; + typedef struct rgdb_block { DWORD RGDB_ID; /* RGDB */ DWORD size; @@ -79,21 +96,19 @@ typedef struct rgdb_block { } RGDB_HDR; typedef struct rgdb_key { - DWORD type; - DWORD hash; - DWORD next_free; - DWORD parent; - DWORD child; - DWORD next; - WORD id; - WORD rgdb; + DWORD size; + REG_ID id; + DWORD used_size; + WORD name_len; + WORD num_values; + DWORD uk1; } RGDB_KEY; typedef struct rgdb_value { DWORD type; DWORD uk1; - DWORD name_len; - DWORD data_len; + WORD name_len; + WORD data_len; } RGDB_VALUE; typedef struct creg_struct_s { @@ -103,9 +118,16 @@ typedef struct creg_struct_s { struct stat sbuf; CREG_HDR *creg_hdr; RGKN_HDR *rgkn_hdr; - char *rgkn; + RGDB_KEY ***rgdb_keys; } CREG; +#define RGKN_START_SIZE 0x2000 +#define RGKN_INC_SIZE 0x1000 + +#define LOCN_RGKN(creg, o) ((RGKN_KEY *)((creg)->base + sizeof(CREG_HDR) + o)) +#define LOCN_RGDB_BLOCK(creg, o) (((creg)->base + (creg)->creg_hdr->rgdb_offset + o)) +#define LOCN_RGDB_KEY(creg, rgdb, id) ((RGDB_KEY *)((creg)->rgdb_keys[(rgdb)][(id)])) + static DWORD str_to_dword(const char *a) { int i; unsigned long ret = 0; @@ -115,7 +137,86 @@ static DWORD str_to_dword(const char *a) { return ret; } -#define LOCN(creg, o) (((creg)->base + sizeof(CREG_HDR) + o)) +static DWORD calc_hash(const char *str) { + DWORD ret = 0; + int i; + for(i = 0; str[i] && str[i] != '\\'; i++) { + ret+=toupper(str[i]); + } + return ret; +} + +static void parse_rgkn_block(CREG *creg, off_t start_off, off_t end_off) +{ + off_t i; + for(i = start_off; end_off - i > sizeof(RGKN_KEY); i+= sizeof(RGKN_KEY)) { + RGKN_KEY *key = (RGKN_KEY *)LOCN_RGKN(creg, i); + if(key->type == 0) { + DEBUG(4,("Regular, id: %d, %d, parent: %x, firstchild: %x, next: %x hash: %lX\n", key->id.id, key->id.rgdb, key->parent_offset, key->first_child_offset, key->next_offset, key->hash)); + } else if(key->type == 0x80000000) { + DEBUG(3,("free\n")); + i += key->hash; + } else { + DEBUG(0,("Invalid key type in RGKN: %0X\n", key->type)); + } + } +} + +static void parse_rgdb_block(CREG *creg, RGDB_HDR *rgdb_hdr) +{ + DWORD used_size = rgdb_hdr->size - rgdb_hdr->unused_size; + DWORD offset = 0; + + while(offset < used_size) { + RGDB_KEY *key = (RGDB_KEY *)(((char *)rgdb_hdr) + sizeof(RGDB_HDR) + offset); + + if(!(key->id.id == 0xFFFF && key->id.rgdb == 0xFFFF))creg->rgdb_keys[key->id.rgdb][key->id.id] = key; + offset += key->size; + } +} + +static WERROR w95_open_root (REG_HANDLE *h, REG_KEY **key) +{ + CREG *creg = h->backend_data; + + /* First element in rgkn should be root key */ + *key = reg_key_new_abs("\\", h, LOCN_RGKN(creg, sizeof(RGKN_HDR))); + + return WERR_OK; +} + +static WERROR w95_get_subkey_by_index (REG_KEY *parent, int n, REG_KEY **key) +{ + CREG *creg = parent->handle->backend_data; + RGKN_KEY *rgkn_key = parent->backend_data; + RGKN_KEY *child; + DWORD child_offset; + DWORD cur = 0; + + /* Get id of first child */ + child_offset = rgkn_key->first_child_offset; + + while(child_offset != 0xFFFFFFFF) { + child = LOCN_RGKN(creg, child_offset); + + /* n == cur ? return! */ + if(cur == n) { + RGDB_KEY *rgdb_key; + char *name; + rgdb_key = LOCN_RGDB_KEY(creg, child->id.rgdb, child->id.id); + name = strndup((char *)rgdb_key + sizeof(RGDB_KEY), rgdb_key->name_len); + *key = reg_key_new_rel(name, parent, child); + SAFE_FREE(name); + return WERR_OK; + } + + cur++; + + child_offset = child->next_offset; + } + + return WERR_NO_MORE_ITEMS; +} static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *credentials) { @@ -124,7 +225,7 @@ static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *cre memset(creg, 0, sizeof(CREG)); h->backend_data = creg; DWORD i, nfree = 0; - DWORD offset; + DWORD offset, end_offset; if((creg->fd = open(location, O_RDONLY, 0000)) < 0) { return WERR_FOOBAR; @@ -149,7 +250,7 @@ static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *cre return WERR_FOOBAR; } - creg->rgkn_hdr = (RGKN_HDR *)LOCN(creg, 0); + creg->rgkn_hdr = (RGKN_HDR *)LOCN_RGKN(creg, 0); if ((rgkn_id = IVAL(&creg->rgkn_hdr->RGKN_ID,0)) != str_to_dword("RGKN")) { DEBUG(0, ("Unrecognized Windows 95 registry key index id: 0x%0X, %s\n", @@ -157,38 +258,39 @@ static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *cre return WERR_FOOBAR; } -#if 0 - for(i = 0; i < creg->rgkn_hdr->size; i+=sizeof(RGKN_KEY)) { - RGKN_KEY *key = (RGKN_KEY *)LOCN(creg, sizeof(RGKN_HDR) + i); - if(nfree > 0) { - nfree--; - } else if(key->type == 0) { - DEBUG(0,("Not used\n")); - /* Not used */ - } else if(key->type == 0x80000000) { - DEBUG(0,("Regular key\n")); - /* Regular key */ - } else { - DEBUG(0,("Invalid key type in RGKN: %0X\n", key->type)); - } - } +#if 0 + /* If'ed out because we only need to parse this stuff when allocating new + * entries (which we don't do at the moment */ + /* First parse the 0x2000 long block */ + parse_rgkn_block(creg, sizeof(RGKN_HDR), 0x2000); - curpos += creg->rgkn_hdr->size + sizeof(RGKN_HDR); + /* Then parse the other 0x1000 length blocks */ + for(offset = 0x2000; offset < creg->rgkn_hdr->size; offset+=0x1000) { + parse_rgkn_block(creg, offset, offset+0x1000); + } #endif - offset = creg->rgkn_hdr->size; - DEBUG(0, ("Reading %d rgdb entries\n", creg->creg_hdr->num_rgdb)); + creg->rgdb_keys = talloc_array_p(h->mem_ctx, RGDB_KEY **, creg->creg_hdr->num_rgdb); + + offset = 0; + DEBUG(3, ("Reading %d rgdb entries\n", creg->creg_hdr->num_rgdb)); for(i = 0; i < creg->creg_hdr->num_rgdb; i++) { - RGDB_HDR *rgdb_hdr = (RGDB_HDR *)LOCN(creg, offset); + RGDB_HDR *rgdb_hdr = (RGDB_HDR *)LOCN_RGDB_BLOCK(creg, offset); if(strncmp((char *)&(rgdb_hdr->RGDB_ID), "RGDB", 4)) { DEBUG(0, ("unrecognized rgdb entry: %4s, %s\n", &rgdb_hdr->RGDB_ID, location)); return WERR_FOOBAR; } else { - DEBUG(0, ("Valid rgdb entry\n")); + DEBUG(3, ("Valid rgdb entry, first free id: %d, max id: %d\n", rgdb_hdr->first_free_id, rgdb_hdr->max_id)); } + + creg->rgdb_keys[i] = talloc_array_p(h->mem_ctx, RGDB_KEY *, rgdb_hdr->max_id+1); + memset(creg->rgdb_keys[i], 0, sizeof(RGDB_KEY *) * (rgdb_hdr->max_id+1)); + + parse_rgdb_block(creg, rgdb_hdr); + offset+=rgdb_hdr->size; } @@ -205,10 +307,49 @@ static WERROR w95_close_reg(REG_HANDLE *h) return WERR_OK; } + +static WERROR w95_fetch_values(REG_KEY *k, int *count, REG_VAL ***values) +{ + RGKN_KEY *rgkn_key = k->backend_data; + RGDB_VALUE *val; + DWORD i; + DWORD offset = 0; + RGDB_KEY *rgdb_key = LOCN_RGDB_KEY((CREG *)k->handle->backend_data, rgkn_key->id.rgdb, rgkn_key->id.id); + + if(!rgdb_key) return WERR_FOOBAR; + + *count = rgdb_key->num_values; + + if((*count) == 0) return WERR_OK; + + (*values) = talloc_array_p(k->mem_ctx, REG_VAL *, (*count)+1); + for(i = 0; i < rgdb_key->num_values; i++) { + RGDB_VALUE *val = (RGDB_VALUE *)(((char *)rgdb_key) + sizeof(RGDB_KEY) + rgdb_key->name_len + offset); + (*values)[i] = reg_val_new(k, val); + + /* Name */ + (*values)[i]->name = talloc_strndup(k->mem_ctx, (char *)val+sizeof(RGDB_VALUE), val->name_len); + + /* Value */ + (*values)[i]->data_len = val->data_len; + (*values)[i]->data_blk = talloc_memdup((*values)[i]->mem_ctx, (char *)val+sizeof(RGDB_VALUE)+val->name_len, val->data_len); + + /* Type */ + (*values)[i]->data_type = val->type; + + offset+=sizeof(RGDB_VALUE) + val->name_len + val->data_len; + } + + return WERR_OK; +} + static struct registry_ops reg_backend_w95 = { .name = "w95", .open_registry = w95_open_reg, .close_registry = w95_close_reg, + .open_root_key = w95_open_root, + .fetch_values = w95_fetch_values, + .get_subkey_by_index = w95_get_subkey_by_index, }; NTSTATUS reg_w95_init(void) -- cgit From 4019324f7633c029c3cf461ed8d15433fc7609ea Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 12 Apr 2004 18:02:54 +0000 Subject: r182: Fix a couple of segfaults (This used to be commit db5d7062e69b456a89b17525e5a0177f93c90c83) --- source4/lib/registry/TODO | 3 +++ source4/lib/registry/common/reg_objects.c | 3 +++ source4/lib/registry/common/reg_util.c | 4 ++-- source4/lib/registry/reg_backend_w95/reg_backend_w95.c | 4 ++++ 4 files changed, 12 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/TODO b/source4/lib/registry/TODO index f84b1c5339..9b0dbe4c71 100644 --- a/source4/lib/registry/TODO +++ b/source4/lib/registry/TODO @@ -4,6 +4,9 @@ reg_backend_dir: - value support + +reg_backend_w95.c: + - write support reg_backend_nt4: - write support diff --git a/source4/lib/registry/common/reg_objects.c b/source4/lib/registry/common/reg_objects.c index 78260e198f..3f721c107e 100644 --- a/source4/lib/registry/common/reg_objects.c +++ b/source4/lib/registry/common/reg_objects.c @@ -47,6 +47,9 @@ void reg_val_free( REG_VAL *val ) if ( !val ) return; + val->ref--; + if(val->ref) return; + if(val->handle->functions->free_val_backend_data) val->handle->functions->free_val_backend_data(val); diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index 5ca104fc2e..82b8d06679 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -45,10 +45,10 @@ char *reg_val_data_string(REG_VAL *v) switch (reg_val_type(v)) { case REG_SZ: /* FIXME: Convert to ascii */ - return strdup(reg_val_data_blk(v)); + return strndup(reg_val_data_blk(v), reg_val_size(v)); case REG_EXPAND_SZ: - return strdup(reg_val_data_blk(v)); + return strndup(reg_val_data_blk(v), reg_val_size(v)); case REG_BINARY: ret = malloc(reg_val_size(v) * 3 + 2); diff --git a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c index 0b6b6db358..31abd69854 100644 --- a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c @@ -204,6 +204,10 @@ static WERROR w95_get_subkey_by_index (REG_KEY *parent, int n, REG_KEY **key) RGDB_KEY *rgdb_key; char *name; rgdb_key = LOCN_RGDB_KEY(creg, child->id.rgdb, child->id.id); + if(!rgdb_key) { + DEBUG(0, ("Can't find %d,%d in RGDB table!\n", child->id.rgdb, child->id.id)); + return WERR_FOOBAR; + } name = strndup((char *)rgdb_key + sizeof(RGDB_KEY), rgdb_key->name_len); *key = reg_key_new_rel(name, parent, child); SAFE_FREE(name); -- cgit From b4d6cbd380b09d0638102137b589555cb4e1c285 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 12 Apr 2004 18:46:48 +0000 Subject: r183: More bugfixes (This used to be commit 88911bbcca574adbf6ea4f0759a68f2961b05d6b) --- source4/lib/registry/common/reg_interface.c | 40 ++++++++++++----------------- source4/lib/registry/tools/regshell.c | 9 +++---- 2 files changed, 21 insertions(+), 28 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 696a504d87..5753de1bca 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -124,8 +124,7 @@ WERROR reg_open(const char *backend, const char *location, const char *credentia WERROR reg_open_key(REG_KEY *parent, const char *name, REG_KEY **result) { char *fullname; - WERROR status; - REG_KEY *ret = NULL; + WERROR error; TALLOC_CTX *mem_ctx; if(!parent) { @@ -143,10 +142,10 @@ WERROR reg_open_key(REG_KEY *parent, const char *name, REG_KEY **result) while(curbegin && *curbegin) { if(curend)*curend = '\0'; - status = reg_key_get_subkey_by_name(curkey, curbegin, result); - if(!NT_STATUS_IS_OK(status)) { + error = reg_key_get_subkey_by_name(curkey, curbegin, result); + if(!W_ERROR_IS_OK(error)) { SAFE_FREE(orig); - return status; + return error; } if(!curend) break; curbegin = curend + 1; @@ -168,21 +167,19 @@ WERROR reg_open_key(REG_KEY *parent, const char *name, REG_KEY **result) return WERR_NOT_SUPPORTED; } - status = parent->handle->functions->open_key(parent->handle, fullname, result); + error = parent->handle->functions->open_key(parent->handle, fullname, result); - if(!NT_STATUS_IS_OK(status)) { + if(!W_ERROR_IS_OK(error)) { talloc_destroy(mem_ctx); - return status; + return error; } - ret->handle = parent->handle; - ret->path = fullname; - talloc_steal(mem_ctx, ret->mem_ctx, fullname); + (*result)->handle = parent->handle; + (*result)->path = fullname; + talloc_steal(mem_ctx, (*result)->mem_ctx, fullname); talloc_destroy(mem_ctx); - *result = ret; - return WERR_OK; } @@ -294,32 +291,29 @@ WERROR reg_key_get_subkey_by_index(REG_KEY *key, int idx, REG_KEY **subkey) WERROR reg_key_get_subkey_by_name(REG_KEY *key, const char *name, REG_KEY **subkey) { int i; - REG_KEY *ret = NULL; WERROR error = WERR_OK; if(!key) return WERR_INVALID_PARAM; if(key->handle->functions->get_subkey_by_name) { error = key->handle->functions->get_subkey_by_name(key,name,subkey); - } else { + } else if(key->handle->functions->get_subkey_by_index || key->handle->functions->fetch_subkeys) { for(i = 0; W_ERROR_IS_OK(error); i++) { error = reg_key_get_subkey_by_index(key, i, subkey); if(W_ERROR_IS_OK(error) && !strcmp((*subkey)->name, name)) { - break; + return error; } reg_key_free(*subkey); } - + } else { + return WERR_NOT_SUPPORTED; } - if(!W_ERROR_IS_OK(error) && W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) - return error; + if(!W_ERROR_IS_OK(error)) return error; - ret->path = talloc_asprintf(ret->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name); - ret->handle = key->handle; + (*subkey)->path = talloc_asprintf((*subkey)->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", (*subkey)->name); + (*subkey)->handle = key->handle; - *subkey = ret; - return WERR_OK; } diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index d60ca1ff46..18399b5bda 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -39,18 +39,17 @@ static REG_KEY *cmd_set(REG_KEY *cur, int argc, char **argv) static REG_KEY *cmd_ck(REG_KEY *cur, int argc, char **argv) { - REG_KEY *new; + REG_KEY *new = NULL; WERROR error; if(argc < 2) { new = cur; } else { error = reg_open_key(cur, argv[1], &new); if(!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error opening specified key\n")); + DEBUG(0, ("Error opening specified key: %s\n", win_errstr(error))); + return NULL; } - } - - if(!new) new = cur; + } printf("Current path is: %s\n", reg_key_get_path(new)); -- cgit From 198a92cb77ef2070957f18da0a8b6a48d01dbe9b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 12 Apr 2004 20:07:50 +0000 Subject: r187: RPC registry backend fixes (This used to be commit f832d6776cb10f5c7d7ed83e6f66e4d28a461916) --- source4/lib/registry/common/reg_interface.c | 11 +- source4/lib/registry/common/reg_objects.c | 3 + .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 141 +++++++++++++++++---- source4/lib/registry/tools/regtree.c | 2 +- 4 files changed, 127 insertions(+), 30 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 5753de1bca..fdbb7345d2 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -187,7 +187,12 @@ WERROR reg_key_get_value_by_index(REG_KEY *key, int idx, REG_VAL **val) { if(!key) return WERR_INVALID_PARAM; - if(!key->handle->functions->get_value_by_index) { + if(key->handle->functions->get_value_by_index) { + WERROR status = key->handle->functions->get_value_by_index(key, idx, val); + if(!W_ERROR_IS_OK(status)) + return status; + + } else if(key->handle->functions->fetch_values) { if(!key->cache_values) key->handle->functions->fetch_values(key, &key->cache_values_count, &key->cache_values); @@ -197,9 +202,7 @@ WERROR reg_key_get_value_by_index(REG_KEY *key, int idx, REG_VAL **val) return WERR_NO_MORE_ITEMS; } } else { - WERROR status = key->handle->functions->get_value_by_index(key, idx, val); - if(!W_ERROR_IS_OK(status)) - return status; + return WERR_NOT_SUPPORTED; } (*val)->parent = key; diff --git a/source4/lib/registry/common/reg_objects.c b/source4/lib/registry/common/reg_objects.c index 3f721c107e..787ec52127 100644 --- a/source4/lib/registry/common/reg_objects.c +++ b/source4/lib/registry/common/reg_objects.c @@ -163,11 +163,14 @@ REG_KEY *reg_key_new_abs(const char *path, REG_HANDLE *h, void *data) REG_KEY *reg_key_new_rel(const char *name, REG_KEY *k, void *data) { REG_KEY *r; + const char *parent_path = k?reg_key_get_path(k):""; TALLOC_CTX *mem_ctx = talloc_init(name); r = talloc(mem_ctx, sizeof(REG_KEY)); ZERO_STRUCTP(r); r->handle = k->handle; r->name = talloc_strdup(mem_ctx, name); + + r->path = talloc_asprintf(mem_ctx, "%s%s%s", parent_path, *parent_path && parent_path[strlen(parent_path)-1] != '\\'?"\\":"", name); r->backend_data = data; r->mem_ctx = mem_ctx; r->ref = 1; 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 f17bdbb3f5..f5a7127ed6 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -71,6 +71,12 @@ struct rpc_data { struct policy_handle *hives[10]; }; +struct rpc_key_data { + struct policy_handle pol; + int num_subkeys; + int num_values; +}; + struct { const char *name; struct policy_handle *(*open) (struct dcerpc_pipe *p, REG_HANDLE *h); @@ -119,21 +125,30 @@ static WERROR rpc_open_root(REG_HANDLE *h, REG_KEY **k) static WERROR rpc_close_registry(REG_HANDLE *h) { dcerpc_pipe_close(((struct rpc_data *)h->backend_data)->pipe); - free(h->backend_data); return WERR_OK; } -static WERROR rpc_key_put_policy_handle(REG_KEY *k) +static WERROR rpc_key_put_rpc_data(REG_KEY *k, struct rpc_key_data **data) { - struct policy_handle *key_handle, *hive = NULL; + struct policy_handle *hive = NULL; struct winreg_OpenKey r; int i; struct rpc_data *mydata = k->handle->backend_data; + struct rpc_key_data *mykeydata; char *realkeyname, *hivename; - if(k->backend_data) return WERR_OK; + + if(k->backend_data) { + *data = k->backend_data; + return WERR_OK; + } + + k->backend_data = mykeydata = talloc_p(k->mem_ctx, struct rpc_key_data); + *data = mykeydata; + mykeydata->num_values = -1; + mykeydata->num_subkeys = -1; /* First, ensure the handle to the hive is opened */ - realkeyname = strchr(k->path, '\\'); + realkeyname = strchr(k->path+1, '\\'); if(realkeyname) hivename = strndup(k->path+1, realkeyname-k->path-1); else hivename = strdup(k->path+1); @@ -150,15 +165,13 @@ static WERROR rpc_key_put_policy_handle(REG_KEY *k) return WERR_FOOBAR; } - if(realkeyname[0] == '\\')realkeyname++; + if(realkeyname && realkeyname[0] == '\\')realkeyname++; if(!realkeyname || !(*realkeyname)) { - k->backend_data = hive; + mykeydata->pol = *hive; return WERR_OK; } - key_handle = talloc(k->mem_ctx, sizeof(struct policy_handle)); - /* Then, open the handle using the hive */ memset(&r, 0, sizeof(struct winreg_OpenKey)); @@ -166,20 +179,19 @@ static WERROR rpc_key_put_policy_handle(REG_KEY *k) init_winreg_String(&r.in.keyname, realkeyname); r.in.unknown = 0x00000000; r.in.access_mask = 0x02000000; - r.out.handle = key_handle; + r.out.handle = &mykeydata->pol; dcerpc_winreg_OpenKey(mydata->pipe, k->mem_ctx, &r); - if(W_ERROR_IS_OK(r.out.result)) k->backend_data = key_handle; - return r.out.result; } static WERROR rpc_open_key(REG_HANDLE *h, const char *name, REG_KEY **key) { WERROR error; + struct rpc_key_data *mykeydata; *key = reg_key_new_abs(name, h, NULL); - return rpc_key_put_policy_handle(*key); + return rpc_key_put_rpc_data(*key, &mykeydata); } static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey) @@ -189,6 +201,8 @@ static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey) struct winreg_String classname; struct winreg_Time tm; struct rpc_data *mydata = parent->handle->backend_data; + struct rpc_key_data *mykeydata = parent->backend_data; + WERROR error; int i; NTSTATUS status; TALLOC_CTX *mem_ctx; @@ -196,17 +210,14 @@ static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey) /* If parent is the root key, list the hives */ if(parent->backend_data == mydata) { if(!known_hives[n].name) return WERR_NO_MORE_ITEMS; - - *subkey = reg_key_new_rel(known_hives[n].name, parent, known_hives[n].open(mydata->pipe, parent->handle)); - - return WERR_OK; + *subkey = reg_key_new_rel(known_hives[n].name, parent, NULL); + return rpc_key_put_rpc_data(*subkey, &mykeydata); } - if(!parent->backend_data) { - rpc_key_put_policy_handle(parent); - } + error = rpc_key_put_rpc_data(parent, &mykeydata); + if(!W_ERROR_IS_OK(error)) return error; - r.in.handle = parent->backend_data; + r.in.handle = &mykeydata->pol; keyname.unknown = 0x0000020a; init_winreg_String(&keyname.key_name, NULL); init_winreg_String(&classname, NULL); @@ -229,24 +240,56 @@ static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey) static WERROR rpc_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *sec, REG_KEY **key) { - rpc_key_put_policy_handle(parent); + struct rpc_key_data *mykeydata; + WERROR error = rpc_key_put_rpc_data(parent, &mykeydata); + if(!W_ERROR_IS_OK(error)) return error; + /* FIXME */ return WERR_NOT_SUPPORTED; } +static WERROR rpc_query_key(REG_KEY *k) +{ + NTSTATUS status; + struct winreg_QueryInfoKey r; + struct rpc_data *mydata = k->handle->backend_data; + struct rpc_key_data *mykeydata; + WERROR error = rpc_key_put_rpc_data(k, &mykeydata); + + r.in.handle = &mykeydata->pol; + init_winreg_String(&r.in.class, NULL); + + status = dcerpc_winreg_QueryInfoKey(mydata->pipe, k->mem_ctx, &r); + + if (!NT_STATUS_IS_OK(status)) { + printf("QueryInfoKey failed - %s\n", nt_errstr(status)); + return ntstatus_to_werror(status); + } + + if (W_ERROR_IS_OK(r.out.result)) { + mykeydata->num_subkeys = r.out.num_subkeys; + mykeydata->num_values = r.out.num_values; + } + return r.out.result; +} static WERROR rpc_del_key(REG_KEY *k) { NTSTATUS status; struct rpc_data *mydata = k->handle->backend_data; + struct rpc_key_data *mykeydata; struct winreg_DeleteKey r; REG_KEY *parent; - WERROR error = reg_key_get_parent(k, &parent); + WERROR error; + + error = reg_key_get_parent(k, &parent); + if(!W_ERROR_IS_OK(error)) return error; + + error = rpc_key_put_rpc_data(parent, &mykeydata); if(!W_ERROR_IS_OK(error)) return error; - rpc_key_put_policy_handle(parent); - r.in.handle = parent->backend_data; + r.in.handle = &mykeydata->pol; init_winreg_String(&r.in.key, k->name); status = dcerpc_winreg_DeleteKey(mydata->pipe, k->mem_ctx, &r); @@ -259,6 +302,52 @@ static void rpc_close_key(REG_KEY *k) reg_key_free(k); } +static WERROR rpc_num_values(REG_KEY *key, int *count) { + struct rpc_key_data *mykeydata; + WERROR error; + + /* Root is a special case */ + if(key->backend_data == key->handle->backend_data) { + *count = 0; + return WERR_OK; + } + + error = rpc_key_put_rpc_data(key, &mykeydata); + if(!W_ERROR_IS_OK(error)) return error; + + if(mykeydata->num_values == -1) { + WERROR error = rpc_query_key(key); + if(!W_ERROR_IS_OK(error)) return error; + } + + *count = mykeydata->num_values; + return WERR_OK; +} + +static WERROR rpc_num_subkeys(REG_KEY *key, int *count) { + struct rpc_key_data *mykeydata; + WERROR error; + + /* Root is a special case */ + if(key->backend_data == key->handle->backend_data) { + int i; + for(i = 0; known_hives[i].name; i++); + *count = i; + return WERR_OK; + } + + error = rpc_key_put_rpc_data(key, &mykeydata); + if(!W_ERROR_IS_OK(error)) return error; + + if(mykeydata->num_subkeys == -1) { + WERROR error = rpc_query_key(key); + if(!W_ERROR_IS_OK(error)) return error; + } + + *count = mykeydata->num_subkeys; + return WERR_OK; +} + static struct registry_ops reg_backend_rpc = { .name = "rpc", .open_registry = rpc_open_registry, @@ -269,6 +358,8 @@ static struct registry_ops reg_backend_rpc = { .add_key = rpc_add_key, .del_key = rpc_del_key, .free_key_backend_data = rpc_close_key, + .num_subkeys = rpc_num_subkeys, + .num_values = rpc_num_values, }; NTSTATUS reg_rpc_init(void) diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index b8a5f50496..eb32b1e55e 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -38,7 +38,7 @@ void print_tree(int l, REG_KEY *p, int fullpath, int novals) } if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while fetching subkeys for '%s'\n", reg_key_get_path(p))); + DEBUG(0, ("Error occured while fetching subkeys for '%s': %s\n", reg_key_get_path(p), win_errstr(error))); } if(!novals) { -- cgit From 17ddb68b54c6c550bc4614d33f7da69fc5f75633 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 12 Apr 2004 21:59:41 +0000 Subject: r190: More RPC updates (This used to be commit 0a67057e9626c1539f964e978537e24544784263) --- .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 53 ++++++++++++++++++++++ source4/lib/registry/tools/regtree.c | 2 +- 2 files changed, 54 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') 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 f5a7127ed6..472a851638 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -75,6 +75,8 @@ struct rpc_key_data { struct policy_handle pol; int num_subkeys; int num_values; + int max_valnamelen; + int max_valdatalen; }; struct { @@ -194,6 +196,54 @@ static WERROR rpc_open_key(REG_HANDLE *h, const char *name, REG_KEY **key) return rpc_key_put_rpc_data(*key, &mykeydata); } +static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value) +{ + struct winreg_EnumValue r; + struct winreg_Uint8buf vb; + struct winreg_Uint16buf bn; + struct rpc_data *mydata = parent->handle->backend_data; + struct winreg_EnumValueName vn; + NTSTATUS status; + struct rpc_key_data *mykeydata = parent->backend_data; + uint32 type = 0x0, requested_len = 0, returned_len = 0; + + /* FIXME */ + + r.in.handle = &mykeydata->pol; + r.in.enum_index = n; + r.in.type = r.out.type = &type; + r.in.requested_len = r.out.requested_len = &requested_len; + r.in.returned_len = r.out.returned_len = &returned_len; + bn.max_len = mykeydata->max_valnamelen*3; + bn.offset = 0; + bn.len = 0; + bn.buffer = NULL; + vn.max_len = mykeydata->max_valnamelen*3; + vn.buf = &bn; + r.in.name = r.out.name = &vn; + vb.max_len = mykeydata->max_valdatalen*3; + vb.offset = 0x0; + vb.len = 0x0; + vb.buffer = NULL; + r.in.value = r.out.value = &vb; + + status = dcerpc_winreg_EnumValue(mydata->pipe, parent->mem_ctx, &r); + if(NT_STATUS_IS_ERR(status)) { + DEBUG(0, ("Error in EnumValue: %s\n", nt_errstr(status))); + } + + if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { + *value = reg_val_new(parent, NULL); + (*value)->name = (char *)r.out.name->buf->buffer; + (*value)->data_type = type; + (*value)->data_len = r.out.value->len; + (*value)->data_blk = r.out.value->buffer; + return WERR_OK; + } + + return r.out.result; +} + static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey) { struct winreg_EnumKey r; @@ -269,6 +319,8 @@ static WERROR rpc_query_key(REG_KEY *k) if (W_ERROR_IS_OK(r.out.result)) { mykeydata->num_subkeys = r.out.num_subkeys; mykeydata->num_values = r.out.num_values; + mykeydata->max_valnamelen = r.out.max_valnamelen; + mykeydata->max_valdatalen = r.out.max_valbufsize; } return r.out.result; @@ -355,6 +407,7 @@ static struct registry_ops reg_backend_rpc = { .open_root_key = rpc_open_root, .open_key = rpc_open_key, .get_subkey_by_index = rpc_get_subkey_by_index, + .get_value_by_index = rpc_get_value_by_index, .add_key = rpc_add_key, .del_key = rpc_del_key, .free_key_backend_data = rpc_close_key, diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index eb32b1e55e..3e74db2557 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -53,7 +53,7 @@ void print_tree(int l, REG_KEY *p, int fullpath, int novals) } if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while fetching subkeys for '%s'\n", reg_key_get_path(p))); + DEBUG(0, ("Error occured while fetching values for '%s': %s\n", reg_key_get_path(p), win_errstr(error))); } } } -- cgit From 2199a6ffa909d1b53c7f4a3b87634432980c78d9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 13 Apr 2004 15:56:37 +0000 Subject: r199: More registry rpc updates (This used to be commit 02ddf78e5563b15cb45ae4bc6234469be0dc0210) --- .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 43 ++++++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) (limited to 'source4/lib/registry') 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 472a851638..6d1b293ee5 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -91,6 +91,8 @@ struct { { NULL, NULL } }; +static WERROR rpc_query_key(REG_KEY *k); + static WERROR rpc_open_registry(REG_HANDLE *h, const char *location, const char *credentials) { struct rpc_data *mydata = talloc(h->mem_ctx, sizeof(struct rpc_data)); @@ -204,27 +206,43 @@ static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value) struct rpc_data *mydata = parent->handle->backend_data; struct winreg_EnumValueName vn; NTSTATUS status; - struct rpc_key_data *mykeydata = parent->backend_data; + struct rpc_key_data *mykeydata; uint32 type = 0x0, requested_len = 0, returned_len = 0; + WERROR error; + + error = rpc_key_put_rpc_data(parent, &mykeydata); + if(!W_ERROR_IS_OK(error)) return error; + + /* Root is a special case */ + if(parent->backend_data == parent->handle->backend_data) { + return WERR_NO_MORE_ITEMS; + } + + if(mykeydata->num_values == -1) { + error = rpc_query_key(parent); + if(!W_ERROR_IS_OK(error)) return error; + } + + requested_len = mykeydata->max_valdatalen; - /* FIXME */ - r.in.handle = &mykeydata->pol; r.in.enum_index = n; r.in.type = r.out.type = &type; r.in.requested_len = r.out.requested_len = &requested_len; r.in.returned_len = r.out.returned_len = &returned_len; - bn.max_len = mykeydata->max_valnamelen*3; - bn.offset = 0; - bn.len = 0; - bn.buffer = NULL; - vn.max_len = mykeydata->max_valnamelen*3; - vn.buf = &bn; + vn.max_len = mykeydata->max_valnamelen * 2; + vn.len = 0; + vn.buf = NULL; + if(vn.max_len > 0) { + vn.len = 0; + vn.max_len = mykeydata->max_valnamelen*2; + vn.buf = ""; + } r.in.name = r.out.name = &vn; - vb.max_len = mykeydata->max_valdatalen*3; + vb.max_len = mykeydata->max_valdatalen; vb.offset = 0x0; vb.len = 0x0; - vb.buffer = NULL; + vb.buffer = talloc_array_p(parent->mem_ctx, uint8, mykeydata->max_valdatalen); r.in.value = r.out.value = &vb; status = dcerpc_winreg_EnumValue(mydata->pipe, parent->mem_ctx, &r); @@ -234,10 +252,11 @@ static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value) if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { *value = reg_val_new(parent, NULL); - (*value)->name = (char *)r.out.name->buf->buffer; + (*value)->name = r.out.name->buf; (*value)->data_type = type; (*value)->data_len = r.out.value->len; (*value)->data_blk = r.out.value->buffer; + exit(1); return WERR_OK; } -- cgit From c7a60a178f4b28f40d70f7b0c12bec6ab7af7846 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 13 Apr 2004 17:34:37 +0000 Subject: r200: fix compile errors (This used to be commit c64132ddc6396a599a2e13b893e8abf1f731478f) --- source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c | 3 ++- source4/lib/registry/reg_backend_w95/reg_backend_w95.c | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index 74d7bbd3b1..9a3005457e 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -1575,11 +1575,12 @@ static WERROR nt_close_registry (REG_HANDLE *h) static WERROR nt_open_registry (REG_HANDLE *h, const char *location, const char *credentials) { - REGF *regf = (REGF *)talloc_p(h->mem_ctx, REGF); + REGF *regf; REGF_HDR *regf_hdr; unsigned int regf_id, hbin_id; HBIN_HDR *hbin_hdr; + regf = (REGF *)talloc_p(h->mem_ctx, REGF); memset(regf, 0, sizeof(REGF)); regf->owner_sid_str = credentials; h->backend_data = regf; diff --git a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c index 31abd69854..cd07e0a179 100644 --- a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c @@ -224,13 +224,15 @@ static WERROR w95_get_subkey_by_index (REG_KEY *parent, int n, REG_KEY **key) static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *credentials) { - CREG *creg = talloc_p(h->mem_ctx, CREG); + CREG *creg; DWORD creg_id, rgkn_id; - memset(creg, 0, sizeof(CREG)); - h->backend_data = creg; DWORD i, nfree = 0; DWORD offset, end_offset; + creg = talloc_p(h->mem_ctx, CREG); + memset(creg, 0, sizeof(CREG)); + h->backend_data = creg; + if((creg->fd = open(location, O_RDONLY, 0000)) < 0) { return WERR_FOOBAR; } -- cgit From 6de32ddc2dbfe0685f361ed1a0dc11dff8ca19e5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 Apr 2004 21:39:03 +0000 Subject: r274: Be somewhat more POSIX compatible (This used to be commit c98a234d02d6190cf99ab1c9ff7b029f929e292a) --- .../lib/registry/reg_backend_dir/reg_backend_dir.c | 28 +++++++++++++++------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'source4/lib/registry') 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 375daa319b..960d5f3e04 100644 --- a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c @@ -80,22 +80,32 @@ static WERROR reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r) if(!d) return WERR_INVALID_PARAM; while((e = readdir(d))) { - if(e->d_type == DT_DIR && - strcmp(e->d_name, ".") && + if( strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) { - ar[(*count)] = reg_key_new_rel(e->d_name, k, NULL); - ar[(*count)]->backend_data = talloc_asprintf(ar[*count]->mem_ctx, "%s/%s", fullpath, e->d_name); - if(ar[(*count)])(*count)++; + struct stat stbuf; + char *thispath; + + /* Check if file is a directory */ + asprintf(&thispath, "%s/%s", fullpath, e->d_name); + stat(thispath, &stbuf); - if((*count) == max) { - max+=200; - ar = realloc(ar, sizeof(REG_KEY *) * max); + if(S_ISDIR(stbuf.st_mode)) { + ar[(*count)] = reg_key_new_rel(e->d_name, k, NULL); + ar[(*count)]->backend_data = talloc_strdup(ar[*count]->mem_ctx, thispath); + if(ar[(*count)])(*count)++; + + if((*count) == max) { + max+=200; + ar = realloc(ar, sizeof(REG_KEY *) * max); + } } + + SAFE_FREE(thispath); } } closedir(d); - + *r = ar; return WERR_OK; } -- cgit From f3d3b3c8091ad4540c330c07662540440affb96e Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 25 Apr 2004 22:15:48 +0000 Subject: r355: Fix a bunch of compiler warnings in the registry code. (This used to be commit 0be7a866dc39e2d63c9c114d0f668287259e7c9e) --- .../lib/registry/reg_backend_nt4/reg_backend_nt4.c | 11 ++++++++--- .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 14 ++++---------- .../lib/registry/reg_backend_w95/reg_backend_w95.c | 15 +++++++++------ source4/lib/registry/tools/regdiff.c | 21 +++++++++------------ source4/lib/registry/tools/regpatch.c | 2 -- source4/lib/registry/tools/regshell.c | 3 +-- source4/lib/registry/tools/regtree.c | 1 - 7 files changed, 31 insertions(+), 36 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index 9a3005457e..ff39954a9f 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -945,6 +945,8 @@ static WERROR vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size, REG_VAL **val return WERR_OK; } +#if 0 /* unused */ + static BOOL vl_verify(VL_TYPE vl, int count, int size) { if(!vl) return False; @@ -955,6 +957,8 @@ static BOOL vl_verify(VL_TYPE vl, int count, int size) return True; } +#endif + static WERROR lf_verify(REG_HANDLE *h, LF_HDR *lf_hdr, int size) { int lf_id; @@ -1128,6 +1132,8 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent return WERR_OK; } +#if 0 /* unused */ + /* * Allocate a new hbin block, set up the header for the block etc */ @@ -1463,8 +1469,6 @@ static unsigned int nt_store_security(REG_HANDLE *regf, KEY_SEC_DESC *sec) } -#if 0 - /* * Store a KEY in the file ... * @@ -1534,7 +1538,6 @@ static int nt_store_reg_key(REG_HANDLE *regf, REG_KEY *key) error: return 0; } -#endif /* * Store the registry header ... @@ -1563,6 +1566,8 @@ error: return NULL; } +#endif + static WERROR nt_close_registry (REG_HANDLE *h) { REGF *regf = h->backend_data; 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 6d1b293ee5..a24df893fb 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -192,7 +192,6 @@ static WERROR rpc_key_put_rpc_data(REG_KEY *k, struct rpc_key_data **data) static WERROR rpc_open_key(REG_HANDLE *h, const char *name, REG_KEY **key) { - WERROR error; struct rpc_key_data *mykeydata; *key = reg_key_new_abs(name, h, NULL); return rpc_key_put_rpc_data(*key, &mykeydata); @@ -202,7 +201,6 @@ static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value) { struct winreg_EnumValue r; struct winreg_Uint8buf vb; - struct winreg_Uint16buf bn; struct rpc_data *mydata = parent->handle->backend_data; struct winreg_EnumValueName vn; NTSTATUS status; @@ -272,9 +270,7 @@ static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey) struct rpc_data *mydata = parent->handle->backend_data; struct rpc_key_data *mykeydata = parent->backend_data; WERROR error; - int i; NTSTATUS status; - TALLOC_CTX *mem_ctx; /* If parent is the root key, list the hives */ if(parent->backend_data == mydata) { @@ -321,10 +317,8 @@ static WERROR rpc_query_key(REG_KEY *k) { NTSTATUS status; struct winreg_QueryInfoKey r; - struct rpc_data *mydata = k->handle->backend_data; - struct rpc_key_data *mykeydata; - WERROR error = rpc_key_put_rpc_data(k, &mykeydata); - + struct rpc_data *mydata = k->handle->backend_data; + struct rpc_key_data *mykeydata; r.in.handle = &mykeydata->pol; init_winreg_String(&r.in.class, NULL); @@ -387,7 +381,7 @@ static WERROR rpc_num_values(REG_KEY *key, int *count) { if(!W_ERROR_IS_OK(error)) return error; if(mykeydata->num_values == -1) { - WERROR error = rpc_query_key(key); + error = rpc_query_key(key); if(!W_ERROR_IS_OK(error)) return error; } @@ -411,7 +405,7 @@ static WERROR rpc_num_subkeys(REG_KEY *key, int *count) { if(!W_ERROR_IS_OK(error)) return error; if(mykeydata->num_subkeys == -1) { - WERROR error = rpc_query_key(key); + error = rpc_query_key(key); if(!W_ERROR_IS_OK(error)) return error; } diff --git a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c index cd07e0a179..80108fd541 100644 --- a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c @@ -137,6 +137,8 @@ static DWORD str_to_dword(const char *a) { return ret; } +#if 0 /* unused */ + static DWORD calc_hash(const char *str) { DWORD ret = 0; int i; @@ -152,7 +154,7 @@ static void parse_rgkn_block(CREG *creg, off_t start_off, off_t end_off) for(i = start_off; end_off - i > sizeof(RGKN_KEY); i+= sizeof(RGKN_KEY)) { RGKN_KEY *key = (RGKN_KEY *)LOCN_RGKN(creg, i); if(key->type == 0) { - DEBUG(4,("Regular, id: %d, %d, parent: %x, firstchild: %x, next: %x hash: %lX\n", key->id.id, key->id.rgdb, key->parent_offset, key->first_child_offset, key->next_offset, key->hash)); + DEBUG(4,("Regular, id: %d, %d, parent: %x, firstchild: %x, next: %x hash: %lX\n", key->id.id, key->id.rgdb, key->parent_offset, key->first_child_offset, key->next_offset, (long)key->hash)); } else if(key->type == 0x80000000) { DEBUG(3,("free\n")); i += key->hash; @@ -162,6 +164,8 @@ static void parse_rgkn_block(CREG *creg, off_t start_off, off_t end_off) } } +#endif + static void parse_rgdb_block(CREG *creg, RGDB_HDR *rgdb_hdr) { DWORD used_size = rgdb_hdr->size - rgdb_hdr->unused_size; @@ -226,8 +230,8 @@ static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *cre { CREG *creg; DWORD creg_id, rgkn_id; - DWORD i, nfree = 0; - DWORD offset, end_offset; + DWORD i; + DWORD offset; creg = talloc_p(h->mem_ctx, CREG); memset(creg, 0, sizeof(CREG)); @@ -284,8 +288,8 @@ static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *cre RGDB_HDR *rgdb_hdr = (RGDB_HDR *)LOCN_RGDB_BLOCK(creg, offset); if(strncmp((char *)&(rgdb_hdr->RGDB_ID), "RGDB", 4)) { - DEBUG(0, ("unrecognized rgdb entry: %4s, %s\n", - &rgdb_hdr->RGDB_ID, location)); + DEBUG(0, ("unrecognized rgdb entry: %4d, %s\n", + rgdb_hdr->RGDB_ID, location)); return WERR_FOOBAR; } else { DEBUG(3, ("Valid rgdb entry, first free id: %d, max id: %d\n", rgdb_hdr->first_free_id, rgdb_hdr->max_id)); @@ -317,7 +321,6 @@ static WERROR w95_close_reg(REG_HANDLE *h) static WERROR w95_fetch_values(REG_KEY *k, int *count, REG_VAL ***values) { RGKN_KEY *rgkn_key = k->backend_data; - RGDB_VALUE *val; DWORD i; DWORD offset = 0; RGDB_KEY *rgdb_key = LOCN_RGDB_KEY((CREG *)k->handle->backend_data, rgkn_key->id.rgdb, rgkn_key->id.id); diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 94cdf8c8af..305a7a1e46 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -23,7 +23,7 @@ void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) { - int i, numkeys1, numvals1, numvals2, numkeys2; + int i; REG_KEY *t1,*t2; REG_VAL *v1, *v2; WERROR error1, error2; @@ -33,12 +33,12 @@ void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) if(W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { fprintf(out, "-%s\n", reg_key_get_path(t1)+1); } else if(!W_ERROR_IS_OK(error2)) { - DEBUG(0, ("Error occured while getting subkey by name: %d\n", error2)); + DEBUG(0, ("Error occured while getting subkey by name: %d\n", W_ERROR_V(error2))); } } if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while getting subkey by index: %d\n", error1)); + DEBUG(0, ("Error occured while getting subkey by index: %d\n", W_ERROR_V(error1))); return; } @@ -47,13 +47,13 @@ void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) if(W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { fprintf(out, "\n[%s]\n", reg_key_get_path(t1)+1); } else if(!W_ERROR_IS_OK(error2)) { - DEBUG(0, ("Error occured while getting subkey by name: %d\n", error2)); + DEBUG(0, ("Error occured while getting subkey by name: %d\n", W_ERROR_V(error2))); } writediff(t2, t1, out); } if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while getting subkey by index: %d\n", error1)); + DEBUG(0, ("Error occured while getting subkey by index: %d\n", W_ERROR_V(error1))); return; } @@ -65,12 +65,12 @@ void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) } if(!W_ERROR_IS_OK(error2) && !W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - DEBUG(0, ("Error occured while getting value by name: %d\n", error2)); + DEBUG(0, ("Error occured while getting value by name: %d\n", W_ERROR_V(error2))); } } if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while getting value by index: %d\n", error1)); + DEBUG(0, ("Error occured while getting value by index: %d\n", W_ERROR_V(error1))); return; } @@ -81,22 +81,20 @@ void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) } else if(W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { fprintf(out, "\"%s\"=-\n", reg_val_name(v1)); } else { - DEBUG(0, ("Error occured while getting value by name: %d\n", error2)); + DEBUG(0, ("Error occured while getting value by name: %d\n", W_ERROR_V(error2))); } } if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while getting value by index: %d\n", error1)); + DEBUG(0, ("Error occured while getting value by index: %d\n", W_ERROR_V(error1))); return; } } int main (int argc, char **argv) { - uint32 setparms, checkparms; int opt; poptContext pc; - REG_KEY *root; const char *backend1 = NULL, *backend2 = NULL; const char *location2; const char *credentials1= NULL, *credentials2 = NULL; @@ -105,7 +103,6 @@ int main (int argc, char **argv) REG_HANDLE *h2; REG_KEY *root1 = NULL, *root2; int from_null = 0; - int fullpath = 0, no_values = 0; WERROR error; struct poptOption long_options[] = { POPT_AUTOHELP diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 9a51b0f7ff..e632edaa49 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -754,7 +754,6 @@ int nt_apply_reg_command_file(REG_KEY *root, const char *cmd_file_name) int main (int argc, char **argv) { - uint32 setparms, checkparms; int opt; poptContext pc; REG_KEY *root; @@ -763,7 +762,6 @@ int main (int argc, char **argv) const char *patch; const char *backend = "dir"; REG_HANDLE *h; - int fullpath = 0, no_values = 0; WERROR error; struct poptOption long_options[] = { POPT_AUTOHELP diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 18399b5bda..8ee2a65d06 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -58,7 +58,7 @@ static REG_KEY *cmd_ck(REG_KEY *cur, int argc, char **argv) static REG_KEY *cmd_ls(REG_KEY *cur, int argc, char **argv) { - int i, num; + int i; WERROR error; REG_VAL *value; REG_KEY *sub; @@ -198,7 +198,6 @@ REG_KEY *process_cmd(REG_KEY *k, char *line) int main (int argc, char **argv) { - uint32 setparms, checkparms; int opt; char *backend = "dir"; char *credentials = NULL; diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 3e74db2557..94018bdc5c 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -60,7 +60,6 @@ void print_tree(int l, REG_KEY *p, int fullpath, int novals) int main (int argc, char **argv) { - uint32 setparms, checkparms; int opt; char *backend = "dir", *credentials = NULL; poptContext pc; -- cgit From 4c991c6edd2a46d7452096ba80c00e7ab4c95924 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 30 Apr 2004 12:52:58 +0000 Subject: r425: add some comments to ugly code parts we should take care of 'char *' and 'const char *' and DO NOT mix them! Jelmer: please fix this metze (This used to be commit cd609eb2fe9303825d5562047d57fd553b2601bd) --- source4/lib/registry/common/reg_interface.c | 2 +- source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index fdbb7345d2..3600ab62ea 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -160,7 +160,6 @@ WERROR reg_open_key(REG_KEY *parent, const char *name, REG_KEY **result) mem_ctx = talloc_init("mem_ctx"); fullname = talloc_asprintf(mem_ctx, "%s%s%s", parent->path, parent->path[strlen(parent->path)-1] == '\\'?"":"\\", name); -\ if(!parent->handle->functions->open_key) { DEBUG(0, ("Registry backend doesn't have get_subkey_by_name nor open_key!\n")); @@ -432,6 +431,7 @@ WERROR reg_key_add_name_recursive(REG_KEY *parent, const char *path) { REG_KEY *cur, *prevcur = parent; WERROR error; + /* FIXME: we should never write to a 'const char *' !!! --metze */ char *begin = (char *)path, *end; while(1) { 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 a24df893fb..de2c2261b9 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -234,6 +234,7 @@ static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value) if(vn.max_len > 0) { vn.len = 0; vn.max_len = mykeydata->max_valnamelen*2; + /* FIXME: we should not point a 'char *' to a const buffer!!! --metze*/ vn.buf = ""; } r.in.name = r.out.name = &vn; -- cgit From 6a8355a6282563e3198c05dd6eb82107e449682c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 4 May 2004 13:18:29 +0000 Subject: r467: hopefully get the buildfarm compiling fine now... metze (This used to be commit d15f0e18bb43608c611cfe78fc79db9ee10e1eb2) --- source4/lib/registry/tools/gregedit.c | 6 ++++-- source4/lib/registry/tools/regdiff.c | 4 ++-- source4/lib/registry/tools/regpatch.c | 2 +- source4/lib/registry/tools/regshell.c | 6 +++--- source4/lib/registry/tools/regtree.c | 5 +++-- 5 files changed, 13 insertions(+), 10 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/gregedit.c b/source4/lib/registry/tools/gregedit.c index 10e5f45468..4bbde9a37d 100644 --- a/source4/lib/registry/tools/gregedit.c +++ b/source4/lib/registry/tools/gregedit.c @@ -723,10 +723,12 @@ GtkWidget* create_savefilewin (void) return savefilewin; } -int main (int argc, char *argv[]) + int main(int argc, char *argv[]) { poptContext pc; - const char *backend = NULL, *credentials = NULL, *location; + const char *backend = NULL; + const char *credentials = NULL; + const char *location; int opt; struct poptOption long_options[] = { POPT_AUTOHELP diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 305a7a1e46..c3633ef0af 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -59,7 +59,7 @@ void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(newkey, i, &v1)); i++) { error2 = reg_key_get_value_by_name(oldkey, reg_val_name(v1), &v2); - if ((W_ERROR_IS_OK(error2) && reg_val_size(v2) != reg_val_size(v1) || memcmp(reg_val_data_blk(v1), reg_val_data_blk(v2), reg_val_size(v1))) + if (((W_ERROR_IS_OK(error2) && reg_val_size(v2) != reg_val_size(v1)) || memcmp(reg_val_data_blk(v1), reg_val_data_blk(v2), reg_val_size(v1))) || W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { fprintf(out, "\"%s\"=%s:%s\n", reg_val_name(v1), str_regtype(reg_val_type(v1)), reg_val_data_string(v1)); } @@ -91,7 +91,7 @@ void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) } } -int main (int argc, char **argv) + int main(int argc, char **argv) { int opt; poptContext pc; diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index e632edaa49..d4b036afe9 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -752,7 +752,7 @@ int nt_apply_reg_command_file(REG_KEY *root, const char *cmd_file_name) return modified; } -int main (int argc, char **argv) + int main(int argc, char **argv) { int opt; poptContext pc; diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 8ee2a65d06..b78f4256f0 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -199,9 +199,9 @@ REG_KEY *process_cmd(REG_KEY *k, char *line) int main (int argc, char **argv) { int opt; - char *backend = "dir"; - char *credentials = NULL; - REG_KEY *curkey = NULL;; + const char *backend = "dir"; + const char *credentials = NULL; + REG_KEY *curkey = NULL; poptContext pc; WERROR error; REG_HANDLE *h; diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 94018bdc5c..4d0d4b2909 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -58,10 +58,11 @@ void print_tree(int l, REG_KEY *p, int fullpath, int novals) } } -int main (int argc, char **argv) + int main(int argc, char **argv) { int opt; - char *backend = "dir", *credentials = NULL; + const char *backend = "dir"; + const char *credentials = NULL; poptContext pc; REG_KEY *root; REG_HANDLE *h; -- cgit From b2d1f7890765fca5a119d43f4906e885c245005f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 12 May 2004 16:13:32 +0000 Subject: r655: Fix if() logic (This used to be commit 09096cfc3e1b35b4ac944cf84bfdec6ee44e06bf) --- source4/lib/registry/tools/regdiff.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index c3633ef0af..888270f61f 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -24,7 +24,7 @@ void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) { int i; - REG_KEY *t1,*t2; + REG_KEY *t1, *t2; REG_VAL *v1, *v2; WERROR error1, error2; @@ -59,7 +59,7 @@ void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(newkey, i, &v1)); i++) { error2 = reg_key_get_value_by_name(oldkey, reg_val_name(v1), &v2); - if (((W_ERROR_IS_OK(error2) && reg_val_size(v2) != reg_val_size(v1)) || memcmp(reg_val_data_blk(v1), reg_val_data_blk(v2), reg_val_size(v1))) + if ((W_ERROR_IS_OK(error2) && (reg_val_size(v2) != reg_val_size(v1) || memcmp(reg_val_data_blk(v1), reg_val_data_blk(v2), reg_val_size(v1)))) || W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { fprintf(out, "\"%s\"=%s:%s\n", reg_val_name(v1), str_regtype(reg_val_type(v1)), reg_val_data_string(v1)); } -- cgit From f236700ef67d4f93ec56ec7808584552e94e0dfe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 May 2004 10:20:53 +0000 Subject: r665: merge over the new build system from my tmp branch to the main SAMBA_4_0 tree. NOTE: that it's not completely ready, but it's functional:-) metze (This used to be commit c78a2ddb28ec50d6570a83b1f66f18a5c3621731) --- source4/lib/registry/common/reg_interface.c | 2 +- source4/lib/registry/config.m4 | 34 +++++++++++++------ .../lib/registry/reg_backend_dir/reg_backend_dir.c | 2 +- .../registry/reg_backend_gconf/reg_backend_gconf.c | 2 +- .../lib/registry/reg_backend_ldb/reg_backend_ldb.c | 4 +-- .../lib/registry/reg_backend_nt4/reg_backend_nt4.c | 2 +- .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 2 +- .../lib/registry/reg_backend_w95/reg_backend_w95.c | 2 +- .../registry/reg_backend_wine/reg_backend_wine.c | 2 +- source4/lib/registry/tools/gregedit.c | 39 +++++++++------------- source4/lib/registry/tools/regdiff.c | 2 +- source4/lib/registry/tools/regpatch.c | 2 +- source4/lib/registry/tools/regshell.c | 4 +-- source4/lib/registry/tools/regtree.c | 2 +- 14 files changed, 52 insertions(+), 49 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 3600ab62ea..4d1726c542 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -83,7 +83,7 @@ WERROR reg_open(const char *backend, const char *location, const char *credentia if (!NT_STATUS_IS_OK(status)) return WERR_GENERAL_FAILURE; - static_init_reg; + static_init_registry; reg_first_init = False; } diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index d8acb26397..af4470d983 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -5,16 +5,28 @@ if test t$BLDSHARED = ttrue; then fi LIBWINREG=libwinregistry -PKG_CHECK_MODULES(GCONF, gconf-2.0, [ SMB_MODULE_DEFAULT(reg_gconf,STATIC) - CFLAGS="$CFLAGS $GCONF_CFLAGS";], [AC_MSG_WARN([GConf not found, not building reg_gconf])]) +PKG_CHECK_MODULES(GCONF, gconf-2.0, [ SMB_MODULE_DEFAULT(registry_gconf,STATIC) + CFLAGS="$CFLAGS $GCONF_CFLAGS";], [AC_MSG_WARN([GConf not found, not building registry_gconf])]) +AC_CONFIG_FILES(lib/registry/winregistry.pc) -PKG_CHECK_MODULES(GTK, glib-2.0 gtk+-2.0, [ CFLAGS="$CFLAGS $GTK_CFLAGS"; ], [ AC_MSG_WARN([Will be unable to build gregedit])]) +SMB_BINARY_ENABLE(gregedit,NO) -SMB_MODULE(reg_nt4, REG, STATIC, lib/registry/reg_backend_nt4/reg_backend_nt4.o) -SMB_MODULE(reg_w95, REG, STATIC, lib/registry/reg_backend_w95/reg_backend_w95.o) -SMB_MODULE(reg_dir, REG, STATIC, lib/registry/reg_backend_dir/reg_backend_dir.o) -SMB_MODULE(reg_rpc, REG, STATIC, lib/registry/reg_backend_rpc/reg_backend_rpc.o) -SMB_MODULE(reg_gconf, REG, NOT, lib/registry/reg_backend_gconf/reg_backend_gconf.o, [], [$GCONF_LIBS]) -SMB_MODULE(reg_ldb, REG, NOT, lib/registry/reg_backend_ldb/reg_backend_ldb.o) -SMB_SUBSYSTEM(REG,lib/registry/common/reg_interface.o,[lib/registry/common/reg_objects.o lib/registry/common/reg_util.o],lib/registry/common/winregistry_proto.h,[]) -AC_CONFIG_FILES(lib/registry/winregistry.pc) +PKG_CHECK_MODULES(GTK, glib-2.0 gtk+-2.0, [ SMB_BINARY_ENABLE(gregedit,YES) + CFLAGS="$CFLAGS $GTK_CFLAGS"; ], [ AC_MSG_WARN([Will be unable to build gregedit])]) + +SMB_MODULE(registry_nt4, REGISTRY, STATIC, lib/registry/reg_backend_nt4/reg_backend_nt4.o) +SMB_MODULE(registry_w95, REGISTRY, STATIC, lib/registry/reg_backend_w95/reg_backend_w95.o) +SMB_MODULE(registry_dir, REGISTRY, STATIC, lib/registry/reg_backend_dir/reg_backend_dir.o) +SMB_MODULE(registry_rpc, REGISTRY, STATIC, lib/registry/reg_backend_rpc/reg_backend_rpc.o,[],[],[LIBSMB]) +SMB_MODULE(registry_gconf, REGISTRY, NOT, lib/registry/reg_backend_gconf/reg_backend_gconf.o]) +SMB_MODULE(registry_ldb, REGISTRY, NOT, lib/registry/reg_backend_ldb/reg_backend_ldb.o,[],[],[LIBLDB]) +SMB_SUBSYSTEM(REGISTRY,lib/registry/common/reg_interface.o, + [lib/registry/common/reg_objects.o lib/registry/common/reg_util.o], + [], + [LIBBASIC]) + +SMB_BINARY(regdiff, [REG], [BIN], lib/registry/tools/regdiff.o,[],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) +SMB_BINARY(regpatch, [REG], [BIN], lib/registry/tools/regpatch.o,[],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) +SMB_BINARY(regshell, [REG], [BIN], lib/registry/tools/regshell.o,[],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) +SMB_BINARY(regtree, [REG], [BIN], lib/registry/tools/regtree.o,[],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) +SMB_BINARY(gregedit, [REG], [BIN], lib/registry/tools/gregedit.o,[],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) 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 960d5f3e04..517324fdd2 100644 --- a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c @@ -138,7 +138,7 @@ static struct registry_ops reg_backend_dir = { .del_value = reg_dir_del_value, }; -NTSTATUS reg_dir_init(void) +NTSTATUS registry_dir_init(void) { return register_backend("registry", ®_backend_dir); } diff --git a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c index 1acb3cbcec..8f9fd6625b 100644 --- a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c +++ b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c @@ -194,7 +194,7 @@ static struct registry_ops reg_backend_gconf = { */ }; -NTSTATUS reg_gconf_init(void) +NTSTATUS registry_gconf_init(void) { return register_backend("registry", ®_backend_gconf); } diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index 9e561b1e6c..498dc6991b 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -21,7 +21,7 @@ #include "includes.h" #include "lib/registry/common/registry.h" -char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path) +static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path) { char *ret = talloc_strdup(mem_ctx, "(dn="); char *begin = (char *)path; @@ -116,7 +116,7 @@ static struct registry_ops reg_backend_ldb = { .fetch_subkeys = ldb_fetch_subkeys, }; -NTSTATUS reg_ldb_init(void) +NTSTATUS registry_ldb_init(void) { return register_backend("registry", ®_backend_ldb); } diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index ff39954a9f..cb3c284811 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -1752,7 +1752,7 @@ static struct registry_ops reg_backend_nt4 = { */ }; -NTSTATUS reg_nt4_init(void) +NTSTATUS registry_nt4_init(void) { return register_backend("registry", ®_backend_nt4); } 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 de2c2261b9..0b2919366d 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -429,7 +429,7 @@ static struct registry_ops reg_backend_rpc = { .num_values = rpc_num_values, }; -NTSTATUS reg_rpc_init(void) +NTSTATUS registry_rpc_init(void) { return register_backend("registry", ®_backend_rpc); } diff --git a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c index 80108fd541..c5d2e24103 100644 --- a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c @@ -361,7 +361,7 @@ static struct registry_ops reg_backend_w95 = { .get_subkey_by_index = w95_get_subkey_by_index, }; -NTSTATUS reg_w95_init(void) +NTSTATUS registry_w95_init(void) { return register_backend("registry", ®_backend_w95); } diff --git a/source4/lib/registry/reg_backend_wine/reg_backend_wine.c b/source4/lib/registry/reg_backend_wine/reg_backend_wine.c index fd7d04bcf0..249af27e13 100644 --- a/source4/lib/registry/reg_backend_wine/reg_backend_wine.c +++ b/source4/lib/registry/reg_backend_wine/reg_backend_wine.c @@ -26,7 +26,7 @@ static REG_OPS reg_backend_wine = { .name = "wine", }; -NTSTATUS reg_wine_init(void) +NTSTATUS registry_wine_init(void) { register_backend("registry", ®_backend_wine); return NT_STATUS_OK; diff --git a/source4/lib/registry/tools/gregedit.c b/source4/lib/registry/tools/gregedit.c index 4bbde9a37d..b5751ca00b 100644 --- a/source4/lib/registry/tools/gregedit.c +++ b/source4/lib/registry/tools/gregedit.c @@ -142,7 +142,7 @@ static void registry_load_root() gtk_widget_set_sensitive( save_as, True ); } -GtkWidget* create_rpcwin (void) +static GtkWidget* create_rpcwin (void) { GtkWidget *dialog_vbox1; GtkWidget *table1; @@ -242,7 +242,7 @@ static void on_open_file_activate (GtkMenuItem *menuitem, gpointer user_data) gtk_widget_destroy(openfilewin); } -void on_open_gconf_activate (GtkMenuItem *menuitem, +static void on_open_gconf_activate (GtkMenuItem *menuitem, gpointer user_data) { WERROR error = reg_open("gconf", NULL, NULL, ®istry); @@ -254,8 +254,7 @@ void on_open_gconf_activate (GtkMenuItem *menuitem, registry_load_root(); } -void -on_open_remote_activate (GtkMenuItem *menuitem, +static void on_open_remote_activate (GtkMenuItem *menuitem, gpointer user_data) { char *location, *credentials; @@ -281,8 +280,7 @@ on_open_remote_activate (GtkMenuItem *menuitem, } -void -on_save_activate (GtkMenuItem *menuitem, +static void on_save_activate (GtkMenuItem *menuitem, gpointer user_data) { WERROR error = reg_save(registry, NULL); @@ -292,8 +290,7 @@ on_save_activate (GtkMenuItem *menuitem, } -void -on_save_as_activate (GtkMenuItem *menuitem, +static void on_save_as_activate (GtkMenuItem *menuitem, gpointer user_data) { gint result; @@ -316,55 +313,49 @@ on_save_as_activate (GtkMenuItem *menuitem, } -void -on_quit_activate (GtkMenuItem *menuitem, +static void on_quit_activate (GtkMenuItem *menuitem, gpointer user_data) { gtk_main_quit(); } -void -on_cut_activate (GtkMenuItem *menuitem, +static void on_cut_activate (GtkMenuItem *menuitem, gpointer user_data) { /* FIXME */ } -void -on_copy_activate (GtkMenuItem *menuitem, +static void on_copy_activate (GtkMenuItem *menuitem, gpointer user_data) { /* FIXME */ } -void -on_paste_activate (GtkMenuItem *menuitem, +static void on_paste_activate (GtkMenuItem *menuitem, gpointer user_data) { /* FIXME */ } -void -on_delete_activate (GtkMenuItem *menuitem, +static void on_delete_activate (GtkMenuItem *menuitem, gpointer user_data) { /* FIXME */ } -void -on_about_activate (GtkMenuItem *menuitem, +static void on_about_activate (GtkMenuItem *menuitem, gpointer user_data) { gtk_dialog_run(GTK_DIALOG(create_aboutwin())); gtk_widget_destroy(aboutwin); } -void on_key_activate (GtkTreeView *treeview, +static void on_key_activate (GtkTreeView *treeview, GtkTreePath *path, gpointer user_data) { @@ -400,7 +391,7 @@ void on_key_activate (GtkTreeView *treeview, if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) gtk_show_werror(error); } -GtkWidget* create_mainwin (void) +static GtkWidget* create_mainwin (void) { GtkWidget *vbox1; GtkWidget *menubar; @@ -685,7 +676,7 @@ static GtkWidget* create_aboutwin (void) } -GtkWidget* create_openfilewin (void) +static GtkWidget* create_openfilewin (void) { GtkWidget *ok_button; GtkWidget *cancel_button; @@ -704,7 +695,7 @@ GtkWidget* create_openfilewin (void) return openfilewin; } -GtkWidget* create_savefilewin (void) +static GtkWidget* create_savefilewin (void) { GtkWidget *ok_button; GtkWidget *cancel_button; diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 888270f61f..d9419208cd 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -21,7 +21,7 @@ #include "includes.h" -void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) +static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) { int i; REG_KEY *t1, *t2; diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index d4b036afe9..64c2637a0c 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -664,7 +664,7 @@ static CMD_FILE *cmd_file_create(const char *file) char *str_type(unsigned char type); -int nt_apply_reg_command_file(REG_KEY *root, const char *cmd_file_name) +static int nt_apply_reg_command_file(REG_KEY *root, const char *cmd_file_name) { CMD *cmd; BOOL modified = False; diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index b78f4256f0..e8b01081e8 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -173,7 +173,7 @@ static REG_KEY *cmd_help(REG_KEY *cur, int argc, char **argv) return NULL; } -REG_KEY *process_cmd(REG_KEY *k, char *line) +static REG_KEY *process_cmd(REG_KEY *k, char *line) { int argc; char **argv = NULL; @@ -196,7 +196,7 @@ REG_KEY *process_cmd(REG_KEY *k, char *line) return k; } -int main (int argc, char **argv) + int main(int argc, char **argv) { int opt; const char *backend = "dir"; diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 4d0d4b2909..477c63af2c 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -21,7 +21,7 @@ #include "includes.h" -void print_tree(int l, REG_KEY *p, int fullpath, int novals) +static void print_tree(int l, REG_KEY *p, int fullpath, int novals) { REG_KEY *subkey; REG_VAL *value; -- cgit From 9c4a4514633e1b2296ab610b600b27fe439404fa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 May 2004 10:38:11 +0000 Subject: r668: fix the build metze (This used to be commit ba5e71f59e0547aa8329661c7fec73a6469726a5) --- source4/lib/registry/config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index af4470d983..85b0fad41a 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -18,7 +18,7 @@ SMB_MODULE(registry_nt4, REGISTRY, STATIC, lib/registry/reg_backend_nt4/reg_back SMB_MODULE(registry_w95, REGISTRY, STATIC, lib/registry/reg_backend_w95/reg_backend_w95.o) SMB_MODULE(registry_dir, REGISTRY, STATIC, lib/registry/reg_backend_dir/reg_backend_dir.o) SMB_MODULE(registry_rpc, REGISTRY, STATIC, lib/registry/reg_backend_rpc/reg_backend_rpc.o,[],[],[LIBSMB]) -SMB_MODULE(registry_gconf, REGISTRY, NOT, lib/registry/reg_backend_gconf/reg_backend_gconf.o]) +SMB_MODULE(registry_gconf, REGISTRY, NOT, lib/registry/reg_backend_gconf/reg_backend_gconf.o) SMB_MODULE(registry_ldb, REGISTRY, NOT, lib/registry/reg_backend_ldb/reg_backend_ldb.o,[],[],[LIBLDB]) SMB_SUBSYSTEM(REGISTRY,lib/registry/common/reg_interface.o, [lib/registry/common/reg_objects.o lib/registry/common/reg_util.o], -- cgit From 0a690c12a14b96a3f50b1e37875944cb3cf2b967 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 May 2004 10:53:52 +0000 Subject: r672: disable gregedit for now metze (This used to be commit 63600a2a9b2607130efe8e4336a48b5e9584d929) --- source4/lib/registry/config.m4 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index 85b0fad41a..ebe9a49439 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -11,7 +11,8 @@ AC_CONFIG_FILES(lib/registry/winregistry.pc) SMB_BINARY_ENABLE(gregedit,NO) -PKG_CHECK_MODULES(GTK, glib-2.0 gtk+-2.0, [ SMB_BINARY_ENABLE(gregedit,YES) +#disable grpedit for now +PKG_CHECK_MODULES(GTK, glib-2.0 gtk+-2.0, [ SMB_BINARY_ENABLE(gregedit,NO) CFLAGS="$CFLAGS $GTK_CFLAGS"; ], [ AC_MSG_WARN([Will be unable to build gregedit])]) SMB_MODULE(registry_nt4, REGISTRY, STATIC, lib/registry/reg_backend_nt4/reg_backend_nt4.o) -- cgit From 0b7f81e0f6e4a8eb8cd514541dcd39ebed07b7f0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 May 2004 11:32:39 +0000 Subject: r673: disable registry_gconf for now metze (This used to be commit 5bbf0c240730fc27b7341eb7c6891c7741640e74) --- source4/lib/registry/config.m4 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index ebe9a49439..7aafd2af71 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -5,7 +5,8 @@ if test t$BLDSHARED = ttrue; then fi LIBWINREG=libwinregistry -PKG_CHECK_MODULES(GCONF, gconf-2.0, [ SMB_MODULE_DEFAULT(registry_gconf,STATIC) +#disable registry_gconf for now +PKG_CHECK_MODULES(GCONF, gconf-2.0, [ SMB_MODULE_DEFAULT(registry_gconf,NOT) CFLAGS="$CFLAGS $GCONF_CFLAGS";], [AC_MSG_WARN([GConf not found, not building registry_gconf])]) AC_CONFIG_FILES(lib/registry/winregistry.pc) -- cgit From 14832874ee24f7c658882c9323e4c0b98b13ceda Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 May 2004 13:36:14 +0000 Subject: r681: don't init r.out.result.v metze (This used to be commit f7ded36699dabecf31ccaf765d667b7240822f8d) --- source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/lib/registry') 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 0b2919366d..c63ab20b82 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -291,7 +291,6 @@ static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey) r.in.class = &classname; tm.low = tm.high = 0x7fffffff; r.in.last_changed_time = &tm; - r.out.result.v = 0; r.in.enum_index = n; r.in.unknown = r.out.unknown = 0x0414; -- cgit From 0048335d9e3e0c7db61f6a325a3d7f49037810c3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 May 2004 15:37:57 +0000 Subject: r686: - Add SMB_EXT_LIB_FROM_PKGCONFIG() - Build gregedit and registry_gconf again if the required libs are found (gconf and gtk) (This used to be commit a63b704c36f2f5b52e932b6b2c99e7d664c9bdc7) --- source4/lib/registry/config.m4 | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index 7aafd2af71..da2c84d5c6 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -5,22 +5,28 @@ if test t$BLDSHARED = ttrue; then fi LIBWINREG=libwinregistry -#disable registry_gconf for now -PKG_CHECK_MODULES(GCONF, gconf-2.0, [ SMB_MODULE_DEFAULT(registry_gconf,NOT) - CFLAGS="$CFLAGS $GCONF_CFLAGS";], [AC_MSG_WARN([GConf not found, not building registry_gconf])]) AC_CONFIG_FILES(lib/registry/winregistry.pc) -SMB_BINARY_ENABLE(gregedit,NO) +SMB_BINARY_ENABLE(gregedit, NO) +SMB_MODULE_DEFAULT(registry_gconf, NOT) -#disable grpedit for now -PKG_CHECK_MODULES(GTK, glib-2.0 gtk+-2.0, [ SMB_BINARY_ENABLE(gregedit,NO) - CFLAGS="$CFLAGS $GTK_CFLAGS"; ], [ AC_MSG_WARN([Will be unable to build gregedit])]) +SMB_EXT_LIB_FROM_PKGCONFIG(gconf, gconf-2.0) + +if test t$SMB_EXT_LIB_ENABLE_gconf = tYES; then + SMB_MODULE_DEFAULT(registry_gconf, STATIC) +fi + +SMB_EXT_LIB_FROM_PKGCONFIG(gtk, [glib-2.0 gtk+-2.0]) + +if test t$SMB_EXT_LIB_ENABLE_gtk = tYES; then + SMB_BINARY_ENABLE(gregedit, YES) +fi SMB_MODULE(registry_nt4, REGISTRY, STATIC, lib/registry/reg_backend_nt4/reg_backend_nt4.o) SMB_MODULE(registry_w95, REGISTRY, STATIC, lib/registry/reg_backend_w95/reg_backend_w95.o) SMB_MODULE(registry_dir, REGISTRY, STATIC, lib/registry/reg_backend_dir/reg_backend_dir.o) SMB_MODULE(registry_rpc, REGISTRY, STATIC, lib/registry/reg_backend_rpc/reg_backend_rpc.o,[],[],[LIBSMB]) -SMB_MODULE(registry_gconf, REGISTRY, NOT, lib/registry/reg_backend_gconf/reg_backend_gconf.o) +SMB_MODULE(registry_gconf, REGISTRY, STATIC, lib/registry/reg_backend_gconf/reg_backend_gconf.o, [], [gconf]) SMB_MODULE(registry_ldb, REGISTRY, NOT, lib/registry/reg_backend_ldb/reg_backend_ldb.o,[],[],[LIBLDB]) SMB_SUBSYSTEM(REGISTRY,lib/registry/common/reg_interface.o, [lib/registry/common/reg_objects.o lib/registry/common/reg_util.o], @@ -31,4 +37,5 @@ SMB_BINARY(regdiff, [REG], [BIN], lib/registry/tools/regdiff.o,[],[CONFIG LIBBAS SMB_BINARY(regpatch, [REG], [BIN], lib/registry/tools/regpatch.o,[],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) SMB_BINARY(regshell, [REG], [BIN], lib/registry/tools/regshell.o,[],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) SMB_BINARY(regtree, [REG], [BIN], lib/registry/tools/regtree.o,[],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) -SMB_BINARY(gregedit, [REG], [BIN], lib/registry/tools/gregedit.o,[],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) +SMB_BINARY(gregedit, [REG], [BIN], lib/registry/tools/gregedit.o,[gtk],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) + -- cgit From 76d50e0d264e7d000fe8c0bb332b083084f2e1d8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 May 2004 16:45:01 +0000 Subject: r692: Add libwinregistry (This used to be commit 0ace3bf289777c30310a05e66fd674337413f0d8) --- source4/lib/registry/config.m4 | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index da2c84d5c6..7b05cbb982 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -39,3 +39,8 @@ SMB_BINARY(regshell, [REG], [BIN], lib/registry/tools/regshell.o,[],[CONFIG LIBB SMB_BINARY(regtree, [REG], [BIN], lib/registry/tools/regtree.o,[],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) SMB_BINARY(gregedit, [REG], [BIN], lib/registry/tools/gregedit.o,[gtk],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) +if test x"$experimental" = xyes; then + SMB_LIBRARY_ENABLE(libwinregistry, YES) +fi + +SMB_LIBRARY(libwinregistry, 0, 0, 1, , , REGISTRY) -- cgit From 072ef868c333f47cb3f2bf04a8edcf80c944b85e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 May 2004 16:47:32 +0000 Subject: r693: Make static (This used to be commit 30d3915c760ac5ee5e632539a3503fc7fed9cc63) --- source4/lib/registry/tools/gregedit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/gregedit.c b/source4/lib/registry/tools/gregedit.c index b5751ca00b..7b06b2266f 100644 --- a/source4/lib/registry/tools/gregedit.c +++ b/source4/lib/registry/tools/gregedit.c @@ -47,8 +47,8 @@ GtkWidget *rpcwin_user; GtkWidget *rpcwin_password; GtkWidget *save; GtkWidget *save_as; -GtkWidget* create_openfilewin (void); -GtkWidget* create_savefilewin (void); +static GtkWidget* create_openfilewin (void); +static GtkWidget* create_savefilewin (void); static GtkWidget* create_aboutwin (void); REG_HANDLE *registry = NULL; -- cgit From 77c30ebe9eaf72bdbfb519e252ad6d070c984fad Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 May 2004 20:12:26 +0000 Subject: r700: fix SMB_LIBRARY() to disable the lib by default metze (This used to be commit b6ac3021f275ba6b0ee0035933c290db4e8bda00) --- source4/lib/registry/config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index 7b05cbb982..77508063fc 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -39,7 +39,7 @@ SMB_BINARY(regshell, [REG], [BIN], lib/registry/tools/regshell.o,[],[CONFIG LIBB SMB_BINARY(regtree, [REG], [BIN], lib/registry/tools/regtree.o,[],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) SMB_BINARY(gregedit, [REG], [BIN], lib/registry/tools/gregedit.o,[gtk],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) -if test x"$experimental" = xyes; then +if test x"$experimental" = x"yes"; then SMB_LIBRARY_ENABLE(libwinregistry, YES) fi -- cgit From 53f2f8254b39b346c6ee718debd79bfc41207ec3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 14 May 2004 13:07:20 +0000 Subject: r734: Fix crash bug (This used to be commit 178cd902fc7069e3d613c46fc4845101a0229655) --- source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') 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 c63ab20b82..af3a6ac214 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -316,14 +316,19 @@ static WERROR rpc_add_key(REG_KEY *parent, const char *name, uint32 access_mask, static WERROR rpc_query_key(REG_KEY *k) { NTSTATUS status; + WERROR error; struct winreg_QueryInfoKey r; struct rpc_data *mydata = k->handle->backend_data; - struct rpc_key_data *mykeydata; + struct rpc_key_data *mykeydata; + r.in.handle = &mykeydata->pol; init_winreg_String(&r.in.class, NULL); - + + error = rpc_key_put_rpc_data(k, &mykeydata); + if(!W_ERROR_IS_OK(error)) return error; + status = dcerpc_winreg_QueryInfoKey(mydata->pipe, k->mem_ctx, &r); - + if (!NT_STATUS_IS_OK(status)) { printf("QueryInfoKey failed - %s\n", nt_errstr(status)); return ntstatus_to_werror(status); -- cgit From 1ca75ec3bb5d001958d02a8d05a63c44269e57b8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 May 2004 11:36:20 +0000 Subject: r819: Fix seg fault in rpc backend, found by Andrew Bartlett (This used to be commit d4cc4b3d682eb828208a621fe6b795f3e77c746a) --- source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') 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 af3a6ac214..74b25884d6 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -321,11 +321,11 @@ static WERROR rpc_query_key(REG_KEY *k) struct rpc_data *mydata = k->handle->backend_data; struct rpc_key_data *mykeydata; - r.in.handle = &mykeydata->pol; init_winreg_String(&r.in.class, NULL); error = rpc_key_put_rpc_data(k, &mykeydata); if(!W_ERROR_IS_OK(error)) return error; + r.in.handle = &mykeydata->pol; status = dcerpc_winreg_QueryInfoKey(mydata->pipe, k->mem_ctx, &r); -- cgit From bf52e242f53aeaac33eea69fbdfb3477634b90fb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 May 2004 18:49:25 +0000 Subject: r825: - Introduce support for multiple roots (or 'hives') - Clean up rpc backend (possible now that multiple hives are supported) (This used to be commit 8cd1b6bc70510fe576135a66351e9e3ea895c9ff) --- source4/lib/registry/common/reg_interface.c | 62 +++++++- source4/lib/registry/common/reg_objects.c | 7 + source4/lib/registry/common/registry.h | 24 +-- .../lib/registry/reg_backend_dir/reg_backend_dir.c | 10 +- .../lib/registry/reg_backend_nt4/reg_backend_nt4.c | 5 +- .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 168 ++++++++------------- .../lib/registry/reg_backend_w95/reg_backend_w95.c | 8 +- source4/lib/registry/tools/gregedit.c | 31 ++-- source4/lib/registry/tools/regdiff.c | 32 ++-- source4/lib/registry/tools/regpatch.c | 19 +-- source4/lib/registry/tools/regshell.c | 3 +- source4/lib/registry/tools/regtree.c | 12 +- 12 files changed, 213 insertions(+), 168 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 4d1726c542..3e5a545f9a 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -117,6 +117,25 @@ WERROR reg_open(const char *backend, const char *location, const char *credentia return werr; } +WERROR reg_open_key_abs(REG_HANDLE *handle, const char *name, REG_KEY **result) +{ + REG_KEY *hive; + WERROR error; + int i, hivelength; + + if(strchr(name, '\\')) hivelength = strchr(name, '\\')-name; + else hivelength = strlen(name); + + for(i = 0; W_ERROR_IS_OK(error); i++) { + error = reg_get_hive(handle, i, &hive); + if(W_ERROR_IS_OK(error) && !strncmp(reg_key_name(hive), name, hivelength)) { + return reg_open_key(hive, name, result); + } + } + + return error; +} + /* Open a key * First tries to use the open_key function from the backend * then falls back to get_subkey_by_name and later get_subkey_by_index @@ -166,7 +185,7 @@ WERROR reg_open_key(REG_KEY *parent, const char *name, REG_KEY **result) return WERR_NOT_SUPPORTED; } - error = parent->handle->functions->open_key(parent->handle, fullname, result); + error = parent->handle->functions->open_key(parent->handle, parent->hive, fullname, result); if(!W_ERROR_IS_OK(error)) { talloc_destroy(mem_ctx); @@ -175,6 +194,7 @@ WERROR reg_open_key(REG_KEY *parent, const char *name, REG_KEY **result) (*result)->handle = parent->handle; (*result)->path = fullname; + (*result)->hive = parent->hive; talloc_steal(mem_ctx, (*result)->mem_ctx, fullname); talloc_destroy(mem_ctx); @@ -285,6 +305,7 @@ WERROR reg_key_get_subkey_by_index(REG_KEY *key, int idx, REG_KEY **subkey) (*subkey)->path = talloc_asprintf((*subkey)->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", (*subkey)->name); (*subkey)->handle = key->handle; + (*subkey)->hive = key->hive; return WERR_OK;; @@ -315,6 +336,7 @@ WERROR reg_key_get_subkey_by_name(REG_KEY *key, const char *name, REG_KEY **subk (*subkey)->path = talloc_asprintf((*subkey)->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", (*subkey)->name); (*subkey)->handle = key->handle; + (*subkey)->hive = key->hive; return WERR_OK; } @@ -427,6 +449,25 @@ WERROR reg_val_del(REG_VAL *val) return WERR_OK; } +WERROR reg_key_add_name_recursive_abs(REG_HANDLE *handle, const char *name) +{ + REG_KEY *hive; + WERROR error; + int i, hivelength; + + if(strchr(name, '\\')) hivelength = strchr(name, '\\')-name; + else hivelength = strlen(name); + + for(i = 0; W_ERROR_IS_OK(error); i++) { + error = reg_get_hive(handle, i, &hive); + if(W_ERROR_IS_OK(error) && !strncmp(reg_key_name(hive), name, hivelength)) { + return reg_key_add_name_recursive(hive, name); + } + } + + return error; +} + WERROR reg_key_add_name_recursive(REG_KEY *parent, const char *path) { REG_KEY *cur, *prevcur = parent; @@ -516,21 +557,26 @@ void reg_free(REG_HANDLE *h) h->functions->close_registry(h); } -WERROR reg_get_root(REG_HANDLE *h, REG_KEY **key) +WERROR reg_get_hive(REG_HANDLE *h, int hivenum, REG_KEY **key) { WERROR ret; - if(h->functions->open_root_key) { - ret = h->functions->open_root_key(h, key); + + if(h->functions->get_hive) { + ret = h->functions->get_hive(h, hivenum, key); } else if(h->functions->open_key) { - ret = h->functions->open_key(h, "\\", key); + if(hivenum == 0) ret = h->functions->open_key(h, hivenum, "", key); + else ret = WERR_NO_MORE_ITEMS; } else { - DEBUG(0, ("Backend '%s' has neither open_root_key nor open_key method implemented\n", h->functions->name)); + DEBUG(0, ("Backend '%s' has neither open_root_key nor open_key or get_hive method implemented\n", h->functions->name)); ret = WERR_NOT_SUPPORTED; } if(W_ERROR_IS_OK(ret)) { (*key)->handle = h; - (*key)->path = talloc_strdup((*key)->mem_ctx, "\\"); + if(!(*key)->path) { + (*key)->path = talloc_strdup((*key)->mem_ctx, (*key)->name); + } + (*key)->hive = hivenum; } return ret; @@ -565,7 +611,7 @@ WERROR reg_key_get_parent(REG_KEY *key, REG_KEY **parent) REG_KEY *root; WERROR error; - error = reg_get_root(key->handle, &root); + error = reg_get_hive(key->handle, key->hive, &root); if(!W_ERROR_IS_OK(error)) return error; parent_name = strdup(reg_key_get_path(key)); diff --git a/source4/lib/registry/common/reg_objects.c b/source4/lib/registry/common/reg_objects.c index 787ec52127..7a92f413ff 100644 --- a/source4/lib/registry/common/reg_objects.c +++ b/source4/lib/registry/common/reg_objects.c @@ -139,6 +139,12 @@ char *reg_val_get_path(REG_VAL *v) } const char *reg_key_get_path(REG_KEY *k) +{ + SMB_REG_ASSERT(k); + return strchr(k->path, '\\')?strchr(k->path, '\\')+1:k->path; +} + +const char *reg_key_get_path_abs(REG_KEY *k) { SMB_REG_ASSERT(k); return k->path; @@ -168,6 +174,7 @@ REG_KEY *reg_key_new_rel(const char *name, REG_KEY *k, void *data) r = talloc(mem_ctx, sizeof(REG_KEY)); ZERO_STRUCTP(r); r->handle = k->handle; + r->hive = k->hive; r->name = talloc_strdup(mem_ctx, name); r->path = talloc_asprintf(mem_ctx, "%s%s%s", parent_path, *parent_path && parent_path[strlen(parent_path)-1] != '\\'?"\\":"", name); diff --git a/source4/lib/registry/common/registry.h b/source4/lib/registry/common/registry.h index 208bcae1e1..d4e8cccade 100644 --- a/source4/lib/registry/common/registry.h +++ b/source4/lib/registry/common/registry.h @@ -40,6 +40,7 @@ struct reg_key_s { int cache_values_count; REG_KEY **cache_subkeys; int cache_subkeys_count; + int hive; TALLOC_CTX *mem_ctx; int ref; }; @@ -61,10 +62,14 @@ struct reg_val_s { typedef void (*key_notification_function) (void); typedef void (*value_notification_function) (void); - /* * Container for function pointers to enumeration routines * for virtual registry view + * + * Backends can provide : + * - just one hive (example: nt4, w95) + * - several hives (example: rpc) + * */ struct registry_ops { @@ -73,17 +78,23 @@ struct registry_ops { WERROR (*sync_key)(REG_KEY *, const char *location); WERROR (*close_registry) (REG_HANDLE *); + /* Implement this one */ + WERROR (*get_hive) (REG_HANDLE *, int , REG_KEY **); + + /* Or this one */ + WERROR (*open_key) (REG_HANDLE *, int hive, const char *name, REG_KEY **); + /* Either implement these */ - WERROR (*open_root_key) (REG_HANDLE *, REG_KEY **); WERROR (*num_subkeys) (REG_KEY *, int *count); WERROR (*num_values) (REG_KEY *, int *count); WERROR (*get_subkey_by_index) (REG_KEY *, int idx, REG_KEY **); + /* Can not contain more then one level */ WERROR (*get_subkey_by_name) (REG_KEY *, const char *name, REG_KEY **); WERROR (*get_value_by_index) (REG_KEY *, int idx, REG_VAL **); + /* Can not contain more then one level */ WERROR (*get_value_by_name) (REG_KEY *, const char *name, REG_VAL **); /* Or these */ - WERROR (*open_key) (REG_HANDLE *, const char *name, REG_KEY **); WERROR (*fetch_subkeys) (REG_KEY *, int *count, REG_KEY ***); WERROR (*fetch_values) (REG_KEY *, int *count, REG_VAL ***); @@ -111,15 +122,8 @@ struct registry_ops { void (*free_val_backend_data) (REG_VAL *); }; -typedef struct reg_sub_tree_s { - char *path; - REG_HANDLE *handle; - struct reg_sub_tree_s *prev, *next; -} REG_SUBTREE; - struct reg_handle_s { struct registry_ops *functions; - REG_SUBTREE *subtrees; char *location; char *credentials; void *backend_data; 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 517324fdd2..cb61864d0c 100644 --- a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c @@ -38,16 +38,22 @@ static WERROR reg_dir_del_key(REG_KEY *k) return (rmdir((char *)k->backend_data) == 0)?WERR_OK:WERR_GENERAL_FAILURE; } -static WERROR reg_dir_open_key(REG_HANDLE *h, const char *name, REG_KEY **subkey) +static WERROR reg_dir_open_key(REG_HANDLE *h, int hive, const char *name, REG_KEY **subkey) { DIR *d; char *fullpath; REG_KEY *ret; - TALLOC_CTX *mem_ctx = talloc_init("tmp"); + TALLOC_CTX *mem_ctx; + + if(hive != 0) return WERR_NO_MORE_ITEMS; + if(!name) { DEBUG(0, ("NULL pointer passed as directory name!")); return WERR_INVALID_PARAM; } + + + mem_ctx = talloc_init("tmp"); fullpath = talloc_asprintf(mem_ctx, "%s%s", h->location, name); fullpath = reg_path_win2unix(fullpath); diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index cb3c284811..255389624e 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -1663,8 +1663,9 @@ static WERROR nt_open_registry (REG_HANDLE *h, const char *location, const char return WERR_OK; } -static WERROR nt_get_root_key(REG_HANDLE *h, REG_KEY **key) +static WERROR nt_get_root_key(REG_HANDLE *h, int hive, REG_KEY **key) { + if(hive != 0) return WERR_NO_MORE_ITEMS; return nk_to_key(h, ((REGF *)h->backend_data)->first_key, BLK_SIZE(((REGF *)h->backend_data)->first_key), NULL, key); } @@ -1737,7 +1738,7 @@ static struct registry_ops reg_backend_nt4 = { .name = "nt4", .open_registry = nt_open_registry, .close_registry = nt_close_registry, - .open_root_key = nt_get_root_key, + .get_hive = nt_get_root_key, .num_subkeys = nt_num_subkeys, .num_values = nt_num_values, .get_subkey_by_index = nt_key_by_index, 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 74b25884d6..d863568c17 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -22,9 +22,6 @@ /** * This is the RPC backend for the registry library. - * - * This backend is a little special. The root key is 'virtual'. All - * of its subkeys are the hives available on the remote server. */ static void init_winreg_String(struct winreg_String *name, const char *s) @@ -40,11 +37,11 @@ static void init_winreg_String(struct winreg_String *name, const char *s) } -#define openhive(u) static struct policy_handle *open_ ## u(struct dcerpc_pipe *p, REG_HANDLE *h) \ +#define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, REG_KEY *h, struct policy_handle *hnd) \ { \ struct winreg_Open ## u r; \ struct winreg_OpenUnknown unknown; \ - struct policy_handle *hnd = malloc(sizeof(struct policy_handle)); \ + NTSTATUS status; \ \ unknown.unknown0 = 0x84e0; \ unknown.unknown1 = 0x0000; \ @@ -52,12 +49,13 @@ static void init_winreg_String(struct winreg_String *name, const char *s) r.in.access_required = SEC_RIGHTS_MAXIMUM_ALLOWED; \ r.out.handle = hnd;\ \ - if (!NT_STATUS_IS_OK(dcerpc_winreg_Open ## u(p, h->mem_ctx, &r))) {\ + status = dcerpc_winreg_Open ## u(p, h->mem_ctx, &r); \ + if (NT_STATUS_IS_ERR(status)) {\ DEBUG(0,("Error executing open\n"));\ - return NULL;\ + return ntstatus_to_werror(status);\ }\ \ - return hnd;\ + return r.out.result;\ } openhive(HKLM) @@ -66,11 +64,6 @@ openhive(HKPD) openhive(HKU) openhive(HKCR) -struct rpc_data { - struct dcerpc_pipe *pipe; - struct policy_handle *hives[10]; -}; - struct rpc_key_data { struct policy_handle pol; int num_subkeys; @@ -81,7 +74,7 @@ struct rpc_key_data { struct { const char *name; - struct policy_handle *(*open) (struct dcerpc_pipe *p, REG_HANDLE *h); + WERROR (*open) (struct dcerpc_pipe *p, REG_KEY *k, struct policy_handle *h); } known_hives[] = { { "HKEY_LOCAL_MACHINE", open_HKLM }, { "HKEY_CURRENT_USER", open_HKCU }, @@ -95,7 +88,6 @@ static WERROR rpc_query_key(REG_KEY *k); static WERROR rpc_open_registry(REG_HANDLE *h, const char *location, const char *credentials) { - struct rpc_data *mydata = talloc(h->mem_ctx, sizeof(struct rpc_data)); char *binding = strdup(location); NTSTATUS status; char *user, *pass; @@ -106,40 +98,42 @@ static WERROR rpc_open_registry(REG_HANDLE *h, const char *location, const char pass = strchr(user, '%'); *pass = '\0'; pass++; - ZERO_STRUCTP(mydata); - - status = dcerpc_pipe_connect(&mydata->pipe, binding, + status = dcerpc_pipe_connect((struct dcerpc_pipe **)&h->backend_data, binding, DCERPC_WINREG_UUID, DCERPC_WINREG_VERSION, lp_workgroup(), user, pass); - - h->backend_data = mydata; return ntstatus_to_werror(status); } -static WERROR rpc_open_root(REG_HANDLE *h, REG_KEY **k) +static WERROR rpc_get_hive(REG_HANDLE *h, int n, REG_KEY **k) { - /* There's not really a 'root' key here */ - *k = reg_key_new_abs("\\", h, h->backend_data); - return WERR_OK; + struct rpc_key_data *mykeydata; + WERROR error; + if(!known_hives[n].name) return WERR_NO_MORE_ITEMS; + *k = reg_key_new_abs(known_hives[n].name, h, NULL); + (*k)->backend_data = mykeydata = talloc_p((*k)->mem_ctx, struct rpc_key_data); + mykeydata->num_values = -1; + mykeydata->num_subkeys = -1; + error = known_hives[n].open((struct dcerpc_pipe *)h->backend_data, *k, &mykeydata->pol); + return error; } static WERROR rpc_close_registry(REG_HANDLE *h) { - dcerpc_pipe_close(((struct rpc_data *)h->backend_data)->pipe); + dcerpc_pipe_close((struct dcerpc_pipe *)h->backend_data); return WERR_OK; } static WERROR rpc_key_put_rpc_data(REG_KEY *k, struct rpc_key_data **data) { - struct policy_handle *hive = NULL; struct winreg_OpenKey r; int i; struct rpc_data *mydata = k->handle->backend_data; + WERROR error; + REG_KEY *hivekey; struct rpc_key_data *mykeydata; - char *realkeyname, *hivename; if(k->backend_data) { *data = k->backend_data; @@ -151,57 +145,55 @@ static WERROR rpc_key_put_rpc_data(REG_KEY *k, struct rpc_key_data **data) mykeydata->num_values = -1; mykeydata->num_subkeys = -1; - /* First, ensure the handle to the hive is opened */ - realkeyname = strchr(k->path+1, '\\'); - if(realkeyname) hivename = strndup(k->path+1, realkeyname-k->path-1); - else hivename = strdup(k->path+1); - - for(i = 0; known_hives[i].name; i++) { - if(!strcmp(hivename, known_hives[i].name)) { - if(!mydata->hives[i]) mydata->hives[i] = known_hives[i].open(mydata->pipe, k->handle); - hive = mydata->hives[i]; - break; - } - } - - if(!hive) { - DEBUG(0, ("No such hive: %s\n", hivename)); - return WERR_FOOBAR; - } - - if(realkeyname && realkeyname[0] == '\\')realkeyname++; - - if(!realkeyname || !(*realkeyname)) { - mykeydata->pol = *hive; - return WERR_OK; - } - /* Then, open the handle using the hive */ memset(&r, 0, sizeof(struct winreg_OpenKey)); - r.in.handle = hive; - init_winreg_String(&r.in.keyname, realkeyname); + error = rpc_get_hive(k->handle, k->hive, &hivekey); + if(!W_ERROR_IS_OK(error))return error; + r.in.handle = &(((struct rpc_key_data *)hivekey->backend_data)->pol); + init_winreg_String(&r.in.keyname, reg_key_get_path(k)); r.in.unknown = 0x00000000; r.in.access_mask = 0x02000000; r.out.handle = &mykeydata->pol; - dcerpc_winreg_OpenKey(mydata->pipe, k->mem_ctx, &r); + dcerpc_winreg_OpenKey((struct dcerpc_pipe *)k->handle->backend_data, k->mem_ctx, &r); return r.out.result; } -static WERROR rpc_open_key(REG_HANDLE *h, const char *name, REG_KEY **key) +static WERROR rpc_open_key(REG_HANDLE *h, int hive, const char *name, REG_KEY **key) { struct rpc_key_data *mykeydata; + struct winreg_OpenKey r; + REG_KEY *hivekey; + WERROR error; + *key = reg_key_new_abs(name, h, NULL); - return rpc_key_put_rpc_data(*key, &mykeydata); + + (*key)->backend_data = mykeydata = talloc_p((*key)->mem_ctx, struct rpc_key_data); + mykeydata->num_values = -1; + mykeydata->num_subkeys = -1; + + /* Then, open the handle using the hive */ + + memset(&r, 0, sizeof(struct winreg_OpenKey)); + error = rpc_get_hive(h, hive, &hivekey); + if(!W_ERROR_IS_OK(error))return error; + r.in.handle = &(((struct rpc_key_data *)hivekey->backend_data)->pol); + init_winreg_String(&r.in.keyname, name); + r.in.unknown = 0x00000000; + r.in.access_mask = 0x02000000; + r.out.handle = &mykeydata->pol; + + dcerpc_winreg_OpenKey((struct dcerpc_pipe *)(*key)->handle->backend_data, (*key)->mem_ctx, &r); + + return r.out.result; } static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value) { struct winreg_EnumValue r; struct winreg_Uint8buf vb; - struct rpc_data *mydata = parent->handle->backend_data; struct winreg_EnumValueName vn; NTSTATUS status; struct rpc_key_data *mykeydata; @@ -211,11 +203,6 @@ static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value) error = rpc_key_put_rpc_data(parent, &mykeydata); if(!W_ERROR_IS_OK(error)) return error; - /* Root is a special case */ - if(parent->backend_data == parent->handle->backend_data) { - return WERR_NO_MORE_ITEMS; - } - if(mykeydata->num_values == -1) { error = rpc_query_key(parent); if(!W_ERROR_IS_OK(error)) return error; @@ -244,7 +231,7 @@ static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value) vb.buffer = talloc_array_p(parent->mem_ctx, uint8, mykeydata->max_valdatalen); r.in.value = r.out.value = &vb; - status = dcerpc_winreg_EnumValue(mydata->pipe, parent->mem_ctx, &r); + status = dcerpc_winreg_EnumValue((struct dcerpc_pipe *)parent->handle->backend_data, parent->mem_ctx, &r); if(NT_STATUS_IS_ERR(status)) { DEBUG(0, ("Error in EnumValue: %s\n", nt_errstr(status))); } @@ -273,13 +260,6 @@ static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey) WERROR error; NTSTATUS status; - /* If parent is the root key, list the hives */ - if(parent->backend_data == mydata) { - if(!known_hives[n].name) return WERR_NO_MORE_ITEMS; - *subkey = reg_key_new_rel(known_hives[n].name, parent, NULL); - return rpc_key_put_rpc_data(*subkey, &mykeydata); - } - error = rpc_key_put_rpc_data(parent, &mykeydata); if(!W_ERROR_IS_OK(error)) return error; @@ -295,7 +275,7 @@ static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey) r.in.enum_index = n; r.in.unknown = r.out.unknown = 0x0414; r.in.key_name_len = r.out.key_name_len = 0; - status = dcerpc_winreg_EnumKey(mydata->pipe, parent->mem_ctx, &r); + status = dcerpc_winreg_EnumKey((struct dcerpc_pipe *)parent->handle->backend_data, parent->mem_ctx, &r); if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { *subkey = reg_key_new_rel(r.out.out_name->name, parent, NULL); } @@ -306,7 +286,9 @@ static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey) static WERROR rpc_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *sec, REG_KEY **key) { struct rpc_key_data *mykeydata; - WERROR error = rpc_key_put_rpc_data(parent, &mykeydata); + WERROR error; + + error = rpc_key_put_rpc_data(parent, &mykeydata); if(!W_ERROR_IS_OK(error)) return error; /* FIXME */ @@ -318,16 +300,15 @@ static WERROR rpc_query_key(REG_KEY *k) NTSTATUS status; WERROR error; struct winreg_QueryInfoKey r; - struct rpc_data *mydata = k->handle->backend_data; struct rpc_key_data *mykeydata; - init_winreg_String(&r.in.class, NULL); - error = rpc_key_put_rpc_data(k, &mykeydata); if(!W_ERROR_IS_OK(error)) return error; + + init_winreg_String(&r.in.class, NULL); r.in.handle = &mykeydata->pol; - status = dcerpc_winreg_QueryInfoKey(mydata->pipe, k->mem_ctx, &r); + status = dcerpc_winreg_QueryInfoKey((struct dcerpc_pipe *)k->handle->backend_data, k->mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { printf("QueryInfoKey failed - %s\n", nt_errstr(status)); @@ -347,22 +328,21 @@ static WERROR rpc_query_key(REG_KEY *k) static WERROR rpc_del_key(REG_KEY *k) { NTSTATUS status; - struct rpc_data *mydata = k->handle->backend_data; - struct rpc_key_data *mykeydata; + struct rpc_key_data *mykeydata = k->backend_data; struct winreg_DeleteKey r; REG_KEY *parent; WERROR error; error = reg_key_get_parent(k, &parent); if(!W_ERROR_IS_OK(error)) return error; - + error = rpc_key_put_rpc_data(parent, &mykeydata); if(!W_ERROR_IS_OK(error)) return error; - + r.in.handle = &mykeydata->pol; init_winreg_String(&r.in.key, k->name); - status = dcerpc_winreg_DeleteKey(mydata->pipe, k->mem_ctx, &r); + status = dcerpc_winreg_DeleteKey((struct dcerpc_pipe *)k->handle->backend_data, k->mem_ctx, &r); return r.out.result; } @@ -373,15 +353,9 @@ static void rpc_close_key(REG_KEY *k) } static WERROR rpc_num_values(REG_KEY *key, int *count) { - struct rpc_key_data *mykeydata; + struct rpc_key_data *mykeydata = key->backend_data; WERROR error; - /* Root is a special case */ - if(key->backend_data == key->handle->backend_data) { - *count = 0; - return WERR_OK; - } - error = rpc_key_put_rpc_data(key, &mykeydata); if(!W_ERROR_IS_OK(error)) return error; @@ -395,20 +369,12 @@ static WERROR rpc_num_values(REG_KEY *key, int *count) { } static WERROR rpc_num_subkeys(REG_KEY *key, int *count) { - struct rpc_key_data *mykeydata; + struct rpc_key_data *mykeydata = key->backend_data; WERROR error; - - /* Root is a special case */ - if(key->backend_data == key->handle->backend_data) { - int i; - for(i = 0; known_hives[i].name; i++); - *count = i; - return WERR_OK; - } - + error = rpc_key_put_rpc_data(key, &mykeydata); if(!W_ERROR_IS_OK(error)) return error; - + if(mykeydata->num_subkeys == -1) { error = rpc_query_key(key); if(!W_ERROR_IS_OK(error)) return error; @@ -422,7 +388,7 @@ static struct registry_ops reg_backend_rpc = { .name = "rpc", .open_registry = rpc_open_registry, .close_registry = rpc_close_registry, - .open_root_key = rpc_open_root, + .get_hive = rpc_get_hive, .open_key = rpc_open_key, .get_subkey_by_index = rpc_get_subkey_by_index, .get_value_by_index = rpc_get_value_by_index, diff --git a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c index c5d2e24103..b014f4da66 100644 --- a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c @@ -179,12 +179,14 @@ static void parse_rgdb_block(CREG *creg, RGDB_HDR *rgdb_hdr) } } -static WERROR w95_open_root (REG_HANDLE *h, REG_KEY **key) +static WERROR w95_open_root (REG_HANDLE *h, int hive, REG_KEY **key) { CREG *creg = h->backend_data; + + if(hive != 0) return WERR_NO_MORE_ITEMS; /* First element in rgkn should be root key */ - *key = reg_key_new_abs("\\", h, LOCN_RGKN(creg, sizeof(RGKN_HDR))); + *key = reg_key_new_abs("", h, LOCN_RGKN(creg, sizeof(RGKN_HDR))); return WERR_OK; } @@ -356,7 +358,7 @@ static struct registry_ops reg_backend_w95 = { .name = "w95", .open_registry = w95_open_reg, .close_registry = w95_close_reg, - .open_root_key = w95_open_root, + .get_hive = w95_open_root, .fetch_values = w95_fetch_values, .get_subkey_by_index = w95_get_subkey_by_index, }; diff --git a/source4/lib/registry/tools/gregedit.c b/source4/lib/registry/tools/gregedit.c index 7b06b2266f..e8800c6ee9 100644 --- a/source4/lib/registry/tools/gregedit.c +++ b/source4/lib/registry/tools/gregedit.c @@ -1,6 +1,6 @@ /* Unix SMB/CIFS implementation. - Gtk registry frontend + GTK+ registry frontend Copyright (C) Jelmer Vernooij 2004 @@ -115,20 +115,25 @@ static void registry_load_root() { REG_KEY *root; GtkTreeIter iter, tmpiter; - WERROR error; + WERROR error = WERR_OK; + int i = 0; if(!registry) return; - error = reg_get_root(registry, &root); - if(!W_ERROR_IS_OK(error)) { - gtk_show_werror(error); - return; - } - gtk_tree_store_clear(store_keys); - /* Add the root */ - gtk_tree_store_append(store_keys, &iter, NULL); - gtk_tree_store_set (store_keys, + while(1) { + error = reg_get_hive(registry, i, &root); + if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { + return; + } + if(!W_ERROR_IS_OK(error)) { + gtk_show_werror(error); + return; + } + + /* Add the root */ + gtk_tree_store_append(store_keys, &iter, NULL); + gtk_tree_store_set (store_keys, &iter, 0, reg_key_name(root), @@ -136,7 +141,9 @@ static void registry_load_root() root, -1); - gtk_tree_store_append(store_keys, &tmpiter, &iter); + gtk_tree_store_append(store_keys, &tmpiter, &iter); + i++; + } gtk_widget_set_sensitive( save, True ); gtk_widget_set_sensitive( save_as, True ); diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index d9419208cd..7520e653bb 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -100,10 +100,11 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) const char *credentials1= NULL, *credentials2 = NULL; char *outputfile = NULL; FILE *fd = stdout; - REG_HANDLE *h2; + REG_HANDLE *h1, *h2; REG_KEY *root1 = NULL, *root2; int from_null = 0; - WERROR error; + int i; + WERROR error, error2; struct poptOption long_options[] = { POPT_AUTOHELP {"backend", 'b', POPT_ARG_STRING, NULL, 'b', "backend to use", NULL}, @@ -130,7 +131,6 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) setup_logging(argv[0], True); if(!from_null) { - REG_HANDLE *h1; const char *location1; location1 = poptGetArg(pc); if(!location1) { @@ -145,8 +145,6 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location1, backend1); return 1; } - - if(!W_ERROR_IS_OK(reg_get_root(h1, &root1))) return 1; } location2 = poptGetArg(pc); @@ -163,12 +161,6 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) return 1; } - error = reg_get_root(h2, &root2); - if(!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Can't open root key for '%s:%s'\n", backend2, location2); - return 1; - } - poptFreeContext(pc); if(outputfile) { @@ -182,7 +174,23 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) fprintf(fd, "REGEDIT4\n\n"); fprintf(fd, "; Generated using regdiff\n"); - writediff(root1, root2, fd); + error2 = error = WERR_OK; + + for(i = 0; ; i++) { + if(backend1) error = reg_get_hive(h1, i, &root1); + else root1 = NULL; + + if(!W_ERROR_IS_OK(error)) break; + + if(backend2) error2 = reg_get_hive(h2, i, &root2); + else root2 = NULL; + + if(!W_ERROR_IS_OK(error2)) break; + + writediff(root1, root2, fd); + + if(!root1 && !root2) break; + } fclose(fd); diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 64c2637a0c..77c0f710c1 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -664,7 +664,7 @@ static CMD_FILE *cmd_file_create(const char *file) char *str_type(unsigned char type); -static int nt_apply_reg_command_file(REG_KEY *root, const char *cmd_file_name) +static int nt_apply_reg_command_file(REG_HANDLE *r, const char *cmd_file_name) { CMD *cmd; BOOL modified = False; @@ -680,12 +680,12 @@ static int nt_apply_reg_command_file(REG_KEY *root, const char *cmd_file_name) */ switch (cmd->cmd) { case CMD_ADD_KEY: - error = reg_open_key(root, cmd->key, &tmp); + error = reg_open_key_abs(r, cmd->key, &tmp); /* If we found it, apply the other bits, else create such a key */ if (W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) { - if(W_ERROR_IS_OK(reg_key_add_name_recursive(root, cmd->key))) { - error = reg_open_key(root, cmd->key, &tmp); + if(W_ERROR_IS_OK(reg_key_add_name_recursive_abs(r, cmd->key))) { + error = reg_open_key_abs(r, cmd->key, &tmp); if(!W_ERROR_IS_OK(error)) { DEBUG(0, ("Error finding new key '%s' after it has been added\n", cmd->key)); continue; @@ -732,7 +732,7 @@ static int nt_apply_reg_command_file(REG_KEY *root, const char *cmd_file_name) * Find the key if it exists, and delete it ... */ - error = reg_open_key(root, cmd->key, &tmp); + error = reg_open_key_abs(r, cmd->key, &tmp); if(!W_ERROR_IS_OK(error)) { DEBUG(0, ("Unable to open key '%s'\n", cmd->key)); continue; @@ -756,7 +756,6 @@ static int nt_apply_reg_command_file(REG_KEY *root, const char *cmd_file_name) { int opt; poptContext pc; - REG_KEY *root; const char *location; const char *credentials = NULL; const char *patch; @@ -793,13 +792,7 @@ static int nt_apply_reg_command_file(REG_KEY *root, const char *cmd_file_name) if(!patch) patch = "/dev/stdin"; poptFreeContext(pc); - error = reg_get_root(h, &root); - if(!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error opening root!\n")); - return 1; - } - - nt_apply_reg_command_file(root, patch); + nt_apply_reg_command_file(h, patch); reg_free(h); diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index e8b01081e8..26312ad4bc 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -27,6 +27,7 @@ * rmval/rm - remove value * rmkey/rmdir - remove key * mkkey/mkdir - make key + * ch - change hive * help * exit */ @@ -227,7 +228,7 @@ static REG_KEY *process_cmd(REG_KEY *k, char *line) setup_logging("regtree", True); - error = reg_get_root(h, &curkey); + error = reg_get_hive(h, 0, &curkey); if(!W_ERROR_IS_OK(error)) return 1; diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 477c63af2c..e583194a56 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -60,7 +60,7 @@ static void print_tree(int l, REG_KEY *p, int fullpath, int novals) int main(int argc, char **argv) { - int opt; + int opt, i; const char *backend = "dir"; const char *credentials = NULL; poptContext pc; @@ -91,10 +91,14 @@ static void print_tree(int l, REG_KEY *p, int fullpath, int novals) } poptFreeContext(pc); - error = reg_get_root(h, &root); - if(!W_ERROR_IS_OK(error)) return 1; + error = WERR_OK; - print_tree(0, root, fullpath, no_values); + for(i = 0; W_ERROR_IS_OK(error); i++) { + error = reg_get_hive(h, i, &root); + if(!W_ERROR_IS_OK(error)) return 1; + + print_tree(0, root, fullpath, no_values); + } return 0; } -- cgit From f371d2454298b0e64978c04056da5635d7e72921 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 May 2004 12:01:20 +0000 Subject: r828: Some fixes in the core and regshell concerning hives and unicode (This used to be commit 25c27b176c9905f3968e955f33a6db41b0102a38) --- source4/lib/registry/common/reg_interface.c | 14 +++++++------- source4/lib/registry/common/reg_objects.c | 2 +- source4/lib/registry/common/registry.h | 2 +- .../lib/registry/reg_backend_nt4/reg_backend_nt4.c | 5 ++++- source4/lib/registry/tools/regshell.c | 21 +++++++++++++++++---- source4/lib/registry/tools/regtree.c | 6 +++--- 6 files changed, 33 insertions(+), 17 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 3e5a545f9a..e748c836cf 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -176,15 +176,15 @@ WERROR reg_open_key(REG_KEY *parent, const char *name, REG_KEY **result) return WERR_OK; } - mem_ctx = talloc_init("mem_ctx"); - - fullname = talloc_asprintf(mem_ctx, "%s%s%s", parent->path, parent->path[strlen(parent->path)-1] == '\\'?"":"\\", name); - if(!parent->handle->functions->open_key) { DEBUG(0, ("Registry backend doesn't have get_subkey_by_name nor open_key!\n")); return WERR_NOT_SUPPORTED; } + mem_ctx = talloc_init("mem_ctx"); + + fullname = talloc_asprintf(mem_ctx, "%s%s%s", reg_key_get_path(parent), strlen(reg_key_get_path(parent))?"\\":"", name); + error = parent->handle->functions->open_key(parent->handle, parent->hive, fullname, result); if(!W_ERROR_IS_OK(error)) { @@ -193,7 +193,7 @@ WERROR reg_open_key(REG_KEY *parent, const char *name, REG_KEY **result) } (*result)->handle = parent->handle; - (*result)->path = fullname; + (*result)->path = talloc_asprintf((*result)->mem_ctx, "%s\\%s", reg_key_get_path_abs(parent), (*result)->name); (*result)->hive = parent->hive; talloc_steal(mem_ctx, (*result)->mem_ctx, fullname); @@ -303,7 +303,7 @@ WERROR reg_key_get_subkey_by_index(REG_KEY *key, int idx, REG_KEY **subkey) return WERR_NOT_SUPPORTED; } - (*subkey)->path = talloc_asprintf((*subkey)->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", (*subkey)->name); + (*subkey)->path = talloc_asprintf((*subkey)->mem_ctx, "%s\\%s", reg_key_get_path_abs(key), (*subkey)->name); (*subkey)->handle = key->handle; (*subkey)->hive = key->hive; @@ -334,7 +334,7 @@ WERROR reg_key_get_subkey_by_name(REG_KEY *key, const char *name, REG_KEY **subk if(!W_ERROR_IS_OK(error)) return error; - (*subkey)->path = talloc_asprintf((*subkey)->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", (*subkey)->name); + (*subkey)->path = talloc_asprintf((*subkey)->mem_ctx, "%s\\%s", reg_key_get_path_abs(key), (*subkey)->name); (*subkey)->handle = key->handle; (*subkey)->hive = key->hive; diff --git a/source4/lib/registry/common/reg_objects.c b/source4/lib/registry/common/reg_objects.c index 7a92f413ff..0109a1f8fe 100644 --- a/source4/lib/registry/common/reg_objects.c +++ b/source4/lib/registry/common/reg_objects.c @@ -141,7 +141,7 @@ char *reg_val_get_path(REG_VAL *v) const char *reg_key_get_path(REG_KEY *k) { SMB_REG_ASSERT(k); - return strchr(k->path, '\\')?strchr(k->path, '\\')+1:k->path; + return strchr(k->path, '\\')?strchr(k->path, '\\')+1:""; } const char *reg_key_get_path_abs(REG_KEY *k) diff --git a/source4/lib/registry/common/registry.h b/source4/lib/registry/common/registry.h index d4e8cccade..5325a89086 100644 --- a/source4/lib/registry/common/registry.h +++ b/source4/lib/registry/common/registry.h @@ -31,7 +31,7 @@ struct reg_key_s { char *name; /* Name of the key */ char *path; /* Full path to the key */ - smb_ucs2_t *class_name; /* Name of key class */ + char *class_name; /* Name of key class */ NTTIME last_mod; /* Time last modified */ SEC_DESC *security; REG_HANDLE *handle; diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index 255389624e..a28f1880db 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -1085,12 +1085,15 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent if (clsname_len) { /* Just print in Ascii for now */ smb_ucs2_t *clsnamep; int clsnam_off; + char *clsnameu; clsnam_off = IVAL(&nk_hdr->clsnam_off,0); clsnamep = (smb_ucs2_t *)LOCN(regf->base, clsnam_off); DEBUG(2, ("Class Name Offset: %0X\n", clsnam_off)); - tmp->class_name = talloc_strdup_w(h->mem_ctx, clsnamep); + clsnameu = acnv_u2ux(clsnamep); + tmp->class_name = talloc_strdup(tmp->mem_ctx, clsnameu); + SAFE_FREE(clsnameu); DEBUGADD(2,(" Class Name: %s\n", cls_name)); diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 26312ad4bc..dbddaa5dcf 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -32,6 +32,12 @@ * exit */ +static REG_KEY *cmd_pwd(REG_KEY *cur, int argc, char **argv) +{ + printf("%s\n", reg_key_get_path_abs(cur)); + return cur; +} + static REG_KEY *cmd_set(REG_KEY *cur, int argc, char **argv) { /* FIXME */ @@ -52,7 +58,7 @@ static REG_KEY *cmd_ck(REG_KEY *cur, int argc, char **argv) } } - printf("Current path is: %s\n", reg_key_get_path(new)); + printf("Current path is: %s\n", reg_key_get_path_abs(new)); return new; } @@ -68,7 +74,7 @@ static REG_KEY *cmd_ls(REG_KEY *cur, int argc, char **argv) } if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while browsing thru keys\n")); + DEBUG(0, ("Error occured while browsing thru keys: %s\n", win_errstr(error))); } for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(cur, i, &value)); i++) { @@ -90,7 +96,7 @@ static REG_KEY *cmd_mkkey(REG_KEY *cur, int argc, char **argv) return NULL; } - fprintf(stderr, "Successfully added new subkey '%s' to '%s'\n", argv[1], reg_key_get_path(cur)); + fprintf(stderr, "Successfully added new subkey '%s' to '%s'\n", argv[1], reg_key_get_path_abs(cur)); return NULL; } @@ -139,6 +145,11 @@ static REG_KEY *cmd_rmval(REG_KEY *cur, int argc, char **argv) return NULL; } +static REG_KEY *cmd_hive(REG_KEY *cur, int argc, char **argv) +{ + /* FIXME */ +} + static REG_KEY *cmd_exit(REG_KEY *cur, int argc, char **argv) { exit(0); @@ -154,10 +165,12 @@ struct { REG_KEY *(*handle)(REG_KEY *, int argc, char **argv); } regshell_cmds[] = { {"ck", "cd", "Change current key", cmd_ck }, + {"ch", "hive", "Change current hive", cmd_hive }, {"list", "ls", "List values/keys in current key", cmd_ls }, {"mkkey", "mkdir", "Make new key", cmd_mkkey }, {"rmval", "rm", "Remove value", cmd_rmval }, {"rmkey", "rmdir", "Remove key", cmd_rmkey }, + {"pwd", "pwk", "Printing current key", cmd_pwd }, {"set", "update", "Update value", cmd_set }, {"help", "?", "Help", cmd_help }, {"exit", "quit", "Exit", cmd_exit }, @@ -235,7 +248,7 @@ static REG_KEY *process_cmd(REG_KEY *k, char *line) while(True) { char *line, *prompt; - asprintf(&prompt, "%s> ", reg_key_get_path(curkey)); + asprintf(&prompt, "%s> ", reg_key_get_path_abs(curkey)); line = smb_readline(prompt, NULL, NULL); diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index e583194a56..b1ca9b3fb2 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -29,7 +29,7 @@ static void print_tree(int l, REG_KEY *p, int fullpath, int novals) int i; for(i = 0; i < l; i++) putchar(' '); - if(fullpath) printf("%s\n", reg_key_get_path(p)); + if(fullpath) printf("%s\n", reg_key_get_path_abs(p)); else printf("%s\n", reg_key_name(p)); for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(p, i, &subkey)); i++) { @@ -38,7 +38,7 @@ static void print_tree(int l, REG_KEY *p, int fullpath, int novals) } if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while fetching subkeys for '%s': %s\n", reg_key_get_path(p), win_errstr(error))); + DEBUG(0, ("Error occured while fetching subkeys for '%s': %s\n", reg_key_get_path_abs(p), win_errstr(error))); } if(!novals) { @@ -53,7 +53,7 @@ static void print_tree(int l, REG_KEY *p, int fullpath, int novals) } if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while fetching values for '%s': %s\n", reg_key_get_path(p), win_errstr(error))); + DEBUG(0, ("Error occured while fetching values for '%s': %s\n", reg_key_get_path_abs(p), win_errstr(error))); } } } -- cgit From 4a137a7cf154955db5d1b1bb67017575a428d737 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 May 2004 12:12:50 +0000 Subject: r829: Implement 'hive' command (This used to be commit 2a87981bd0a79f0d685441d690e2f810d6ed86d0) --- source4/lib/registry/common/reg_objects.c | 5 +++++ source4/lib/registry/tools/regshell.c | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_objects.c b/source4/lib/registry/common/reg_objects.c index 0109a1f8fe..168ee946e8 100644 --- a/source4/lib/registry/common/reg_objects.c +++ b/source4/lib/registry/common/reg_objects.c @@ -93,6 +93,11 @@ uint32 reg_val_type( REG_VAL *val ) /********************************************************************** *********************************************************************/ +REG_HANDLE *reg_key_handle (REG_KEY *key) +{ + return key->handle; +} + char *reg_key_name( REG_KEY *key ) { return key->name; diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index dbddaa5dcf..b843e91120 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -147,7 +147,21 @@ static REG_KEY *cmd_rmval(REG_KEY *cur, int argc, char **argv) static REG_KEY *cmd_hive(REG_KEY *cur, int argc, char **argv) { - /* FIXME */ + int i; + WERROR error = WERR_OK; + for(i = 0; W_ERROR_IS_OK(error); i++) { + REG_KEY *hive; + error = reg_get_hive(reg_key_handle(cur), i, &hive); + if(!W_ERROR_IS_OK(error)) break; + + if(argc == 1) { + printf("%s\n", reg_key_name(hive)); + } else if(!strcmp(reg_key_name(hive), argv[1])) { + return hive; + } + reg_key_free(hive); + } + return NULL; } static REG_KEY *cmd_exit(REG_KEY *cur, int argc, char **argv) -- cgit From a64be8dbdd9e3e2aecb696b38925cc8f15a91f36 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 May 2004 12:37:55 +0000 Subject: r830: Use pull_ucs2_talloc() instead of acnv_u2ux() and fix a memory leak. (This used to be commit ad88561becf59cd38a3e329e68cbe5518a3373d7) --- source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index a28f1880db..e4f9447488 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -919,7 +919,7 @@ static WERROR vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size, REG_VAL **val if (dat_len&0x7FFFFFFF) { - char *dtmp = (char *)malloc(dat_len&0x7FFFFFFF); + char *dtmp = (char *)talloc(tmp->mem_ctx, dat_len&0x7FFFFFFF); tmp->data_blk = dtmp; @@ -1085,15 +1085,12 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent if (clsname_len) { /* Just print in Ascii for now */ smb_ucs2_t *clsnamep; int clsnam_off; - char *clsnameu; clsnam_off = IVAL(&nk_hdr->clsnam_off,0); clsnamep = (smb_ucs2_t *)LOCN(regf->base, clsnam_off); DEBUG(2, ("Class Name Offset: %0X\n", clsnam_off)); - clsnameu = acnv_u2ux(clsnamep); - tmp->class_name = talloc_strdup(tmp->mem_ctx, clsnameu); - SAFE_FREE(clsnameu); + pull_ucs2_talloc(tmp->mem_ctx, &tmp->class_name, clsnamep); DEBUGADD(2,(" Class Name: %s\n", cls_name)); -- cgit From b4c23f5a52ca5f3fa93e42f95efc74f5d6b47d50 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 May 2004 13:50:56 +0000 Subject: r832: Only show menu items for backends if they're present (This used to be commit 9228aeeafd956a2885b5f1dfaa6feacb555b7483) --- source4/lib/registry/common/reg_interface.c | 31 +++++++++++++++++----------- source4/lib/registry/tools/gregedit.c | 32 ++++++++++++++++++----------- 2 files changed, 39 insertions(+), 24 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index e748c836cf..93e5b60984 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -58,7 +58,19 @@ NTSTATUS registry_register(void *_function) /* Find a backend in the list of available backends */ static struct reg_init_function_entry *reg_find_backend_entry(const char *name) { - struct reg_init_function_entry *entry = backends; + struct reg_init_function_entry *entry; + static BOOL reg_first_init = True; + + if(reg_first_init) { + status = register_subsystem("registry", registry_register); + if (!NT_STATUS_IS_OK(status)) + return WERR_GENERAL_FAILURE; + + static_init_registry; + reg_first_init = False; + } + + entry = backends; while(entry) { if (strcmp(entry->functions->name, name)==0) return entry; @@ -68,25 +80,20 @@ static struct reg_init_function_entry *reg_find_backend_entry(const char *name) return NULL; } +BOOL reg_has_backend(const char *backend) +{ + return reg_find_backend_entry(backend)?True:False; +} + /* Open a registry file/host/etc */ WERROR reg_open(const char *backend, const char *location, const char *credentials, REG_HANDLE **h) { struct reg_init_function_entry *entry; - static BOOL reg_first_init = True; TALLOC_CTX *mem_ctx; REG_HANDLE *ret; NTSTATUS status; WERROR werr; - - if(reg_first_init) { - status = register_subsystem("registry", registry_register); - if (!NT_STATUS_IS_OK(status)) - return WERR_GENERAL_FAILURE; - - static_init_registry; - reg_first_init = False; - } - + entry = reg_find_backend_entry(backend); if (!entry) { diff --git a/source4/lib/registry/tools/gregedit.c b/source4/lib/registry/tools/gregedit.c index e8800c6ee9..5b78292061 100644 --- a/source4/lib/registry/tools/gregedit.c +++ b/source4/lib/registry/tools/gregedit.c @@ -450,21 +450,29 @@ static GtkWidget* create_mainwin (void) menu_file_menu = gtk_menu_new (); gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_file), menu_file_menu); - open_nt4 = gtk_image_menu_item_new_with_mnemonic("_Open NT4 file"); - gtk_widget_show (open_nt4); - gtk_container_add (GTK_CONTAINER (menu_file_menu), open_nt4); + if(reg_has_backend("nt4")) { + open_nt4 = gtk_image_menu_item_new_with_mnemonic("_Open NT4 file"); + gtk_widget_show (open_nt4); + gtk_container_add (GTK_CONTAINER (menu_file_menu), open_nt4); + } - open_w95 = gtk_image_menu_item_new_with_mnemonic("_Open Win9x file"); - gtk_widget_show (open_w95); - gtk_container_add (GTK_CONTAINER (menu_file_menu), open_w95); + if(reg_has_backend("w95")) { + open_w95 = gtk_image_menu_item_new_with_mnemonic("_Open Win9x file"); + gtk_widget_show (open_w95); + gtk_container_add (GTK_CONTAINER (menu_file_menu), open_w95); + } - open_gconf = gtk_image_menu_item_new_with_mnemonic ("_Open GConf"); - gtk_widget_show (open_gconf); - gtk_container_add (GTK_CONTAINER (menu_file_menu), open_gconf); + if(reg_has_backend("gconf")) { + open_gconf = gtk_image_menu_item_new_with_mnemonic ("_Open GConf"); + gtk_widget_show (open_gconf); + gtk_container_add (GTK_CONTAINER (menu_file_menu), open_gconf); + } - open_remote = gtk_menu_item_new_with_mnemonic ("_Open Remote"); - gtk_widget_show (open_remote); - gtk_container_add (GTK_CONTAINER (menu_file_menu), open_remote); + if(reg_has_backend("rpc")) { + open_remote = gtk_menu_item_new_with_mnemonic ("_Open Remote"); + gtk_widget_show (open_remote); + gtk_container_add (GTK_CONTAINER (menu_file_menu), open_remote); + } save = gtk_image_menu_item_new_from_stock ("gtk-save", accel_group); gtk_widget_show (save); -- cgit From f0d7ae39c00627ebc1e43927ae5df42762e73d95 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 May 2004 13:55:52 +0000 Subject: r833: Compile error (This used to be commit e4f6ca85223b86beac237398ea5474f4f56404a2) --- source4/lib/registry/common/reg_interface.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 93e5b60984..6acedb3591 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -60,11 +60,12 @@ static struct reg_init_function_entry *reg_find_backend_entry(const char *name) { struct reg_init_function_entry *entry; static BOOL reg_first_init = True; + NTSTATUS status; if(reg_first_init) { status = register_subsystem("registry", registry_register); if (!NT_STATUS_IS_OK(status)) - return WERR_GENERAL_FAILURE; + return NULL; static_init_registry; reg_first_init = False; -- cgit From 25ed82e7ee84a069661c3dd8b0f808049ee7fa88 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 May 2004 14:18:08 +0000 Subject: r834: Fix gconf and dir backends (This used to be commit fe5166ee88d401cdd493644af4876e803f546aef) --- .../lib/registry/reg_backend_dir/reg_backend_dir.c | 9 +++++++ .../registry/reg_backend_gconf/reg_backend_gconf.c | 17 +++++++++++-- source4/lib/registry/tools/gregedit.c | 28 ++++++++++++---------- 3 files changed, 40 insertions(+), 14 deletions(-) (limited to 'source4/lib/registry') 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 cb61864d0c..c7ed95d80f 100644 --- a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c @@ -127,6 +127,14 @@ static WERROR reg_dir_add_value(REG_KEY *p, const char *name, int type, void *da return WERR_NOT_SUPPORTED; } +static WERROR reg_dir_get_hive(REG_HANDLE *h, int hive, REG_KEY **key) +{ + if(hive != 0) return WERR_NO_MORE_ITEMS; + *key = reg_key_new_abs("", h, NULL); + (*key)->backend_data = talloc_strdup((*key)->mem_ctx, h->location); + return WERR_OK; +} + static WERROR reg_dir_del_value(REG_VAL *v) { /* FIXME*/ @@ -137,6 +145,7 @@ static struct registry_ops reg_backend_dir = { .name = "dir", .open_registry = reg_dir_open, .open_key = reg_dir_open_key, + .get_hive = reg_dir_get_hive, .fetch_subkeys = reg_dir_fetch_subkeys, .add_key = reg_dir_add_key, .del_key = reg_dir_del_key, diff --git a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c index 8f9fd6625b..c705a2e3cb 100644 --- a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c +++ b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c @@ -41,10 +41,22 @@ static WERROR reg_close_gconf(REG_HANDLE *h) return WERR_OK; } -static WERROR gconf_open_key (REG_HANDLE *h, const char *name, REG_KEY **key) +static WERROR gconf_get_hive (REG_HANDLE *h, int hivenum, REG_KEY **key) +{ + if(hivenum != 0) return WERR_NO_MORE_ITEMS; + *key = reg_key_new_abs("", h, NULL); + (*key)->backend_data = talloc_strdup((*key)->mem_ctx, "/"); + return WERR_OK; +} + +static WERROR gconf_open_key (REG_HANDLE *h, int hivenum, const char *name, REG_KEY **key) { REG_KEY *ret; - char *fullpath = reg_path_win2unix(strdup(name)); + char *fullpath; + + if(hivenum != 0) return WERR_NO_MORE_ITEMS; + + fullpath = reg_path_win2unix(strdup(name)); /* Check if key exists */ if(!gconf_client_dir_exists((GConfClient *)h->backend_data, fullpath, NULL)) { @@ -183,6 +195,7 @@ static struct registry_ops reg_backend_gconf = { .name = "gconf", .open_registry = reg_open_gconf, .close_registry = reg_close_gconf, + .get_hive = gconf_get_hive, .open_key = gconf_open_key, .fetch_subkeys = gconf_fetch_subkeys, .fetch_values = gconf_fetch_values, diff --git a/source4/lib/registry/tools/gregedit.c b/source4/lib/registry/tools/gregedit.c index 5b78292061..d878461bff 100644 --- a/source4/lib/registry/tools/gregedit.c +++ b/source4/lib/registry/tools/gregedit.c @@ -454,24 +454,40 @@ static GtkWidget* create_mainwin (void) open_nt4 = gtk_image_menu_item_new_with_mnemonic("_Open NT4 file"); gtk_widget_show (open_nt4); gtk_container_add (GTK_CONTAINER (menu_file_menu), open_nt4); + + g_signal_connect ((gpointer) open_nt4, "activate", + G_CALLBACK (on_open_file_activate), + "nt4"); } if(reg_has_backend("w95")) { open_w95 = gtk_image_menu_item_new_with_mnemonic("_Open Win9x file"); gtk_widget_show (open_w95); gtk_container_add (GTK_CONTAINER (menu_file_menu), open_w95); + + g_signal_connect ((gpointer) open_w95, "activate", + G_CALLBACK (on_open_file_activate), + "w95"); } if(reg_has_backend("gconf")) { open_gconf = gtk_image_menu_item_new_with_mnemonic ("_Open GConf"); gtk_widget_show (open_gconf); gtk_container_add (GTK_CONTAINER (menu_file_menu), open_gconf); + + g_signal_connect ((gpointer) open_gconf, "activate", + G_CALLBACK (on_open_gconf_activate), + NULL); } if(reg_has_backend("rpc")) { open_remote = gtk_menu_item_new_with_mnemonic ("_Open Remote"); gtk_widget_show (open_remote); gtk_container_add (GTK_CONTAINER (menu_file_menu), open_remote); + + g_signal_connect ((gpointer) open_remote, "activate", + G_CALLBACK (on_open_remote_activate), + NULL); } save = gtk_image_menu_item_new_from_stock ("gtk-save", accel_group); @@ -605,18 +621,6 @@ static GtkWidget* create_mainwin (void) gtk_box_pack_start (GTK_BOX (vbox1), statusbar, FALSE, FALSE, 0); gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (statusbar), FALSE); - g_signal_connect ((gpointer) open_nt4, "activate", - G_CALLBACK (on_open_file_activate), - "nt4"); - g_signal_connect ((gpointer) open_w95, "activate", - G_CALLBACK (on_open_file_activate), - "w95"); - g_signal_connect ((gpointer) open_gconf, "activate", - G_CALLBACK (on_open_gconf_activate), - NULL); - g_signal_connect ((gpointer) open_remote, "activate", - G_CALLBACK (on_open_remote_activate), - NULL); g_signal_connect ((gpointer) save, "activate", G_CALLBACK (on_save_activate), NULL); -- cgit From d17ca56aed836b5cf0725e7c74f34ecbf5dcdab3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 24 May 2004 17:18:00 +0000 Subject: r851: convert lib/registry/ to a config.mk file metze (This used to be commit b5567601464a649374e0ef280661292322b3334c) --- source4/lib/registry/config.m4 | 32 +++++----- source4/lib/registry/config.mk | 132 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+), 17 deletions(-) create mode 100644 source4/lib/registry/config.mk (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index 77508063fc..331b9c2df1 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -22,25 +22,23 @@ if test t$SMB_EXT_LIB_ENABLE_gtk = tYES; then SMB_BINARY_ENABLE(gregedit, YES) fi -SMB_MODULE(registry_nt4, REGISTRY, STATIC, lib/registry/reg_backend_nt4/reg_backend_nt4.o) -SMB_MODULE(registry_w95, REGISTRY, STATIC, lib/registry/reg_backend_w95/reg_backend_w95.o) -SMB_MODULE(registry_dir, REGISTRY, STATIC, lib/registry/reg_backend_dir/reg_backend_dir.o) -SMB_MODULE(registry_rpc, REGISTRY, STATIC, lib/registry/reg_backend_rpc/reg_backend_rpc.o,[],[],[LIBSMB]) -SMB_MODULE(registry_gconf, REGISTRY, STATIC, lib/registry/reg_backend_gconf/reg_backend_gconf.o, [], [gconf]) -SMB_MODULE(registry_ldb, REGISTRY, NOT, lib/registry/reg_backend_ldb/reg_backend_ldb.o,[],[],[LIBLDB]) -SMB_SUBSYSTEM(REGISTRY,lib/registry/common/reg_interface.o, - [lib/registry/common/reg_objects.o lib/registry/common/reg_util.o], - [], - [LIBBASIC]) - -SMB_BINARY(regdiff, [REG], [BIN], lib/registry/tools/regdiff.o,[],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) -SMB_BINARY(regpatch, [REG], [BIN], lib/registry/tools/regpatch.o,[],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) -SMB_BINARY(regshell, [REG], [BIN], lib/registry/tools/regshell.o,[],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) -SMB_BINARY(regtree, [REG], [BIN], lib/registry/tools/regtree.o,[],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) -SMB_BINARY(gregedit, [REG], [BIN], lib/registry/tools/gregedit.o,[gtk],[CONFIG LIBBASIC LIBCMDLINE REGISTRY]) +SMB_MODULE_MK(registry_nt4, REGISTRY, STATIC, lib/registry/config.mk) +SMB_MODULE_MK(registry_w95, REGISTRY, STATIC, lib/registry/config.mk) +SMB_MODULE_MK(registry_dir, REGISTRY, STATIC, lib/registry/config.mk) +SMB_MODULE_MK(registry_rpc, REGISTRY, STATIC, lib/registry/config.mk) +SMB_MODULE_MK(registry_gconf, REGISTRY, STATIC, lib/registry/config.mk) +SMB_MODULE_MK(registry_ldb, REGISTRY, NOT, lib/registry/config.mk) + +SMB_SUBSYSTEM_MK(REGISTRY,lib/registry/config.mk) + +SMB_BINARY_MK(regdiff, lib/registry/config.mk) +SMB_BINARY_MK(regpatch, lib/registry/config.mk) +SMB_BINARY_MK(regshell, lib/registry/config.mk) +SMB_BINARY_MK(regtree, lib/registry/config.mk) +SMB_BINARY_MK(gregedit, lib/registry/config.mk) if test x"$experimental" = x"yes"; then SMB_LIBRARY_ENABLE(libwinregistry, YES) fi -SMB_LIBRARY(libwinregistry, 0, 0, 1, , , REGISTRY) +SMB_LIBRARY_MK(libwinregistry, lib/registry/config.mk) diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk new file mode 100644 index 0000000000..fff5381e87 --- /dev/null +++ b/source4/lib/registry/config.mk @@ -0,0 +1,132 @@ +# Registry backends + +################################################ +# Start MODULE registry_nt4 +[MODULE::registry_nt4] +INIT_OBJ_FILES = \ + lib/registry/reg_backend_nt4/reg_backend_nt4.o +# End MODULE registry_nt4 +################################################ + +################################################ +# Start MODULE registry_w95 +[MODULE::registry_w95] +INIT_OBJ_FILES = \ + lib/registry/reg_backend_w95/reg_backend_w95.o +# End MODULE registry_w95 +################################################ + +################################################ +# Start MODULE registry_dir +[MODULE::registry_dir] +INIT_OBJ_FILES = \ + lib/registry/reg_backend_dir/reg_backend_dir.o +# End MODULE registry_dir +################################################ + +################################################ +# Start MODULE registry_rpc +[MODULE::registry_rpc] +INIT_OBJ_FILES = \ + lib/registry/reg_backend_rpc/reg_backend_rpc.o +REQUIRED_SUBSYSTEMS = \ + LIBSMB +# End MODULE registry_rpc +################################################ + +################################################ +# Start MODULE registry_gconf +[MODULE::registry_gconf] +INIT_OBJ_FILES = \ + lib/registry/reg_backend_gconf/reg_backend_gconf.o +REQUIRED_LIBRARIES = \ + gconf +# End MODULE registry_gconf +################################################ + +################################################ +# Start MODULE registry_ldb +[MODULE::registry_ldb] +INIT_OBJ_FILES = \ + lib/registry/reg_backend_ldb/reg_backend_ldb.o +REQUIRED_SUBSYSTEMS = \ + LIBLDB +# End MODULE registry_ldb +################################################ + +################################################ +# Start SUBSYSTEM REGISTRY +[SUBSYSTEM::REGISTRY] +INIT_OBJ_FILES = \ + lib/registry/common/reg_interface.o +ADD_OBJ_FILES = \ + lib/registry/common/reg_objects.o \ + lib/registry/common/reg_util.o +REQUIRED_SUBSYSTEMS = \ + LIBBASIC +# End MODULE registry_ldb +################################################ + +################################################ +# Start LIBRARY libwinregistry +[LIBRARY::libwinregistry] +MAJOR_VERSION = 0 +MINOR_VERSION = 0 +RELEASE_VERSION = 1 +REQUIRED_SUBSYSTEMS = \ + REGISTRY +# +# End LIBRARY libwinregistry +################################################ + +################################################ +# Start BINARY regdiff +[BINARY::regdiff] +OBJ_FILES= \ + lib/registry/tools/regdiff.o +REQUIRED_SUBSYSTEMS = \ + CONFIG LIBCMDLINE REGISTRY +# End BINARY regdiff +################################################ + +################################################ +# Start BINARY regpatch +[BINARY::regpatch] +OBJ_FILES= \ + lib/registry/tools/regpatch.o +REQUIRED_SUBSYSTEMS = \ + CONFIG LIBCMDLINE REGISTRY +# End BINARY regpatch +################################################ + +################################################ +# Start BINARY regshell +[BINARY::regshell] +OBJ_FILES= \ + lib/registry/tools/regshell.o +REQUIRED_SUBSYSTEMS = \ + CONFIG LIBCMDLINE REGISTRY +# End BINARY regshell +################################################ + +################################################ +# Start BINARY regtree +[BINARY::regtree] +OBJ_FILES= \ + lib/registry/tools/regtree.o +REQUIRED_SUBSYSTEMS = \ + CONFIG LIBCMDLINE REGISTRY +# End BINARY regtree +################################################ + +################################################ +# Start BINARY gregedit +[BINARY::grepedit] +OBJ_FILES= \ + lib/registry/tools/gregedit.o +REQUIRED_LIBRARIES = \ + gtk +REQUIRED_SUBSYSTEMS = \ + CONFIG LIBCMDLINE REGISTRY +# End BINARY gregedit +################################################ -- cgit From 69e40486f98e49cb9fbfd7d4816c8074ed3f786a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 24 May 2004 18:13:24 +0000 Subject: r857: fix the build of gregedit (typo:-) metze (This used to be commit 44de741038ccdbca1e3c950670748e99483a7417) --- source4/lib/registry/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index fff5381e87..1d2a1fec6d 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -121,7 +121,7 @@ REQUIRED_SUBSYSTEMS = \ ################################################ # Start BINARY gregedit -[BINARY::grepedit] +[BINARY::gregedit] OBJ_FILES= \ lib/registry/tools/gregedit.o REQUIRED_LIBRARIES = \ -- cgit From 579c13da43d5b40ac6d6c1436399fbc1d8dfd054 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 25 May 2004 13:57:39 +0000 Subject: r873: converted samba4 to use real 64 bit integers instead of structures. This was suggested by metze recently. I checked on the build farm and all the machines we have support 64 bit ints, and support the LL suffix for 64 bit constants. I suspect some won't support strtoll() and related functions, so we will probably need replacements for those. (This used to be commit 9a9244a1c66654c12abe4379661cba83a73c4c21) --- source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index e4f9447488..415f764f61 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -608,8 +608,7 @@ static KEY_SEC_DESC *nt_create_init_sec(REG_HANDLE *h) #define REG_HANDLE_REGTYPE_NT 1 #define REG_HANDLE_REGTYPE_W9X 2 -#define TTTONTTIME(r, t1, t2) (r)->last_mod_time.low = (t1); \ - (r)->last_mod_time.high = (t2); +#define TTTONTTIME(r, t1, t2) (r)->last_mod_time = (t1) | (((uint64_t)(t2)) << 32) #define REGF_HDR_BLKSIZ 0x1000 -- cgit From f9d8f8843dc0ab8c9d59abde7222e0f118b86b5d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 25 May 2004 16:24:13 +0000 Subject: r884: convert samba4 to use [u]int32_t instead of [u]int32 metze (This used to be commit 0e5517d937a2eb7cf707991d1c7498c1ab456095) --- source4/lib/registry/common/reg_interface.c | 2 +- source4/lib/registry/common/reg_objects.c | 2 +- source4/lib/registry/common/reg_util.c | 2 +- source4/lib/registry/common/registry.h | 2 +- source4/lib/registry/reg_backend_dir/reg_backend_dir.c | 2 +- source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c | 2 +- source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 6acedb3591..6d305e61bf 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -508,7 +508,7 @@ WERROR reg_key_add_name_recursive(REG_KEY *parent, const char *path) return WERR_OK; } -WERROR reg_key_add_name(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *desc, REG_KEY **newkey) +WERROR reg_key_add_name(REG_KEY *parent, const char *name, uint32_t access_mask, SEC_DESC *desc, REG_KEY **newkey) { WERROR error; diff --git a/source4/lib/registry/common/reg_objects.c b/source4/lib/registry/common/reg_objects.c index 168ee946e8..be15108f4d 100644 --- a/source4/lib/registry/common/reg_objects.c +++ b/source4/lib/registry/common/reg_objects.c @@ -85,7 +85,7 @@ char *reg_val_name( REG_VAL *val ) /********************************************************************** *********************************************************************/ -uint32 reg_val_type( REG_VAL *val ) +uint32_t reg_val_type( REG_VAL *val ) { return val->data_type; } diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index 82b8d06679..353963f78d 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -105,7 +105,7 @@ WERROR reg_key_get_subkey_val(REG_KEY *key, const char *subname, const char *val return reg_key_get_value_by_name(k, valname, val); } -WERROR reg_key_set_subkey_val(REG_KEY *key, const char *subname, const char *valname, uint32 type, uint8 *data, int real_len) +WERROR reg_key_set_subkey_val(REG_KEY *key, const char *subname, const char *valname, uint32_t type, uint8 *data, int real_len) { REG_KEY *k; REG_VAL *v; diff --git a/source4/lib/registry/common/registry.h b/source4/lib/registry/common/registry.h index 5325a89086..caa0e284bf 100644 --- a/source4/lib/registry/common/registry.h +++ b/source4/lib/registry/common/registry.h @@ -107,7 +107,7 @@ struct registry_ops { WERROR (*request_value_change_notify) (REG_VAL *, value_notification_function); /* Key management */ - WERROR (*add_key)(REG_KEY *, const char *name, uint32 access_mask, SEC_DESC *, REG_KEY **); + WERROR (*add_key)(REG_KEY *, const char *name, uint32_t access_mask, SEC_DESC *, REG_KEY **); WERROR (*del_key)(REG_KEY *); /* Value management */ 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 c7ed95d80f..cac54f8437 100644 --- a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c @@ -21,7 +21,7 @@ #include "includes.h" #include "lib/registry/common/registry.h" -static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *desc, REG_KEY **result) +static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32_t access_mask, SEC_DESC *desc, REG_KEY **result) { char *path; int ret; diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index 415f764f61..627b5a8f13 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -501,7 +501,7 @@ static DWORD str_to_dword(const char *a) { /* * Create an ACE */ -static BOOL nt_create_ace(SEC_ACE *ace, int type, int flags, uint32 perms, const char *sid) +static BOOL nt_create_ace(SEC_ACE *ace, int type, int flags, uint32_t perms, const char *sid) { DOM_SID s; SEC_ACCESS access; 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 d863568c17..28e2094bed 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -197,7 +197,7 @@ static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value) struct winreg_EnumValueName vn; NTSTATUS status; struct rpc_key_data *mykeydata; - uint32 type = 0x0, requested_len = 0, returned_len = 0; + uint32_t type = 0x0, requested_len = 0, returned_len = 0; WERROR error; error = rpc_key_put_rpc_data(parent, &mykeydata); @@ -283,7 +283,7 @@ static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey) return r.out.result; } -static WERROR rpc_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *sec, REG_KEY **key) +static WERROR rpc_add_key(REG_KEY *parent, const char *name, uint32_t access_mask, SEC_DESC *sec, REG_KEY **key) { struct rpc_key_data *mykeydata; WERROR error; -- cgit From fcd718c7d8a6850ae8719f23ed044b06b57501cd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 25 May 2004 17:50:17 +0000 Subject: r890: convert samba4 to use [u]int8_t instead of [u]int8 metze (This used to be commit 2986c5f08c8f0c26a2ea7b6ce20aae025183109f) --- source4/lib/registry/common/reg_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index 353963f78d..01d75f1b90 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -105,7 +105,7 @@ WERROR reg_key_get_subkey_val(REG_KEY *key, const char *subname, const char *val return reg_key_get_value_by_name(k, valname, val); } -WERROR reg_key_set_subkey_val(REG_KEY *key, const char *subname, const char *valname, uint32_t type, uint8 *data, int real_len) +WERROR reg_key_set_subkey_val(REG_KEY *key, const char *subname, const char *valname, uint32_t type, uint8_t *data, int real_len) { REG_KEY *k; REG_VAL *v; -- cgit From 47864891ffd6309764fdc3a5227ec2e83c6f7107 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 26 May 2004 01:13:12 +0000 Subject: r893: a few more _t conversions (This used to be commit 66eb46dbb1486c5916194bf6b303cf16373a272a) --- source4/lib/registry/common/reg_objects.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_objects.c b/source4/lib/registry/common/reg_objects.c index be15108f4d..d042c74e47 100644 --- a/source4/lib/registry/common/reg_objects.c +++ b/source4/lib/registry/common/reg_objects.c @@ -61,7 +61,7 @@ void reg_val_free( REG_VAL *val ) /********************************************************************** *********************************************************************/ -uint8* reg_val_data_blk( REG_VAL *val ) +uint8_t * reg_val_data_blk( REG_VAL *val ) { return val->data_blk; } -- cgit From 45e93c19ef95978f908f5b14962770510634cd3b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 29 May 2004 08:11:46 +0000 Subject: r943: change samba4 to use 'uint8_t' instead of 'unsigned char' metze (This used to be commit b5378803fdcb3b3afe7c2932a38828e83470f61a) --- source4/lib/registry/common/reg_util.c | 2 +- source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c | 16 ++++++++-------- source4/lib/registry/tools/regpatch.c | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index 01d75f1b90..db5e97bf7f 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -55,7 +55,7 @@ char *reg_val_data_string(REG_VAL *v) asciip = ret; for (i=0; i 0) *asciip = ' '; asciip++; } diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index 627b5a8f13..fa4b3e4d18 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -1268,10 +1268,10 @@ static void *nt_alloc_regf_space(REG_HANDLE *h, int size, unsigned int *off) /* * Store a SID at the location provided */ -static int nt_store_SID(REG_HANDLE *regf, DOM_SID *sid, unsigned char *locn) +static int nt_store_SID(REG_HANDLE *regf, DOM_SID *sid, uint8_t *locn) { int i; - unsigned char *p = locn; + uint8_t *p = locn; if (!regf || !sid || !locn) return 0; @@ -1290,11 +1290,11 @@ static int nt_store_SID(REG_HANDLE *regf, DOM_SID *sid, unsigned char *locn) } -static int nt_store_ace(REG_HANDLE *regf, SEC_ACE *ace, unsigned char *locn) +static int nt_store_ace(REG_HANDLE *regf, SEC_ACE *ace, uint8_t *locn) { int size = 0; SEC_ACE *reg_ace = (SEC_ACE *)locn; - unsigned char *p; + uint8_t *p; if (!regf || !ace || !locn) return 0; @@ -1303,7 +1303,7 @@ static int nt_store_ace(REG_HANDLE *regf, SEC_ACE *ace, unsigned char *locn) /* Deal with the length when we have stored the SID */ - p = (unsigned char *)®_ace->info.mask; + p = (uint8_t *)®_ace->info.mask; SIVAL(p, 0, ace->info.mask); p += 4; @@ -1311,7 +1311,7 @@ static int nt_store_ace(REG_HANDLE *regf, SEC_ACE *ace, unsigned char *locn) size += 8; /* Size of the fixed header */ - p = (unsigned char *)®_ace->size; + p = (uint8_t *)®_ace->size; SSVAL(p, 0, size); @@ -1321,9 +1321,9 @@ static int nt_store_ace(REG_HANDLE *regf, SEC_ACE *ace, unsigned char *locn) /* * Store an ACL at the location provided */ -static int nt_store_acl(REG_HANDLE *regf, SEC_ACL *acl, unsigned char *locn) { +static int nt_store_acl(REG_HANDLE *regf, SEC_ACL *acl, uint8_t *locn) { int size = 0, i; - unsigned char *p = locn, *s; + uint8_t *p = locn, *s; if (!regf || !acl || !locn) return 0; diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 77c0f710c1..af869d1cfa 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -155,7 +155,7 @@ static struct cmd_line *get_cmd_line(int fd) { struct cmd_line *cl = (CMD_LINE *)smb_xmalloc(sizeof(CMD_LINE)); int i = 0, rc; - unsigned char ch; + uint8_t ch; cl->len = INIT_ALLOC; @@ -662,7 +662,7 @@ static CMD_FILE *cmd_file_create(const char *file) * Sec Desc print functions */ -char *str_type(unsigned char type); +char *str_type(uint8_t type); static int nt_apply_reg_command_file(REG_HANDLE *r, const char *cmd_file_name) { -- cgit From 9fba08b621432861b52d5af0b7d994ba0e0100f0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 31 May 2004 17:14:27 +0000 Subject: r955: Update debian package rules... builds now (This used to be commit 3df8ff6cf111c6601554bffb411506bd43f726c7) --- source4/lib/registry/TODO | 3 +++ source4/lib/registry/common/reg_interface.c | 8 ++++++-- source4/lib/registry/config.m4 | 2 +- source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c | 8 ++++++-- 4 files changed, 16 insertions(+), 5 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/TODO b/source4/lib/registry/TODO index 9b0dbe4c71..695f786b69 100644 --- a/source4/lib/registry/TODO +++ b/source4/lib/registry/TODO @@ -24,6 +24,9 @@ reg_backend_wine.c: regshell: - support for security descriptors + + regdiff: + - fix gregedit.c: - support for editing values / adding values / deleting values diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 6d305e61bf..6ad7ee69cb 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -64,8 +64,12 @@ static struct reg_init_function_entry *reg_find_backend_entry(const char *name) if(reg_first_init) { status = register_subsystem("registry", registry_register); - if (!NT_STATUS_IS_OK(status)) + if (NT_STATUS_IS_ERR(status)) { + DEBUG(0, ("Error registering registry subsystem: %s\n", nt_errstr(status))); + /* Don't try the initialisation again */ + reg_first_init = False; return NULL; + } static_init_registry; reg_first_init = False; @@ -83,7 +87,7 @@ static struct reg_init_function_entry *reg_find_backend_entry(const char *name) BOOL reg_has_backend(const char *backend) { - return reg_find_backend_entry(backend)?True:False; + return reg_find_backend_entry(backend) != NULL?True:False; } /* Open a registry file/host/etc */ diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index 331b9c2df1..a1dc9a45bc 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -27,7 +27,7 @@ SMB_MODULE_MK(registry_w95, REGISTRY, STATIC, lib/registry/config.mk) SMB_MODULE_MK(registry_dir, REGISTRY, STATIC, lib/registry/config.mk) SMB_MODULE_MK(registry_rpc, REGISTRY, STATIC, lib/registry/config.mk) SMB_MODULE_MK(registry_gconf, REGISTRY, STATIC, lib/registry/config.mk) -SMB_MODULE_MK(registry_ldb, REGISTRY, NOT, lib/registry/config.mk) +SMB_MODULE_MK(registry_ldb, REGISTRY, STATIC, lib/registry/config.mk) SMB_SUBSYSTEM_MK(REGISTRY,lib/registry/config.mk) diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index 498dc6991b..7b574069e9 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -39,6 +39,7 @@ static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path) } ret[strlen(ret)-1] = ')'; + printf("Doing search for : %s\n", ret); return ret; } @@ -85,9 +86,12 @@ static WERROR ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys) return WERR_OK; } +static WERROR ldb_get_hive(REG_HANDLE *h, int num, REG_KEY **key) +{ + /* FIXME */ +} - -static WERROR ldb_open_key(REG_HANDLE *h, const char *name, REG_KEY **key) +static WERROR ldb_open_key(REG_HANDLE *h, int num, const char *name, REG_KEY **key) { struct ldb_context *c = h->backend_data; char *path; -- cgit From b88fc7a3911e0ff8b6d7d324028e351281e94c46 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Jun 2004 07:23:51 +0000 Subject: r959: - a static WERROR function should return a WERROR:-) - some minor format fixes metze (This used to be commit 72d9c70fdd21101744f6fad230c75b6a13105696) --- source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index 7b574069e9..0633c94616 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. Registry interface - Copyright (C) Jelmer Vernooij 2004. + Copyright (C) Jelmer Vernooij 2004. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -88,7 +88,8 @@ static WERROR ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys) static WERROR ldb_get_hive(REG_HANDLE *h, int num, REG_KEY **key) { - /* FIXME */ + /* FIXME */ + return WERR_FOOBAR; } static WERROR ldb_open_key(REG_HANDLE *h, int num, const char *name, REG_KEY **key) @@ -109,7 +110,7 @@ static WERROR ldb_open_key(REG_HANDLE *h, int num, const char *name, REG_KEY **k ldb_search_free(c, msg); talloc_destroy(mem_ctx); - return WERR_OK;; + return WERR_OK; } static struct registry_ops reg_backend_ldb = { -- cgit From fa2e9ec311b99dee2fbff5ee5fa2c743298dacad Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Jun 2004 08:12:45 +0000 Subject: r960: convert 'unsigned int' to uint_t in the most places metze (This used to be commit 18062d2ed9fc9224c43143c10efbf2f6f1f5bbe0) --- .../lib/registry/reg_backend_nt4/reg_backend_nt4.c | 28 +++++++++++----------- .../lib/registry/reg_backend_w95/reg_backend_w95.c | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index fa4b3e4d18..36feaff907 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -338,7 +338,7 @@ const char *def_owner_sid_str = NULL; #define BLK_SIZE(b) ((int)*(int *)(((int *)b)-1)) -typedef unsigned int DWORD; +typedef uint_t DWORD; typedef unsigned short WORD; typedef struct sk_struct SK_HDR; @@ -358,7 +358,7 @@ typedef struct regf_block { DWORD uk5; /* 0 */ DWORD uk6; /* 1 */ DWORD first_key; /* offset */ - unsigned int dblk_size; + uint_t dblk_size; DWORD uk7[116]; /* 1 */ DWORD chksum; } REGF_HDR; @@ -462,9 +462,9 @@ typedef struct hbin_blk_s { int type, size; struct hbin_blk_s *next; char *data; /* The data block */ - unsigned int file_offset; /* Offset in file */ - unsigned int free_space; /* Amount of free space in block */ - unsigned int fsp_off; /* Start of free space in block */ + uint_t file_offset; /* Offset in file */ + uint_t free_space; /* Amount of free space in block */ + uint_t fsp_off; /* Start of free space in block */ int complete, stored; } HBIN_BLK; @@ -1023,7 +1023,7 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent REGF *regf = h->backend_data; REG_KEY *tmp = NULL, *own; int namlen, clsname_len, sk_off, own_off; - unsigned int nk_id; + uint_t nk_id; SK_HDR *sk_hdr; int type; char key_name[1024], cls_name[1024]; @@ -1104,7 +1104,7 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent DEBUG(2, ("Owner Offset: %0X\n", own_off)); DEBUGADD(2, (" Owner locn: %0X, Our locn: %0X\n", - (unsigned int)own, (unsigned int)nk_hdr)); + (uint_t)own, (uint_t)nk_hdr)); /* * We should verify that the owner field is correct ... @@ -1185,7 +1185,7 @@ static HBIN_BLK *nt_create_hbin_blk(REG_HANDLE *h, int size) * Allocate a unit of space ... and return a pointer as function param * and the block's offset as a side effect */ -static void *nt_alloc_regf_space(REG_HANDLE *h, int size, unsigned int *off) +static void *nt_alloc_regf_space(REG_HANDLE *h, int size, uint_t *off) { REGF *regf = h->backend_data; int tmp = 0; @@ -1357,10 +1357,10 @@ static int nt_store_acl(REG_HANDLE *regf, SEC_ACL *acl, uint8_t *locn) { * that first, then the owner, then the group SID. So, we do it that way * too. */ -static unsigned int nt_store_sec_desc(REG_HANDLE *regf, SEC_DESC *sd, char *locn) +static uint_t nt_store_sec_desc(REG_HANDLE *regf, SEC_DESC *sd, char *locn) { SEC_DESC *rsd = (SEC_DESC *)locn; - unsigned int size = 0, off = 0; + uint_t size = 0, off = 0; if (!regf || !sd || !locn) return 0; @@ -1424,10 +1424,10 @@ static unsigned int nt_store_sec_desc(REG_HANDLE *regf, SEC_DESC *sd, char *locn * If it has already been stored, just get its offset from record * otherwise, store it and record its offset */ -static unsigned int nt_store_security(REG_HANDLE *regf, KEY_SEC_DESC *sec) +static uint_t nt_store_security(REG_HANDLE *regf, KEY_SEC_DESC *sec) { int size = 0; - unsigned int sk_off; + uint_t sk_off; SK_HDR *sk_hdr; if (sec->offset) return sec->offset; @@ -1483,7 +1483,7 @@ static unsigned int nt_store_security(REG_HANDLE *regf, KEY_SEC_DESC *sec) static int nt_store_reg_key(REG_HANDLE *regf, REG_KEY *key) { NK_HDR *nk_hdr; - unsigned int nk_off, sk_off, size; + uint_t nk_off, sk_off, size; if (!regf || !key) return 0; @@ -1581,7 +1581,7 @@ static WERROR nt_open_registry (REG_HANDLE *h, const char *location, const char { REGF *regf; REGF_HDR *regf_hdr; - unsigned int regf_id, hbin_id; + uint_t regf_id, hbin_id; HBIN_HDR *hbin_hdr; regf = (REGF *)talloc_p(h->mem_ctx, REGF); diff --git a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c index b014f4da66..f392759b8d 100644 --- a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c @@ -40,7 +40,7 @@ * the keys and the RGDB contains the actual data. */ -typedef unsigned int DWORD; +typedef uint_t DWORD; typedef unsigned short WORD; typedef struct creg_block { -- cgit From fe3bcd4588f75805a12ff6c11f4f0794f9963463 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Jun 2004 18:45:27 +0000 Subject: r1032: Fix RPC backend segfault (This used to be commit db902bff3c5eb54d6b1035d009948ff316cffa94) --- source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/lib/registry') 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 28e2094bed..4e6944a1e3 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -88,7 +88,6 @@ static WERROR rpc_query_key(REG_KEY *k); static WERROR rpc_open_registry(REG_HANDLE *h, const char *location, const char *credentials) { - char *binding = strdup(location); NTSTATUS status; char *user, *pass; @@ -98,7 +97,7 @@ static WERROR rpc_open_registry(REG_HANDLE *h, const char *location, const char pass = strchr(user, '%'); *pass = '\0'; pass++; - status = dcerpc_pipe_connect((struct dcerpc_pipe **)&h->backend_data, binding, + status = dcerpc_pipe_connect((struct dcerpc_pipe **)&h->backend_data, h->location, DCERPC_WINREG_UUID, DCERPC_WINREG_VERSION, lp_workgroup(), -- cgit From 39e465a0965b7974c95f318db240d47cced37874 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Jun 2004 19:30:13 +0000 Subject: r1035: Support shared modules again (This used to be commit 7949dc25ab05f7d5ad6217a6304e1f50b8b5dc41) --- source4/lib/registry/tools/regdiff.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 7520e653bb..b599a54c2e 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -91,7 +91,7 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) } } - int main(int argc, char **argv) +int main(int argc, char **argv) { int opt; poptContext pc; @@ -115,7 +115,7 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) }; pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); - + while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { case 'c': @@ -123,9 +123,9 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) else if(!credentials2) credentials2 = poptGetOptArg(pc); break; case 'b': - if(!backend1 && !from_null) backend1 = poptGetOptArg(pc); - else if(!backend2) backend2 = poptGetOptArg(pc); - break; + if(!backend1 && !from_null) backend1 = poptGetOptArg(pc); + else if(!backend2) backend2 = poptGetOptArg(pc); + break; } } setup_logging(argv[0], True); @@ -154,13 +154,13 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) } if(!backend2) backend2 = "dir"; - + error = reg_open(backend2, location2, credentials2, &h2); if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location2, backend2); return 1; } - + poptFreeContext(pc); if(outputfile) { @@ -175,24 +175,24 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) fprintf(fd, "; Generated using regdiff\n"); error2 = error = WERR_OK; - + for(i = 0; ; i++) { if(backend1) error = reg_get_hive(h1, i, &root1); else root1 = NULL; if(!W_ERROR_IS_OK(error)) break; - + if(backend2) error2 = reg_get_hive(h2, i, &root2); else root2 = NULL; - + if(!W_ERROR_IS_OK(error2)) break; - + writediff(root1, root2, fd); if(!root1 && !root2) break; } fclose(fd); - + return 0; } -- cgit From 7ea6a0b1fc3e5f35e5096ad820053d54c4496a09 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 6 Jun 2004 07:10:58 +0000 Subject: r1040: make sure main() doesn't get auto-prototyped (This used to be commit 7c2279e4bc631d88e402ac82c6c17fb811785394) --- source4/lib/registry/tools/regdiff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index b599a54c2e..c46411ae31 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -91,7 +91,7 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) } } -int main(int argc, char **argv) + int main(int argc, char **argv) { int opt; poptContext pc; -- cgit From 9503af8d648eb727b954dfe4c09d5764038a245e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 12 Jun 2004 15:12:23 +0000 Subject: r1118: Read-only enumeration of keys in the LDB backend works now :-) (This used to be commit 456f97eed05047b20acceb50708b47209c37ca20) --- source4/lib/registry/common/reg_interface.c | 25 +++-- .../lib/registry/reg_backend_ldb/reg_backend_ldb.c | 106 +++++++++++++++------ 2 files changed, 95 insertions(+), 36 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 6ad7ee69cb..0a0cf05c2e 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -85,6 +85,7 @@ static struct reg_init_function_entry *reg_find_backend_entry(const char *name) return NULL; } +/* Check whether a certain backend is present */ BOOL reg_has_backend(const char *backend) { return reg_find_backend_entry(backend) != NULL?True:False; @@ -129,6 +130,7 @@ WERROR reg_open(const char *backend, const char *location, const char *credentia return werr; } +/* Open a key by name (including the hive name!) */ WERROR reg_open_key_abs(REG_HANDLE *handle, const char *name, REG_KEY **result) { REG_KEY *hive; @@ -195,9 +197,13 @@ WERROR reg_open_key(REG_KEY *parent, const char *name, REG_KEY **result) mem_ctx = talloc_init("mem_ctx"); - fullname = talloc_asprintf(mem_ctx, "%s%s%s", reg_key_get_path(parent), strlen(reg_key_get_path(parent))?"\\":"", name); + fullname = talloc_asprintf(mem_ctx, "%s%s%s", + reg_key_get_path(parent), + strlen(reg_key_get_path(parent))?"\\":"", + name); - error = parent->handle->functions->open_key(parent->handle, parent->hive, fullname, result); + error = parent->handle->functions->open_key(parent->handle, + parent->hive, fullname, result); if(!W_ERROR_IS_OK(error)) { talloc_destroy(mem_ctx); @@ -205,7 +211,8 @@ WERROR reg_open_key(REG_KEY *parent, const char *name, REG_KEY **result) } (*result)->handle = parent->handle; - (*result)->path = talloc_asprintf((*result)->mem_ctx, "%s\\%s", reg_key_get_path_abs(parent), (*result)->name); + (*result)->path = talloc_asprintf((*result)->mem_ctx, "%s\\%s", + reg_key_get_path_abs(parent), (*result)->name); (*result)->hive = parent->hive; talloc_steal(mem_ctx, (*result)->mem_ctx, fullname); @@ -225,7 +232,8 @@ WERROR reg_key_get_value_by_index(REG_KEY *key, int idx, REG_VAL **val) } else if(key->handle->functions->fetch_values) { if(!key->cache_values) - key->handle->functions->fetch_values(key, &key->cache_values_count, &key->cache_values); + key->handle->functions->fetch_values(key, + &key->cache_values_count, &key->cache_values); if(idx < key->cache_values_count && idx >= 0) { *val = reg_val_dup(key->cache_values[idx]); @@ -251,7 +259,8 @@ WERROR reg_key_num_subkeys(REG_KEY *key, int *count) if(key->handle->functions->fetch_subkeys) { if(!key->cache_subkeys) - key->handle->functions->fetch_subkeys(key, &key->cache_subkeys_count, &key->cache_subkeys); + key->handle->functions->fetch_subkeys(key, + &key->cache_subkeys_count, &key->cache_subkeys); *count = key->cache_subkeys_count; return WERR_OK; @@ -304,7 +313,8 @@ WERROR reg_key_get_subkey_by_index(REG_KEY *key, int idx, REG_KEY **subkey) if(!NT_STATUS_IS_OK(status)) return status; } else if(key->handle->functions->fetch_subkeys) { if(!key->cache_subkeys) - key->handle->functions->fetch_subkeys(key, &key->cache_subkeys_count, &key->cache_subkeys); + key->handle->functions->fetch_subkeys(key, + &key->cache_subkeys_count, &key->cache_subkeys); if(idx < key->cache_subkeys_count) { *subkey = reg_key_dup(key->cache_subkeys[idx]); @@ -315,7 +325,8 @@ WERROR reg_key_get_subkey_by_index(REG_KEY *key, int idx, REG_KEY **subkey) return WERR_NOT_SUPPORTED; } - (*subkey)->path = talloc_asprintf((*subkey)->mem_ctx, "%s\\%s", reg_key_get_path_abs(key), (*subkey)->name); + (*subkey)->path = talloc_asprintf((*subkey)->mem_ctx, "%s\\%s", + reg_key_get_path_abs(key), (*subkey)->name); (*subkey)->handle = key->handle; (*subkey)->hive = key->hive; diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index 0633c94616..408ce52e44 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -21,24 +21,37 @@ #include "includes.h" #include "lib/registry/common/registry.h" -static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path) +static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char *add) { - char *ret = talloc_strdup(mem_ctx, "(dn="); - char *begin = (char *)path; - char *end = NULL; - - while(begin) { - end = strchr(begin, '\\'); - if(end)end = '\0'; - if(end - begin != 0) ret = talloc_asprintf_append(mem_ctx, ret, "key=%s,", begin); + char *ret = talloc_strdup(mem_ctx, ""); + char *mypath = strdup(path); + char *end = mypath, *begin; + + if(add) + ret = talloc_asprintf_append(mem_ctx, ret, "%s", add); + + while(end) { + char *keyname; + begin = strrchr(end, '\\'); + + if(begin) keyname = begin + 1; + else keyname = mypath; + + if(strlen(keyname)) + ret = talloc_asprintf_append(mem_ctx, ret, "key=%s,", keyname); - if(end) { - *end = '\\'; - begin = end+1; - } else begin = NULL; + if(begin) { + begin[0] = '\0'; + end = begin-1; + } else { + end = NULL; + } } - ret[strlen(ret)-1] = ')'; + SAFE_FREE(mypath); + + ret[strlen(ret)-1] = '\0'; + printf("Doing search for : %s\n", ret); return ret; } @@ -50,8 +63,12 @@ static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path) static WERROR ldb_open_registry(REG_HANDLE *handle, const char *location, const char *credentials) { struct ldb_context *c; + + if (!location) return WERR_INVALID_PARAM; c = ldb_connect(location, 0, NULL); + ldb_set_debug_stderr(c); + if(!c) return WERR_FOOBAR; handle->backend_data = c; @@ -69,18 +86,36 @@ static WERROR ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys) { struct ldb_context *c = k->handle->backend_data; char *path; + int ret, i, j; struct ldb_message **msg; - char *ldap_path; TALLOC_CTX *mem_ctx = talloc_init("ldb_path"); REG_KEY *key = NULL; - ldap_path = reg_path_to_ldb(mem_ctx, reg_key_get_path(k)); - - if(ldb_search(c, NULL, LDB_SCOPE_ONELEVEL, ldap_path, NULL,&msg) > 0) { - key = reg_key_new_abs(reg_key_get_path(k), k->handle, ldap_path); - talloc_steal(mem_ctx, key->mem_ctx, ldap_path); - /* FIXME */ + + ret = ldb_search(c, (char *)k->backend_data, LDB_SCOPE_ONELEVEL, "(key=*)", NULL,&msg); + + if(ret < 0) { + DEBUG(0, ("Error getting subkeys for '%s': %s\n", k->backend_data, ldb_errstring(c))); + return WERR_FOOBAR; } + *subkeys = talloc_array_p(k->mem_ctx, REG_KEY *, ret); + j = 0; + for(i = 0; i < ret; i++) { + struct ldb_message_element *el; + char *name; + el = ldb_msg_find_element(msg[i], "key"); + + name = el->values[0].data; + + /* Dirty hack to circumvent ldb_tdb bug */ + if(k->backend_data && !strcmp(msg[i]->dn, (char *)k->backend_data)) continue; + + (*subkeys)[j] = reg_key_new_rel(name, k, NULL); + (*subkeys)[j]->backend_data = talloc_strdup((*subkeys)[j]->mem_ctx, msg[i]->dn); + j++; + } + *count = j; + ldb_search_free(c, msg); talloc_destroy(mem_ctx); return WERR_OK; @@ -88,8 +123,10 @@ static WERROR ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys) static WERROR ldb_get_hive(REG_HANDLE *h, int num, REG_KEY **key) { - /* FIXME */ - return WERR_FOOBAR; + if(num != 0) return WERR_NO_MORE_ITEMS; + *key = reg_key_new_abs("", h, NULL); +// (*key)->backend_data = talloc_strdup((*key)->mem_ctx, ""); + return WERR_OK; } static WERROR ldb_open_key(REG_HANDLE *h, int num, const char *name, REG_KEY **key) @@ -97,16 +134,26 @@ static WERROR ldb_open_key(REG_HANDLE *h, int num, const char *name, REG_KEY **k struct ldb_context *c = h->backend_data; char *path; struct ldb_message **msg; - char *ldap_path; + char *ldap_path, *new_ldap_path; + int ret; TALLOC_CTX *mem_ctx = talloc_init("ldb_path"); - ldap_path = reg_path_to_ldb(mem_ctx, name); + if(num != 0) return WERR_NO_MORE_ITEMS; + ldap_path = reg_path_to_ldb(mem_ctx, name, NULL); - if(ldb_search(c, NULL, LDB_SCOPE_BASE, ldap_path, NULL,&msg) > 0) { - *key = reg_key_new_abs(name, h, ldap_path); - talloc_steal(mem_ctx, (*key)->mem_ctx, ldap_path); - /* FIXME */ + ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "*", NULL,&msg); + + if(ret == 0) { + return WERR_NO_MORE_ITEMS; + } else if(ret < 0) { + DEBUG(0, ("Error opening key '%s': %s\n", ldap_path, ldb_errstring(c))); + return WERR_FOOBAR; } + *key = reg_key_new_abs(name, h, ldap_path); + talloc_steal(mem_ctx, (*key)->mem_ctx, ldap_path); + printf("Got something!\n"); + /* FIXME */ + ldb_search_free(c, msg); talloc_destroy(mem_ctx); @@ -116,6 +163,7 @@ static WERROR ldb_open_key(REG_HANDLE *h, int num, const char *name, REG_KEY **k static struct registry_ops reg_backend_ldb = { .name = "ldb", .open_registry = ldb_open_registry, + .get_hive = ldb_get_hive, .close_registry = ldb_close_registry, .open_key = ldb_open_key, .fetch_subkeys = ldb_fetch_subkeys, -- cgit From 8dcb4aa084457e6d7a68467dceebc11abe4464bd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 12 Jun 2004 17:51:22 +0000 Subject: r1119: Saner keyboard shortcuts (This used to be commit 971941acc7e75da89b1bdc612fd476a7f6124dcb) --- source4/lib/registry/tools/gregedit.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/gregedit.c b/source4/lib/registry/tools/gregedit.c index d878461bff..f9e1786d71 100644 --- a/source4/lib/registry/tools/gregedit.c +++ b/source4/lib/registry/tools/gregedit.c @@ -451,7 +451,7 @@ static GtkWidget* create_mainwin (void) gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_file), menu_file_menu); if(reg_has_backend("nt4")) { - open_nt4 = gtk_image_menu_item_new_with_mnemonic("_Open NT4 file"); + open_nt4 = gtk_image_menu_item_new_with_mnemonic("Open _NT4 file"); gtk_widget_show (open_nt4); gtk_container_add (GTK_CONTAINER (menu_file_menu), open_nt4); @@ -461,7 +461,7 @@ static GtkWidget* create_mainwin (void) } if(reg_has_backend("w95")) { - open_w95 = gtk_image_menu_item_new_with_mnemonic("_Open Win9x file"); + open_w95 = gtk_image_menu_item_new_with_mnemonic("Open Win_9x file"); gtk_widget_show (open_w95); gtk_container_add (GTK_CONTAINER (menu_file_menu), open_w95); @@ -471,7 +471,7 @@ static GtkWidget* create_mainwin (void) } if(reg_has_backend("gconf")) { - open_gconf = gtk_image_menu_item_new_with_mnemonic ("_Open GConf"); + open_gconf = gtk_image_menu_item_new_with_mnemonic ("Open _GConf"); gtk_widget_show (open_gconf); gtk_container_add (GTK_CONTAINER (menu_file_menu), open_gconf); @@ -481,7 +481,7 @@ static GtkWidget* create_mainwin (void) } if(reg_has_backend("rpc")) { - open_remote = gtk_menu_item_new_with_mnemonic ("_Open Remote"); + open_remote = gtk_menu_item_new_with_mnemonic ("Open _Remote"); gtk_widget_show (open_remote); gtk_container_add (GTK_CONTAINER (menu_file_menu), open_remote); -- cgit From 0b817ae8511983825ef63d2989e937f03beb39cf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jun 2004 13:56:52 +0000 Subject: r1147: Support enumerating values (This used to be commit 3af8419fa4053a3b2887e91b4bda5c93327efad4) --- .../lib/registry/reg_backend_ldb/reg_backend_ldb.c | 48 ++++++++++++++++++++-- 1 file changed, 44 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index 408ce52e44..9dfd3329e0 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -52,7 +52,6 @@ static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char * ret[strlen(ret)-1] = '\0'; - printf("Doing search for : %s\n", ret); return ret; } @@ -82,13 +81,17 @@ static WERROR ldb_close_registry(REG_HANDLE *h) return WERR_OK; } +static WERROR ldb_add_key(REG_KEY *p, const char *name, uint32_t access_mask, SEC_DESC *sec, REG_KEY **new) +{ + return WERR_NOT_SUPPORTED; +} + static WERROR ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys) { struct ldb_context *c = k->handle->backend_data; char *path; int ret, i, j; struct ldb_message **msg; - TALLOC_CTX *mem_ctx = talloc_init("ldb_path"); REG_KEY *key = NULL; ret = ldb_search(c, (char *)k->backend_data, LDB_SCOPE_ONELEVEL, "(key=*)", NULL,&msg); @@ -117,7 +120,43 @@ static WERROR ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys) *count = j; ldb_search_free(c, msg); - talloc_destroy(mem_ctx); + return WERR_OK; +} + +static WERROR ldb_fetch_values(REG_KEY *k, int *count, REG_VAL ***values) +{ + struct ldb_context *c = k->handle->backend_data; + char *path; + int ret, i, j; + struct ldb_message **msg; + REG_KEY *key = NULL; + + ret = ldb_search(c, (char *)k->backend_data, LDB_SCOPE_ONELEVEL, "(value=*)", NULL,&msg); + + if(ret < 0) { + DEBUG(0, ("Error getting values for '%s': %s\n", k->backend_data, ldb_errstring(c))); + return WERR_FOOBAR; + } + + *values = talloc_array_p(k->mem_ctx, REG_VAL *, ret); + j = 0; + for(i = 0; i < ret; i++) { + struct ldb_message_element *el; + char *name; + el = ldb_msg_find_element(msg[i], "key"); + + name = el->values[0].data; + + /* Dirty hack to circumvent ldb_tdb bug */ + if(k->backend_data && !strcmp(msg[i]->dn, (char *)k->backend_data)) continue; + + (*values)[j] = reg_val_new(k, NULL); + (*values)[j]->backend_data = talloc_strdup((*values)[j]->mem_ctx, msg[i]->dn); + j++; + } + *count = j; + + ldb_search_free(c, msg); return WERR_OK; } @@ -125,7 +164,6 @@ static WERROR ldb_get_hive(REG_HANDLE *h, int num, REG_KEY **key) { if(num != 0) return WERR_NO_MORE_ITEMS; *key = reg_key_new_abs("", h, NULL); -// (*key)->backend_data = talloc_strdup((*key)->mem_ctx, ""); return WERR_OK; } @@ -167,6 +205,8 @@ static struct registry_ops reg_backend_ldb = { .close_registry = ldb_close_registry, .open_key = ldb_open_key, .fetch_subkeys = ldb_fetch_subkeys, + .fetch_values = ldb_fetch_values, + .add_key = ldb_add_key, }; NTSTATUS registry_ldb_init(void) -- cgit From e3fd2d049216f79ced472e2af790ca6ffefba442 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 Jul 2004 01:01:48 +0000 Subject: r1432: - Move the various Gtk-specific parts from the registry code into a directory gtk/ - Move common "Samba-Gtk" code into gtk/common/ ("Connect to RPC pipe"-dialog, etc) - Add a new utility 'gwcrontab' that can currently list, delete and add 'atsvc' jobs. It still displays times and dates as integers though, will fix that later. Some screenshots available at: http://samba.org/~jelmer/gwcrontab/ (This used to be commit d321cf20f1f0ff33603b013c26d370669f255868) --- source4/lib/registry/config.m4 | 6 - source4/lib/registry/config.mk | 12 - source4/lib/registry/tools/gregedit.c | 783 ---------------------------------- 3 files changed, 801 deletions(-) delete mode 100644 source4/lib/registry/tools/gregedit.c (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index a1dc9a45bc..4fdde67faf 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -7,7 +7,6 @@ LIBWINREG=libwinregistry AC_CONFIG_FILES(lib/registry/winregistry.pc) -SMB_BINARY_ENABLE(gregedit, NO) SMB_MODULE_DEFAULT(registry_gconf, NOT) SMB_EXT_LIB_FROM_PKGCONFIG(gconf, gconf-2.0) @@ -18,10 +17,6 @@ fi SMB_EXT_LIB_FROM_PKGCONFIG(gtk, [glib-2.0 gtk+-2.0]) -if test t$SMB_EXT_LIB_ENABLE_gtk = tYES; then - SMB_BINARY_ENABLE(gregedit, YES) -fi - SMB_MODULE_MK(registry_nt4, REGISTRY, STATIC, lib/registry/config.mk) SMB_MODULE_MK(registry_w95, REGISTRY, STATIC, lib/registry/config.mk) SMB_MODULE_MK(registry_dir, REGISTRY, STATIC, lib/registry/config.mk) @@ -35,7 +30,6 @@ SMB_BINARY_MK(regdiff, lib/registry/config.mk) SMB_BINARY_MK(regpatch, lib/registry/config.mk) SMB_BINARY_MK(regshell, lib/registry/config.mk) SMB_BINARY_MK(regtree, lib/registry/config.mk) -SMB_BINARY_MK(gregedit, lib/registry/config.mk) if test x"$experimental" = x"yes"; then SMB_LIBRARY_ENABLE(libwinregistry, YES) diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 1d2a1fec6d..8100c798e6 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -118,15 +118,3 @@ REQUIRED_SUBSYSTEMS = \ CONFIG LIBCMDLINE REGISTRY # End BINARY regtree ################################################ - -################################################ -# Start BINARY gregedit -[BINARY::gregedit] -OBJ_FILES= \ - lib/registry/tools/gregedit.o -REQUIRED_LIBRARIES = \ - gtk -REQUIRED_SUBSYSTEMS = \ - CONFIG LIBCMDLINE REGISTRY -# End BINARY gregedit -################################################ diff --git a/source4/lib/registry/tools/gregedit.c b/source4/lib/registry/tools/gregedit.c deleted file mode 100644 index f9e1786d71..0000000000 --- a/source4/lib/registry/tools/gregedit.c +++ /dev/null @@ -1,783 +0,0 @@ -/* - Unix SMB/CIFS implementation. - GTK+ registry frontend - - Copyright (C) Jelmer Vernooij 2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include - -#include -#include -#include "includes.h" - -GtkWidget *openfilewin; -GtkWidget *savefilewin; -GtkTreeStore *store_keys; -GtkListStore *store_vals; -GtkWidget *tree_keys; -GtkWidget *aboutwin; -GtkWidget *mainwin; - -GtkWidget *rpcwin; -GtkWidget *rpcwin_host; -GtkWidget *rpcwin_user; -GtkWidget *rpcwin_password; -GtkWidget *save; -GtkWidget *save_as; -static GtkWidget* create_openfilewin (void); -static GtkWidget* create_savefilewin (void); -static GtkWidget* create_aboutwin (void); -REG_HANDLE *registry = NULL; - -static void gtk_show_werror(WERROR err) -{ - GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(mainwin), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "Registry error: %s\n", win_errstr(err)); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); -} - -static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath *arg2) -{ - GtkTreeIter firstiter, iter, tmpiter; - REG_KEY *k, *sub; - char *name; - GValue value; - WERROR error; - int i; - - gtk_tree_model_iter_children(GTK_TREE_MODEL(store_keys), &firstiter, parent); - - /* See if this row has ever had a name gtk_tree_store_set()'ed to it. - If not, read the directory contents */ - gtk_tree_model_get(GTK_TREE_MODEL(store_keys), &firstiter, 0, &name, -1); - - if(name) return; - - gtk_tree_model_get(GTK_TREE_MODEL(store_keys), parent, 1, &k, -1); - - g_assert(k); - - for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(k, i, &sub)); i++) { - int count; - /* Replace the blank child with the first directory entry - You may be tempted to remove the blank child node and then - append a new one. Don't. If you remove the blank child - node GTK gets confused and won't expand the parent row. */ - - if(i == 0) { - iter = firstiter; - } else { - gtk_tree_store_append(store_keys, &iter, parent); - } - gtk_tree_store_set (store_keys, - &iter, - 0, - reg_key_name(sub), - 1, - sub, - -1); - - if(W_ERROR_IS_OK(reg_key_num_subkeys(sub, &count)) && count > 0) - gtk_tree_store_append(store_keys, &tmpiter, &iter); - } - - if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) gtk_show_werror(error); -} - -static void registry_load_root() -{ - REG_KEY *root; - GtkTreeIter iter, tmpiter; - WERROR error = WERR_OK; - int i = 0; - if(!registry) return; - - gtk_tree_store_clear(store_keys); - - while(1) { - error = reg_get_hive(registry, i, &root); - if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { - return; - } - if(!W_ERROR_IS_OK(error)) { - gtk_show_werror(error); - return; - } - - /* Add the root */ - gtk_tree_store_append(store_keys, &iter, NULL); - gtk_tree_store_set (store_keys, - &iter, - 0, - reg_key_name(root), - 1, - root, - -1); - - gtk_tree_store_append(store_keys, &tmpiter, &iter); - i++; - } - - gtk_widget_set_sensitive( save, True ); - gtk_widget_set_sensitive( save_as, True ); -} - -static GtkWidget* create_rpcwin (void) -{ - GtkWidget *dialog_vbox1; - GtkWidget *table1; - GtkWidget *label1; - GtkWidget *label2; - GtkWidget *label3; - GtkWidget *dialog_action_area1; - GtkWidget *cancelbutton1; - GtkWidget *okbutton1; - - rpcwin = gtk_dialog_new (); - gtk_window_set_title (GTK_WINDOW (rpcwin), "Connect to remote server"); - - dialog_vbox1 = GTK_DIALOG (rpcwin)->vbox; - gtk_widget_show (dialog_vbox1); - - table1 = gtk_table_new (3, 2, FALSE); - gtk_widget_show (table1); - gtk_box_pack_start (GTK_BOX (dialog_vbox1), table1, TRUE, TRUE, 0); - - label1 = gtk_label_new ("Host:"); - gtk_widget_show (label1); - gtk_table_attach (GTK_TABLE (table1), label1, 0, 1, 0, 1, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label1), 0, 0.5); - - label2 = gtk_label_new ("User:"); - gtk_widget_show (label2); - gtk_table_attach (GTK_TABLE (table1), label2, 0, 1, 1, 2, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label2), 0, 0.5); - - label3 = gtk_label_new ("Password:"); - gtk_widget_show (label3); - gtk_table_attach (GTK_TABLE (table1), label3, 0, 1, 2, 3, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment (GTK_MISC (label3), 0, 0.5); - - rpcwin_host = gtk_entry_new (); - gtk_widget_show (rpcwin_host); - gtk_table_attach (GTK_TABLE (table1), rpcwin_host, 1, 2, 0, 1, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - - rpcwin_user = gtk_entry_new (); - gtk_widget_show (rpcwin_user); - gtk_table_attach (GTK_TABLE (table1), rpcwin_user, 1, 2, 1, 2, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - - rpcwin_password = gtk_entry_new (); - gtk_widget_show (rpcwin_password); - gtk_table_attach (GTK_TABLE (table1), rpcwin_password, 1, 2, 2, 3, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_entry_set_visibility (GTK_ENTRY (rpcwin_password), FALSE); - - dialog_action_area1 = GTK_DIALOG (rpcwin)->action_area; - gtk_widget_show (dialog_action_area1); - gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END); - - cancelbutton1 = gtk_button_new_from_stock ("gtk-cancel"); - gtk_widget_show (cancelbutton1); - gtk_dialog_add_action_widget (GTK_DIALOG (rpcwin), cancelbutton1, GTK_RESPONSE_CANCEL); - GTK_WIDGET_SET_FLAGS (cancelbutton1, GTK_CAN_DEFAULT); - - okbutton1 = gtk_button_new_from_stock ("gtk-ok"); - gtk_widget_show (okbutton1); - gtk_dialog_add_action_widget (GTK_DIALOG (rpcwin), okbutton1, GTK_RESPONSE_OK); - GTK_WIDGET_SET_FLAGS (okbutton1, GTK_CAN_DEFAULT); - - return rpcwin; -} - -static void on_open_file_activate (GtkMenuItem *menuitem, gpointer user_data) -{ - gint result = gtk_dialog_run(GTK_DIALOG(create_openfilewin())); - char *filename; - WERROR error; - switch(result) { - case GTK_RESPONSE_OK: - filename = strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(openfilewin))); - error = reg_open(user_data, filename, NULL, ®istry); - if(!W_ERROR_IS_OK(error)) { - gtk_show_werror(error); - break; - } - registry_load_root(); - break; - default: - break; - } - - gtk_widget_destroy(openfilewin); -} - -static void on_open_gconf_activate (GtkMenuItem *menuitem, - gpointer user_data) -{ - WERROR error = reg_open("gconf", NULL, NULL, ®istry); - if(!W_ERROR_IS_OK(error)) { - gtk_show_werror(error); - return; - } - - registry_load_root(); -} - -static void on_open_remote_activate (GtkMenuItem *menuitem, - gpointer user_data) -{ - char *location, *credentials; - gint result = gtk_dialog_run(GTK_DIALOG(create_rpcwin())); - WERROR error; - switch(result) { - case GTK_RESPONSE_OK: - asprintf(&location, "ncacn_np:%s", gtk_entry_get_text(GTK_ENTRY(rpcwin_host))); - asprintf(&credentials, "%s%%%s", gtk_entry_get_text(GTK_ENTRY(rpcwin_user)), gtk_entry_get_text(GTK_ENTRY(rpcwin_password))); - error = reg_open("rpc", location, credentials, ®istry); - if(!W_ERROR_IS_OK(error)) { - gtk_show_werror(error); - break; - } - free(location); free(credentials); - registry_load_root(); - break; - default: - break; - } - - gtk_widget_destroy(rpcwin); -} - - -static void on_save_activate (GtkMenuItem *menuitem, - gpointer user_data) -{ - WERROR error = reg_save(registry, NULL); - if(!W_ERROR_IS_OK(error)) { - gtk_show_werror(error); - } -} - - -static void on_save_as_activate (GtkMenuItem *menuitem, - gpointer user_data) -{ - gint result; - WERROR error; - create_savefilewin(); - result = gtk_dialog_run(GTK_DIALOG(savefilewin)); - switch(result) { - case GTK_RESPONSE_OK: - error = reg_save(registry, gtk_file_selection_get_filename(GTK_FILE_SELECTION(savefilewin))); - if(!W_ERROR_IS_OK(error)) { - gtk_show_werror(error); - } - break; - - default: - break; - - } - gtk_widget_destroy(savefilewin); -} - - -static void on_quit_activate (GtkMenuItem *menuitem, - gpointer user_data) -{ - gtk_main_quit(); -} - - -static void on_cut_activate (GtkMenuItem *menuitem, - gpointer user_data) -{ - /* FIXME */ -} - - -static void on_copy_activate (GtkMenuItem *menuitem, - gpointer user_data) -{ - /* FIXME */ -} - - -static void on_paste_activate (GtkMenuItem *menuitem, - gpointer user_data) -{ - /* FIXME */ -} - - -static void on_delete_activate (GtkMenuItem *menuitem, - gpointer user_data) -{ - /* FIXME */ -} - - -static void on_about_activate (GtkMenuItem *menuitem, - gpointer user_data) -{ - gtk_dialog_run(GTK_DIALOG(create_aboutwin())); - gtk_widget_destroy(aboutwin); -} - -static void on_key_activate (GtkTreeView *treeview, - GtkTreePath *path, - gpointer user_data) -{ - int i; - REG_KEY *k; - REG_VAL *val; - WERROR error; - GtkTreeIter parent; - - gtk_tree_model_get_iter(GTK_TREE_MODEL(store_keys), &parent, path); - gtk_tree_model_get(GTK_TREE_MODEL(store_keys), &parent, 1, &k, -1); - - g_assert(k); - - gtk_list_store_clear(store_vals); - - for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(k, i, &val)); i++) { - GtkTreeIter iter; - gtk_list_store_append(store_vals, &iter); - gtk_list_store_set (store_vals, - &iter, - 0, - reg_val_name(val), - 1, - str_regtype(reg_val_type(val)), - 2, - reg_val_data_string(val), - 3, - val, - -1); - } - - if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) gtk_show_werror(error); -} - -static GtkWidget* create_mainwin (void) -{ - GtkWidget *vbox1; - GtkWidget *menubar; - GtkWidget *menu_file; - GtkWidget *menu_file_menu; - GtkWidget *open_nt4; - GtkWidget *open_w95; - GtkWidget *open_gconf; - GtkWidget *open_remote; - GtkWidget *separatormenuitem1; - GtkWidget *quit; - GtkWidget *men_edit; - GtkWidget *men_edit_menu; - GtkWidget *cut; - GtkWidget *copy; - GtkWidget *paste; - GtkWidget *delete; - GtkCellRenderer *renderer; - GtkTreeViewColumn *curcol; - GtkWidget *help; - GtkWidget *help_menu; - GtkWidget *about; - GtkWidget *hbox1; - GtkWidget *scrolledwindow1; - GtkWidget *scrolledwindow2; - GtkWidget *tree_vals; - GtkWidget *statusbar; - GtkAccelGroup *accel_group; - GtkTreeIter iter, child; - - accel_group = gtk_accel_group_new (); - - mainwin = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW (mainwin), "Registry editor"); - gtk_window_set_default_size (GTK_WINDOW (mainwin), 642, 562); - - vbox1 = gtk_vbox_new (FALSE, 0); - gtk_widget_show (vbox1); - gtk_container_add (GTK_CONTAINER (mainwin), vbox1); - - menubar = gtk_menu_bar_new (); - gtk_widget_show (menubar); - gtk_box_pack_start (GTK_BOX (vbox1), menubar, FALSE, FALSE, 0); - - menu_file = gtk_menu_item_new_with_mnemonic ("_File"); - gtk_widget_show (menu_file); - gtk_container_add (GTK_CONTAINER (menubar), menu_file); - - menu_file_menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_file), menu_file_menu); - - if(reg_has_backend("nt4")) { - open_nt4 = gtk_image_menu_item_new_with_mnemonic("Open _NT4 file"); - gtk_widget_show (open_nt4); - gtk_container_add (GTK_CONTAINER (menu_file_menu), open_nt4); - - g_signal_connect ((gpointer) open_nt4, "activate", - G_CALLBACK (on_open_file_activate), - "nt4"); - } - - if(reg_has_backend("w95")) { - open_w95 = gtk_image_menu_item_new_with_mnemonic("Open Win_9x file"); - gtk_widget_show (open_w95); - gtk_container_add (GTK_CONTAINER (menu_file_menu), open_w95); - - g_signal_connect ((gpointer) open_w95, "activate", - G_CALLBACK (on_open_file_activate), - "w95"); - } - - if(reg_has_backend("gconf")) { - open_gconf = gtk_image_menu_item_new_with_mnemonic ("Open _GConf"); - gtk_widget_show (open_gconf); - gtk_container_add (GTK_CONTAINER (menu_file_menu), open_gconf); - - g_signal_connect ((gpointer) open_gconf, "activate", - G_CALLBACK (on_open_gconf_activate), - NULL); - } - - if(reg_has_backend("rpc")) { - open_remote = gtk_menu_item_new_with_mnemonic ("Open _Remote"); - gtk_widget_show (open_remote); - gtk_container_add (GTK_CONTAINER (menu_file_menu), open_remote); - - g_signal_connect ((gpointer) open_remote, "activate", - G_CALLBACK (on_open_remote_activate), - NULL); - } - - save = gtk_image_menu_item_new_from_stock ("gtk-save", accel_group); - gtk_widget_show (save); - gtk_widget_set_sensitive( save, False ); - gtk_container_add (GTK_CONTAINER (menu_file_menu), save); - - save_as = gtk_image_menu_item_new_from_stock ("gtk-save-as", accel_group); - gtk_widget_show (save_as); - gtk_widget_set_sensitive( save_as, False ); - gtk_container_add (GTK_CONTAINER (menu_file_menu), save_as); - - separatormenuitem1 = gtk_menu_item_new (); - gtk_widget_show (separatormenuitem1); - gtk_container_add (GTK_CONTAINER (menu_file_menu), separatormenuitem1); - gtk_widget_set_sensitive (separatormenuitem1, FALSE); - - quit = gtk_image_menu_item_new_from_stock ("gtk-quit", accel_group); - gtk_widget_show (quit); - gtk_container_add (GTK_CONTAINER (menu_file_menu), quit); - - men_edit = gtk_menu_item_new_with_mnemonic ("_Edit"); - gtk_widget_show (men_edit); - gtk_container_add (GTK_CONTAINER (menubar), men_edit); - - men_edit_menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (men_edit), men_edit_menu); - - cut = gtk_image_menu_item_new_from_stock ("gtk-cut", accel_group); - gtk_widget_show (cut); - gtk_widget_set_sensitive(cut, False); - gtk_container_add (GTK_CONTAINER (men_edit_menu), cut); - - copy = gtk_image_menu_item_new_from_stock ("gtk-copy", accel_group); - gtk_widget_show (copy); - gtk_widget_set_sensitive(copy, False); - gtk_container_add (GTK_CONTAINER (men_edit_menu), copy); - - paste = gtk_image_menu_item_new_from_stock ("gtk-paste", accel_group); - gtk_widget_show (paste); - gtk_widget_set_sensitive(paste, False); - gtk_container_add (GTK_CONTAINER (men_edit_menu), paste); - - delete = gtk_image_menu_item_new_from_stock ("gtk-delete", accel_group); - gtk_widget_show (delete); - gtk_widget_set_sensitive(delete, False); - gtk_container_add (GTK_CONTAINER (men_edit_menu), delete); - - help = gtk_menu_item_new_with_mnemonic ("_Help"); - gtk_widget_show (help); - gtk_container_add (GTK_CONTAINER (menubar), help); - - help_menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (help), help_menu); - - about = gtk_menu_item_new_with_mnemonic ("_About"); - gtk_widget_show (about); - gtk_container_add (GTK_CONTAINER (help_menu), about); - - hbox1 = gtk_hbox_new (FALSE, 0); - gtk_widget_show (hbox1); - gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0); - - scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_show (scrolledwindow1); - gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow1, TRUE, TRUE, 0); - - tree_keys = gtk_tree_view_new (); - - /* Column names */ - curcol = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title(curcol, "Name"); - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_column_pack_start(curcol, renderer, True); - - gtk_tree_view_append_column(GTK_TREE_VIEW(tree_keys), curcol); - - gtk_tree_view_column_add_attribute(curcol, renderer, "text", 0); - gtk_widget_show (tree_keys); - gtk_container_add (GTK_CONTAINER (scrolledwindow1), tree_keys); - store_keys = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER); - gtk_tree_view_set_model(GTK_TREE_VIEW(tree_keys), GTK_TREE_MODEL(store_keys)); - g_object_unref(store_keys); - - g_signal_connect ((gpointer) tree_keys, "row-activated", - G_CALLBACK (on_key_activate), - NULL); - - g_signal_connect ((gpointer) tree_keys, "row-expanded", - G_CALLBACK (expand_key), - NULL); - - scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_show (scrolledwindow2); - gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow2, TRUE, TRUE, 0); - - tree_vals = gtk_tree_view_new (); - /* Column names */ - - curcol = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title(curcol, "Name"); - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_column_pack_start(curcol, renderer, True); - gtk_tree_view_append_column(GTK_TREE_VIEW(tree_vals), curcol); - gtk_tree_view_column_add_attribute(curcol, renderer, "text", 0); - - curcol = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title(curcol, "Type"); - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_column_pack_start(curcol, renderer, True); - gtk_tree_view_append_column(GTK_TREE_VIEW(tree_vals), curcol); - gtk_tree_view_column_add_attribute(curcol, renderer, "text", 1); - - curcol = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title(curcol, "Value"); - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_column_pack_start(curcol, renderer, True); - gtk_tree_view_append_column(GTK_TREE_VIEW(tree_vals), curcol); - gtk_tree_view_column_add_attribute(curcol, renderer, "text", 2); - - - gtk_widget_show (tree_vals); - gtk_container_add (GTK_CONTAINER (scrolledwindow2), tree_vals); - - store_vals = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); - gtk_tree_view_set_model(GTK_TREE_VIEW(tree_vals), GTK_TREE_MODEL(store_vals)); - g_object_unref(store_vals); - - statusbar = gtk_statusbar_new (); - gtk_widget_show (statusbar); - gtk_box_pack_start (GTK_BOX (vbox1), statusbar, FALSE, FALSE, 0); - gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (statusbar), FALSE); - - g_signal_connect ((gpointer) save, "activate", - G_CALLBACK (on_save_activate), - NULL); - g_signal_connect ((gpointer) save_as, "activate", - G_CALLBACK (on_save_as_activate), - NULL); - g_signal_connect ((gpointer) quit, "activate", - G_CALLBACK (on_quit_activate), - NULL); - g_signal_connect ((gpointer) cut, "activate", - G_CALLBACK (on_cut_activate), - NULL); - g_signal_connect ((gpointer) copy, "activate", - G_CALLBACK (on_copy_activate), - NULL); - g_signal_connect ((gpointer) paste, "activate", - G_CALLBACK (on_paste_activate), - NULL); - g_signal_connect ((gpointer) delete, "activate", - G_CALLBACK (on_delete_activate), - NULL); - g_signal_connect ((gpointer) about, "activate", - G_CALLBACK (on_about_activate), - NULL); - - gtk_window_add_accel_group (GTK_WINDOW (mainwin), accel_group); - - return mainwin; -} - -static GtkWidget* create_aboutwin (void) -{ - GtkWidget *dialog_vbox1; - GtkWidget *image1; - GtkWidget *label1; - GtkWidget *label2; - GtkWidget *dialog_action_area1; - GtkWidget *closebutton1; - - aboutwin = gtk_dialog_new (); - gtk_window_set_title (GTK_WINDOW (aboutwin), "About GRegEdit"); - gtk_window_set_resizable (GTK_WINDOW (aboutwin), FALSE); - - dialog_vbox1 = GTK_DIALOG (aboutwin)->vbox; - gtk_widget_show (dialog_vbox1); - - /* FIXME: Samba logo ? - image1 = create_pixmap (aboutwin, "samba.png"); - gtk_widget_show (image1); - gtk_box_pack_start (GTK_BOX (dialog_vbox1), image1, FALSE, TRUE, 0); */ - - label1 = gtk_label_new ("GRegEdit 0.1"); - gtk_widget_show (label1); - gtk_box_pack_start (GTK_BOX (dialog_vbox1), label1, FALSE, FALSE, 0); - gtk_label_set_use_markup (GTK_LABEL (label1), TRUE); - - label2 = gtk_label_new_with_mnemonic ("(C) 2004 Jelmer Vernooij \nPart of Samba\nhttp://www.samba.org/\n"); - gtk_widget_show (label2); - gtk_box_pack_start (GTK_BOX (dialog_vbox1), label2, TRUE, FALSE, 0); - gtk_label_set_use_markup (GTK_LABEL (label2), TRUE); - - dialog_action_area1 = GTK_DIALOG (aboutwin)->action_area; - gtk_widget_show (dialog_action_area1); - gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END); - - closebutton1 = gtk_button_new_from_stock ("gtk-close"); - gtk_widget_show (closebutton1); - gtk_dialog_add_action_widget (GTK_DIALOG (aboutwin), closebutton1, GTK_RESPONSE_CLOSE); - GTK_WIDGET_SET_FLAGS (closebutton1, GTK_CAN_DEFAULT); - - return aboutwin; -} - - -static GtkWidget* create_openfilewin (void) -{ - GtkWidget *ok_button; - GtkWidget *cancel_button; - - openfilewin = gtk_file_selection_new ("Select File"); - gtk_container_set_border_width (GTK_CONTAINER (openfilewin), 10); - - ok_button = GTK_FILE_SELECTION (openfilewin)->ok_button; - gtk_widget_show (ok_button); - GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT); - - cancel_button = GTK_FILE_SELECTION (openfilewin)->cancel_button; - gtk_widget_show (cancel_button); - GTK_WIDGET_SET_FLAGS (cancel_button, GTK_CAN_DEFAULT); - - return openfilewin; -} - -static GtkWidget* create_savefilewin (void) -{ - GtkWidget *ok_button; - GtkWidget *cancel_button; - - savefilewin = gtk_file_selection_new ("Select File"); - gtk_container_set_border_width (GTK_CONTAINER (savefilewin), 10); - - ok_button = GTK_FILE_SELECTION (savefilewin)->ok_button; - gtk_widget_show (ok_button); - GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT); - - cancel_button = GTK_FILE_SELECTION (savefilewin)->cancel_button; - gtk_widget_show (cancel_button); - GTK_WIDGET_SET_FLAGS (cancel_button, GTK_CAN_DEFAULT); - - return savefilewin; -} - - int main(int argc, char *argv[]) -{ - poptContext pc; - const char *backend = NULL; - const char *credentials = NULL; - const char *location; - int opt; - struct poptOption long_options[] = { - POPT_AUTOHELP - {"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL}, - {"credentials", 'c', POPT_ARG_STRING, &credentials, 0, "credentials (user%%password)", NULL}, - POPT_TABLEEND - }; - - gtk_init (&argc, &argv); - - pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); - - while((opt = poptGetNextOpt(pc)) != -1) { - } - - location = poptGetArg(pc); - - if(location) { - WERROR error; - - if(!backend) { - if(credentials)backend = "rpc"; - else backend = "nt4"; - } - - error = reg_open(backend, location, credentials, ®istry); - if(!W_ERROR_IS_OK(error)) { - gtk_show_werror(error); - return -1; - } - mainwin = create_mainwin (); - registry_load_root(); - } else - mainwin = create_mainwin (); - - gtk_widget_show (mainwin); - - gtk_main (); - - if(registry)reg_free(registry); - return 0; -} -- cgit From 664f50e81cc97eac7162cb3dd324eaefb11aa7d2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 18 Aug 2004 19:57:49 +0000 Subject: r1894: Convert // to /* */ (This used to be commit 5dc793b2b4b5c54df4aa3b0c98c248bdd671bbb1) --- source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c | 2 +- source4/lib/registry/tools/regpatch.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index 36feaff907..ee9f8bf24f 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -1438,7 +1438,7 @@ static uint_t nt_store_security(REG_HANDLE *regf, KEY_SEC_DESC *sec) * means making one pass over each structure and figuring it out */ -//FIXME size = sec_desc_size(sec->sec_desc); +/* FIXME size = sec_desc_size(sec->sec_desc); */ /* Allocate that much space */ diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index af869d1cfa..7eddea2b93 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -648,7 +648,7 @@ static CMD_FILE *cmd_file_create(const char *file) * We pass a table of command callbacks for that */ -//FIXME +/* FIXME */ /* * Main code from here on ... -- cgit From b83ba93eaeb2dcb0bf11615591d886fda84e4162 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 21 Aug 2004 01:54:46 +0000 Subject: r1983: a completely new implementation of talloc This version does the following: 1) talloc_free(), talloc_realloc() and talloc_steal() lose their (redundent) first arguments 2) you can use _any_ talloc pointer as a talloc context to allocate more memory. This allows you to create complex data structures where the top level structure is the logical parent of the next level down, and those are the parents of the level below that. Then destroy either the lot with a single talloc_free() or destroy any sub-part with a talloc_free() of that part 3) you can name any pointer. Use talloc_named() which is just like talloc() but takes the printf style name argument as well as the parent context and the size. The whole thing ends up being a very simple piece of code, although some of the pointer walking gets hairy. So far, I'm just using the new talloc() like the old one. The next step is to actually take advantage of the new interface properly. Expect some new commits soon that simplify some common coding styles in samba4 by using the new talloc(). (This used to be commit e35bb094c52e550b3105dd1638d8d90de71d854f) --- source4/lib/registry/common/reg_interface.c | 2 +- source4/lib/registry/reg_backend_dir/reg_backend_dir.c | 2 +- source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c | 4 ++-- source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 0a0cf05c2e..e7024d23fe 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -214,7 +214,7 @@ WERROR reg_open_key(REG_KEY *parent, const char *name, REG_KEY **result) (*result)->path = talloc_asprintf((*result)->mem_ctx, "%s\\%s", reg_key_get_path_abs(parent), (*result)->name); (*result)->hive = parent->hive; - talloc_steal(mem_ctx, (*result)->mem_ctx, fullname); + talloc_steal((*result)->mem_ctx, fullname); talloc_destroy(mem_ctx); 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 cac54f8437..b2bd34bf71 100644 --- a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c @@ -65,7 +65,7 @@ static WERROR reg_dir_open_key(REG_HANDLE *h, int hive, const char *name, REG_KE } closedir(d); ret = reg_key_new_abs(name, h, fullpath); - talloc_steal(mem_ctx, ret->mem_ctx, fullpath); + talloc_steal(ret->mem_ctx, fullpath); talloc_destroy(mem_ctx); *subkey = ret; return WERR_OK; diff --git a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c index c705a2e3cb..15a8319711 100644 --- a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c +++ b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c @@ -126,7 +126,7 @@ static WERROR gconf_fetch_values(REG_KEY *p, int *count, REG_VAL ***vals) } else newval->data_type = REG_NONE; ar[(*count)] = newval; - ar = talloc_realloc(p->mem_ctx, ar, sizeof(REG_VAL *) * ((*count)+2)); + ar = talloc_realloc(ar, sizeof(REG_VAL *) * ((*count)+2)); (*count)++; g_free(cur->data); cur = cur->next; @@ -151,7 +151,7 @@ static WERROR gconf_fetch_subkeys(REG_KEY *p, int *count, REG_KEY ***subs) ar[(*count)] = reg_key_new_abs(winpath, p->handle,NULL); free(winpath); ar[(*count)]->backend_data = reg_path_win2unix(talloc_strdup(ar[*count]->mem_ctx, cur->data)); - ar = talloc_realloc_p(p->mem_ctx, ar, REG_KEY *, (*count)+2); + ar = talloc_realloc_p(ar, REG_KEY *, (*count)+2); (*count)++; g_free(cur->data); cur = cur->next; diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index 9dfd3329e0..fa7e22d010 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -188,7 +188,7 @@ static WERROR ldb_open_key(REG_HANDLE *h, int num, const char *name, REG_KEY **k } *key = reg_key_new_abs(name, h, ldap_path); - talloc_steal(mem_ctx, (*key)->mem_ctx, ldap_path); + talloc_steal((*key)->mem_ctx, ldap_path); printf("Got something!\n"); /* FIXME */ -- cgit From dcd43a4cbef3bee948bdbd65212361b6043aa4bd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 22 Aug 2004 05:33:07 +0000 Subject: r1990: Fix breakage caused by the recent talloc changes. (Failure to process an SPNEGO login from WinXP at least). talloc_asprintf_append() lost an argument, but because TALLOC_CTX is now a void*, this was not picked up by the compiler. I've tested the login (asn1), but not the registry/gtk changes. Andrew Bartlett (This used to be commit 4294be44057124568fe1d176702056bb62ad3214) --- source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index fa7e22d010..6945ebdb55 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -28,7 +28,7 @@ static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char * char *end = mypath, *begin; if(add) - ret = talloc_asprintf_append(mem_ctx, ret, "%s", add); + ret = talloc_asprintf_append(ret, "%s", add); while(end) { char *keyname; @@ -38,7 +38,7 @@ static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char * else keyname = mypath; if(strlen(keyname)) - ret = talloc_asprintf_append(mem_ctx, ret, "key=%s,", keyname); + ret = talloc_asprintf_append(ret, "key=%s,", keyname); if(begin) { begin[0] = '\0'; -- cgit From 9c69fe6522289c154505beea554426b0bf308e06 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 8 Sep 2004 12:41:12 +0000 Subject: r2254: Fix a couple of compiler warnings... (This used to be commit 8056f4a9a7f5065eeb3a3bec81977c5e4163bf8e) --- source4/lib/registry/common/reg_interface.c | 5 ++--- source4/lib/registry/common/registry.h | 4 ++-- source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c | 11 +++-------- source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c | 3 --- 4 files changed, 7 insertions(+), 16 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index e7024d23fe..f0a6807558 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -30,9 +30,9 @@ static struct reg_init_function_entry *backends = NULL; static struct reg_init_function_entry *reg_find_backend_entry(const char *name); /* Register new backend */ -NTSTATUS registry_register(void *_function) +NTSTATUS registry_register(const void *_function) { - struct registry_ops *functions = _function; + const struct registry_ops *functions = _function; struct reg_init_function_entry *entry = backends; if (!functions || !functions->name) { @@ -97,7 +97,6 @@ WERROR reg_open(const char *backend, const char *location, const char *credentia struct reg_init_function_entry *entry; TALLOC_CTX *mem_ctx; REG_HANDLE *ret; - NTSTATUS status; WERROR werr; entry = reg_find_backend_entry(backend); diff --git a/source4/lib/registry/common/registry.h b/source4/lib/registry/common/registry.h index caa0e284bf..89d0ac6b14 100644 --- a/source4/lib/registry/common/registry.h +++ b/source4/lib/registry/common/registry.h @@ -123,7 +123,7 @@ struct registry_ops { }; struct reg_handle_s { - struct registry_ops *functions; + const struct registry_ops *functions; char *location; char *credentials; void *backend_data; @@ -132,7 +132,7 @@ struct reg_handle_s { struct reg_init_function_entry { /* Function to create a member of the pdb_methods list */ - struct registry_ops *functions; + const struct registry_ops *functions; struct reg_init_function_entry *prev, *next; }; diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index 6945ebdb55..47cb60d711 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -89,15 +89,13 @@ static WERROR ldb_add_key(REG_KEY *p, const char *name, uint32_t access_mask, SE static WERROR ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys) { struct ldb_context *c = k->handle->backend_data; - char *path; int ret, i, j; struct ldb_message **msg; - REG_KEY *key = NULL; ret = ldb_search(c, (char *)k->backend_data, LDB_SCOPE_ONELEVEL, "(key=*)", NULL,&msg); if(ret < 0) { - DEBUG(0, ("Error getting subkeys for '%s': %s\n", k->backend_data, ldb_errstring(c))); + DEBUG(0, ("Error getting subkeys for '%s': %s\n", (char *)k->backend_data, ldb_errstring(c))); return WERR_FOOBAR; } @@ -126,15 +124,13 @@ static WERROR ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys) static WERROR ldb_fetch_values(REG_KEY *k, int *count, REG_VAL ***values) { struct ldb_context *c = k->handle->backend_data; - char *path; int ret, i, j; struct ldb_message **msg; - REG_KEY *key = NULL; ret = ldb_search(c, (char *)k->backend_data, LDB_SCOPE_ONELEVEL, "(value=*)", NULL,&msg); if(ret < 0) { - DEBUG(0, ("Error getting values for '%s': %s\n", k->backend_data, ldb_errstring(c))); + DEBUG(0, ("Error getting values for '%s': %s\n", (char *)k->backend_data, ldb_errstring(c))); return WERR_FOOBAR; } @@ -170,9 +166,8 @@ static WERROR ldb_get_hive(REG_HANDLE *h, int num, REG_KEY **key) static WERROR ldb_open_key(REG_HANDLE *h, int num, const char *name, REG_KEY **key) { struct ldb_context *c = h->backend_data; - char *path; struct ldb_message **msg; - char *ldap_path, *new_ldap_path; + char *ldap_path; int ret; TALLOC_CTX *mem_ctx = talloc_init("ldb_path"); if(num != 0) return WERR_NO_MORE_ITEMS; 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 4e6944a1e3..0d8d935a4a 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -128,8 +128,6 @@ static WERROR rpc_close_registry(REG_HANDLE *h) static WERROR rpc_key_put_rpc_data(REG_KEY *k, struct rpc_key_data **data) { struct winreg_OpenKey r; - int i; - struct rpc_data *mydata = k->handle->backend_data; WERROR error; REG_KEY *hivekey; struct rpc_key_data *mykeydata; @@ -254,7 +252,6 @@ static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey) struct winreg_EnumKeyNameRequest keyname; struct winreg_String classname; struct winreg_Time tm; - struct rpc_data *mydata = parent->handle->backend_data; struct rpc_key_data *mykeydata = parent->backend_data; WERROR error; NTSTATUS status; -- cgit From 93454ff3d8177fb71443808f01740dbbe7e46dd8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 8 Sep 2004 13:44:45 +0000 Subject: r2257: Tab completion support in regshell (complete command names and key names in the current key) (This used to be commit 83f9f8eaa4825bb49e2b160a1a810080ecae4d39) --- source4/lib/registry/common/reg_objects.c | 10 +++ source4/lib/registry/tools/regshell.c | 116 +++++++++++++++++++++++++++++- 2 files changed, 125 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_objects.c b/source4/lib/registry/common/reg_objects.c index d042c74e47..d911b4650b 100644 --- a/source4/lib/registry/common/reg_objects.c +++ b/source4/lib/registry/common/reg_objects.c @@ -103,6 +103,16 @@ char *reg_key_name( REG_KEY *key ) return key->name; } +char *reg_key_class( REG_KEY *key ) +{ + return key->class_name; +} + +NTTIME reg_key_last_modified( REG_KEY *key ) +{ + return key->last_mod; +} + REG_KEY *reg_key_dup(REG_KEY *key) { key->ref++; diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index b843e91120..638ed70d5e 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -28,10 +28,23 @@ * rmkey/rmdir - remove key * mkkey/mkdir - make key * ch - change hive + * info - show key info * help * exit */ +static REG_KEY *cmd_info(REG_KEY *cur, int argc, char **argv) +{ + time_t last_mod; + printf("Name: %s\n", reg_key_name(cur)); + printf("Full path: %s\n", reg_key_get_path(cur)); + printf("Key Class: %s\n", reg_key_class(cur)); + last_mod = nt_time_to_unix(reg_key_last_modified(cur)); + printf("Time Last Modified: %s\n", ctime(&last_mod)); + /* FIXME: Security info */ + return cur; +} + static REG_KEY *cmd_pwd(REG_KEY *cur, int argc, char **argv) { printf("%s\n", reg_key_get_path_abs(cur)); @@ -180,6 +193,7 @@ struct { } regshell_cmds[] = { {"ck", "cd", "Change current key", cmd_ck }, {"ch", "hive", "Change current hive", cmd_hive }, + {"info", "i", "Show detailed information of a key", cmd_info }, {"list", "ls", "List values/keys in current key", cmd_ls }, {"mkkey", "mkdir", "Make new key", cmd_mkkey }, {"rmval", "rm", "Remove value", cmd_rmval }, @@ -224,6 +238,104 @@ static REG_KEY *process_cmd(REG_KEY *k, char *line) return k; } +#define MAX_COMPLETIONS 100 + +static REG_KEY *current_key = NULL; + +static char **reg_complete_command(const char *text, int end) +{ + /* Complete command */ + char **matches; + int i, len, samelen, count=1; + + matches = (char **)malloc(sizeof(matches[0])*MAX_COMPLETIONS); + if (!matches) return NULL; + matches[0] = NULL; + + len = strlen(text); + for (i=0;regshell_cmds[i].handle && count < MAX_COMPLETIONS-1;i++) { + if (strncmp(text, regshell_cmds[i].name, len) == 0) { + matches[count] = strdup(regshell_cmds[i].name); + if (!matches[count]) + goto cleanup; + if (count == 1) + samelen = strlen(matches[count]); + else + while (strncmp(matches[count], matches[count-1], samelen) != 0) + samelen--; + count++; + } + } + + switch (count) { + case 0: /* should never happen */ + case 1: + goto cleanup; + case 2: + matches[0] = strdup(matches[1]); + break; + default: + matches[0] = malloc(samelen+1); + if (!matches[0]) + goto cleanup; + strncpy(matches[0], matches[1], samelen); + matches[0][samelen] = 0; + } + matches[count] = NULL; + return matches; + +cleanup: + while (i >= 0) { + free(matches[i]); + i--; + } + free(matches); + return NULL; +} + +static char **reg_complete_key(const char *text, int end) +{ + REG_KEY *subkey; + int i, j = 0; + int len; + char **matches; + /* Complete argument */ + + matches = (char **)malloc(sizeof(matches[0])*MAX_COMPLETIONS); + if (!matches) return NULL; + matches[0] = NULL; + + len = strlen(text); + for(i = 0; j < MAX_COMPLETIONS-1; i++) { + WERROR status = reg_key_get_subkey_by_index(current_key, i, &subkey); + if(W_ERROR_IS_OK(status)) { + if(!strncmp(text, reg_key_name(subkey), len)) { + matches[j] = strdup(reg_key_name(subkey)); + j++; + } + reg_key_free(subkey); + } else if(W_ERROR_EQUAL(status, WERR_NO_MORE_ITEMS)) { + break; + } else { + printf("Error creating completion list: %s\n", win_errstr(status)); + return NULL; + } + } + matches[j] = NULL; + return matches; +} + +static char **reg_completion(const char *text, int start, int end) +{ + smb_readline_ca_char(' '); + + if (start == 0) { + return reg_complete_command(text, end); + } else { + return reg_complete_key(text, end); + } +} + int main(int argc, char **argv) { int opt; @@ -264,7 +376,9 @@ static REG_KEY *process_cmd(REG_KEY *k, char *line) asprintf(&prompt, "%s> ", reg_key_get_path_abs(curkey)); - line = smb_readline(prompt, NULL, NULL); + current_key = curkey; /* No way to pass a void * pointer + via readline :-( */ + line = smb_readline(prompt, NULL, reg_completion); if(!line) break; -- cgit From 369a5d64e462e084e6c5fe4984d56da18b2c92d9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 22 Sep 2004 12:32:31 +0000 Subject: r2518: Some long overdue changes: - Samba4-style code in lib/registry (struct registry_key instead of REG_KEY, etc) - Use hives (like Windows has drives) instead of one root key (like a Unix FS) - usability fixes in the GTK utilities (autodetect the username, enable/disable options, etc) - fix gwsam compile - several bugfixes in the registry rpc code - do charset conversion in nt4 registry backend (This used to be commit 2762ed3b9bf1d67dd54d63e02cddbfd71ea89892) --- source4/lib/registry/TODO | 1 - source4/lib/registry/common/reg_interface.c | 493 ++++++++++----------- source4/lib/registry/common/reg_objects.c | 213 --------- source4/lib/registry/common/reg_util.c | 64 +-- source4/lib/registry/common/registry.h | 142 ------ source4/lib/registry/config.mk | 1 - .../lib/registry/reg_backend_dir/reg_backend_dir.c | 77 ++-- .../registry/reg_backend_gconf/reg_backend_gconf.c | 201 ++++----- .../lib/registry/reg_backend_ldb/reg_backend_ldb.c | 65 ++- .../lib/registry/reg_backend_nt4/reg_backend_nt4.c | 143 +++--- .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 198 ++++----- .../lib/registry/reg_backend_w95/reg_backend_w95.c | 166 ++++--- source4/lib/registry/tools/regdiff.c | 76 ++-- source4/lib/registry/tools/regpatch.c | 31 +- source4/lib/registry/tools/regshell.c | 128 +++--- source4/lib/registry/tools/regtree.c | 50 ++- 16 files changed, 795 insertions(+), 1254 deletions(-) delete mode 100644 source4/lib/registry/common/reg_objects.c delete mode 100644 source4/lib/registry/common/registry.h (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/TODO b/source4/lib/registry/TODO index 695f786b69..1dea9d2650 100644 --- a/source4/lib/registry/TODO +++ b/source4/lib/registry/TODO @@ -1,4 +1,3 @@ -- support subtrees - ..\..\, \bla\blie support in regshell - finish rpc_server diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index f0a6807558..ec6188be71 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -19,7 +19,6 @@ */ #include "includes.h" -#include "lib/registry/common/registry.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_REGISTRY @@ -29,10 +28,12 @@ static struct reg_init_function_entry *backends = NULL; static struct reg_init_function_entry *reg_find_backend_entry(const char *name); +#define reg_make_path(mem_ctx, parent, name) (((parent)->hive->root == (parent))?talloc_strdup(mem_ctx, name):talloc_asprintf(mem_ctx, "%s\\%s", parent->path, name)) + /* Register new backend */ NTSTATUS registry_register(const void *_function) { - const struct registry_ops *functions = _function; + const struct registry_operations *functions = _function; struct reg_init_function_entry *entry = backends; if (!functions || !functions->name) { @@ -91,90 +92,157 @@ BOOL reg_has_backend(const char *backend) return reg_find_backend_entry(backend) != NULL?True:False; } -/* Open a registry file/host/etc */ -WERROR reg_open(const char *backend, const char *location, const char *credentials, REG_HANDLE **h) +WERROR reg_create(struct registry_context **_ret) +{ + TALLOC_CTX *mem_ctx; + struct registry_context *ret; + mem_ctx = talloc_init("registry handle"); + ret = talloc(mem_ctx, sizeof(struct registry_context)); + ret->mem_ctx = mem_ctx; + ZERO_STRUCTP(ret); + *_ret = ret; + return WERR_OK; +} + +WERROR reg_list_available_hives(TALLOC_CTX *mem_ctx, const char *backend, const char *location, const char *credentials, char ***hives) { struct reg_init_function_entry *entry; + + entry = reg_find_backend_entry(backend); + + if (!entry) { + DEBUG(0, ("No such registry backend '%s' loaded!\n", backend)); + return WERR_GENERAL_FAILURE; + } + + if(!entry->functions->list_available_hives) { + return WERR_NOT_SUPPORTED; + } + + return entry->functions->list_available_hives(mem_ctx, location, credentials, hives); +} + +WERROR reg_open(struct registry_context **ret, const char *backend, const char *location, const char *credentials) +{ + WERROR error = reg_create(ret); + char **hives; + int i; + TALLOC_CTX *mem_ctx = talloc_init("reg_open"); + + if(!W_ERROR_IS_OK(error)) return error; + + error = reg_list_available_hives(mem_ctx, backend, location, credentials, &hives); + + if(W_ERROR_EQUAL(error, WERR_NOT_SUPPORTED)) { + return reg_import_hive(*ret, backend, location, credentials, NULL); + } + + if(!W_ERROR_IS_OK(error)) return error; + + for(i = 0; hives[i]; i++) + { + error = reg_import_hive(*ret, backend, location, credentials, hives[i]); + if(!W_ERROR_IS_OK(error)) return error; + (*ret)->hives[i]->name = talloc_strdup((*ret)->mem_ctx, hives[i]); + } + + return WERR_OK; +} + +/* Open a registry file/host/etc */ +WERROR reg_import_hive(struct registry_context *h, const char *backend, const char *location, const char *credentials, const char *hivename) +{ + struct registry_hive *ret; TALLOC_CTX *mem_ctx; - REG_HANDLE *ret; + struct reg_init_function_entry *entry; WERROR werr; - + entry = reg_find_backend_entry(backend); if (!entry) { DEBUG(0, ("No such registry backend '%s' loaded!\n", backend)); return WERR_GENERAL_FAILURE; } + + if(!entry->functions->open_hive) { + return WERR_NOT_SUPPORTED; + } - mem_ctx = talloc_init(backend); - ret = talloc(mem_ctx, sizeof(REG_HANDLE)); - ZERO_STRUCTP(ret); + + mem_ctx = h->mem_ctx; + ret = talloc_p(mem_ctx, struct registry_hive); ret->location = location?talloc_strdup(mem_ctx, location):NULL; + ret->backend_hivename = hivename?talloc_strdup(mem_ctx, hivename):NULL; ret->credentials = credentials?talloc_strdup(mem_ctx, credentials):NULL; ret->functions = entry->functions; ret->backend_data = NULL; - ret->mem_ctx = mem_ctx; - *h = ret; + ret->reg_ctx = h; - if(!entry->functions->open_registry) { - return WERR_OK; - } + werr = entry->functions->open_hive(mem_ctx, ret, &ret->root); + + if(!W_ERROR_IS_OK(werr)) return werr; - werr = entry->functions->open_registry(ret, location, credentials); + if(!ret->root) return WERR_GENERAL_FAILURE; - if(W_ERROR_IS_OK(werr)) - return WERR_OK; + ret->root->hive = ret; + ret->root->name = NULL; + ret->root->path = ""; - talloc_destroy(mem_ctx); - return werr; + /* Add hive to context */ + h->num_hives++; + h->hives = talloc_realloc_p(h->hives, struct registry_hive *, h->num_hives); + h->hives[h->num_hives-1] = ret; + + return WERR_OK; } /* Open a key by name (including the hive name!) */ -WERROR reg_open_key_abs(REG_HANDLE *handle, const char *name, REG_KEY **result) +WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result) { - REG_KEY *hive; + struct registry_key *hive; WERROR error; - int i, hivelength; + int hivelength; + char *hivename; if(strchr(name, '\\')) hivelength = strchr(name, '\\')-name; else hivelength = strlen(name); - for(i = 0; W_ERROR_IS_OK(error); i++) { - error = reg_get_hive(handle, i, &hive); - if(W_ERROR_IS_OK(error) && !strncmp(reg_key_name(hive), name, hivelength)) { - return reg_open_key(hive, name, result); - } + hivename = strndup(name, hivelength); + error = reg_get_hive(handle, hivename, &hive); + SAFE_FREE(hivename); + + if(!W_ERROR_IS_OK(error)) { + return error; } - return error; + return reg_open_key(mem_ctx, hive, name, result); } /* Open a key * First tries to use the open_key function from the backend * then falls back to get_subkey_by_name and later get_subkey_by_index */ -WERROR reg_open_key(REG_KEY *parent, const char *name, REG_KEY **result) +WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, struct registry_key **result) { char *fullname; WERROR error; - TALLOC_CTX *mem_ctx; if(!parent) { DEBUG(0, ("Invalid parent key specified")); return WERR_INVALID_PARAM; } - if(!parent->handle->functions->open_key && - (parent->handle->functions->get_subkey_by_name || - parent->handle->functions->get_subkey_by_index)) { + if(!parent->hive->functions->open_key && + (parent->hive->functions->get_subkey_by_name || + parent->hive->functions->get_subkey_by_index)) { char *orig = strdup(name), *curbegin = orig, *curend = strchr(orig, '\\'); - REG_KEY *curkey = parent; + struct registry_key *curkey = parent; while(curbegin && *curbegin) { if(curend)*curend = '\0'; - error = reg_key_get_subkey_by_name(curkey, curbegin, result); + error = reg_key_get_subkey_by_name(mem_ctx, curkey, curbegin, &curkey); if(!W_ERROR_IS_OK(error)) { SAFE_FREE(orig); return error; @@ -184,94 +252,63 @@ WERROR reg_open_key(REG_KEY *parent, const char *name, REG_KEY **result) curend = strchr(curbegin, '\\'); } SAFE_FREE(orig); - + *result = curkey; + return WERR_OK; } - if(!parent->handle->functions->open_key) { + if(!parent->hive->functions->open_key) { DEBUG(0, ("Registry backend doesn't have get_subkey_by_name nor open_key!\n")); return WERR_NOT_SUPPORTED; } - mem_ctx = talloc_init("mem_ctx"); + fullname = reg_make_path(mem_ctx, parent, name); - fullname = talloc_asprintf(mem_ctx, "%s%s%s", - reg_key_get_path(parent), - strlen(reg_key_get_path(parent))?"\\":"", - name); + error = parent->hive->functions->open_key(mem_ctx, parent->hive, fullname, result); - error = parent->handle->functions->open_key(parent->handle, - parent->hive, fullname, result); - - if(!W_ERROR_IS_OK(error)) { - talloc_destroy(mem_ctx); - return error; - } + if(!W_ERROR_IS_OK(error)) return error; - (*result)->handle = parent->handle; - (*result)->path = talloc_asprintf((*result)->mem_ctx, "%s\\%s", - reg_key_get_path_abs(parent), (*result)->name); (*result)->hive = parent->hive; - talloc_steal((*result)->mem_ctx, fullname); - - talloc_destroy(mem_ctx); + (*result)->path = fullname; + (*result)->hive = parent->hive; return WERR_OK; } -WERROR reg_key_get_value_by_index(REG_KEY *key, int idx, REG_VAL **val) +WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *key, int idx, struct registry_value **val) { if(!key) return WERR_INVALID_PARAM; - if(key->handle->functions->get_value_by_index) { - WERROR status = key->handle->functions->get_value_by_index(key, idx, val); + if(key->hive->functions->get_value_by_index) { + WERROR status = key->hive->functions->get_value_by_index(mem_ctx, key, idx, val); if(!W_ERROR_IS_OK(status)) return status; - - } else if(key->handle->functions->fetch_values) { - if(!key->cache_values) - key->handle->functions->fetch_values(key, - &key->cache_values_count, &key->cache_values); - - if(idx < key->cache_values_count && idx >= 0) { - *val = reg_val_dup(key->cache_values[idx]); - } else { - return WERR_NO_MORE_ITEMS; - } } else { return WERR_NOT_SUPPORTED; } (*val)->parent = key; - (*val)->handle = key->handle; + (*val)->hive = key->hive; return WERR_OK; } -WERROR reg_key_num_subkeys(REG_KEY *key, int *count) +WERROR reg_key_num_subkeys(struct registry_key *key, int *count) { if(!key) return WERR_INVALID_PARAM; - if(key->handle->functions->num_subkeys) { - return key->handle->functions->num_subkeys(key, count); + if(key->hive->functions->num_subkeys) { + return key->hive->functions->num_subkeys(key, count); } - if(key->handle->functions->fetch_subkeys) { - if(!key->cache_subkeys) - key->handle->functions->fetch_subkeys(key, - &key->cache_subkeys_count, &key->cache_subkeys); - - *count = key->cache_subkeys_count; - return WERR_OK; - } - - if(key->handle->functions->get_subkey_by_index) { + if(key->hive->functions->get_subkey_by_index) { int i; WERROR error; - REG_KEY *dest; - for(i = 0; W_ERROR_IS_OK(error = key->handle->functions->get_subkey_by_index(key, i, &dest)); i++) { - reg_key_free(dest); - } + struct registry_key *dest; + TALLOC_CTX *mem_ctx = talloc_init("num_subkeys"); + + for(i = 0; W_ERROR_IS_OK(error = key->hive->functions->get_subkey_by_index(mem_ctx, key, i, &dest)); i++); + talloc_destroy(mem_ctx); *count = i; if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) return WERR_OK; @@ -281,74 +318,49 @@ WERROR reg_key_num_subkeys(REG_KEY *key, int *count) return WERR_NOT_SUPPORTED; } -WERROR reg_key_num_values(REG_KEY *key, int *count) +WERROR reg_key_num_values(struct registry_key *key, int *count) { if(!key) return WERR_INVALID_PARAM; - if(!key->handle->functions->num_values) { - if(!key->handle->functions->fetch_values) { - DEBUG(1, ("Backend '%s' doesn't support enumerating values\n", key->handle->functions->name)); - return WERR_NOT_SUPPORTED; - } - - if(!key->cache_values) - key->handle->functions->fetch_values(key, &key->cache_values_count, &key->cache_values); - - *count = key->cache_values_count; - return WERR_OK; - } - - - return key->handle->functions->num_values(key, count); + return key->hive->functions->num_values(key, count); } -WERROR reg_key_get_subkey_by_index(REG_KEY *key, int idx, REG_KEY **subkey) +WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key *key, int idx, struct registry_key **subkey) { if(!key) return WERR_INVALID_PARAM; - if(key->handle->functions->get_subkey_by_index) { - WERROR status = key->handle->functions->get_subkey_by_index(key, idx, subkey); + if(key->hive->functions->get_subkey_by_index) { + WERROR status = key->hive->functions->get_subkey_by_index(mem_ctx, key, idx, subkey); if(!NT_STATUS_IS_OK(status)) return status; - } else if(key->handle->functions->fetch_subkeys) { - if(!key->cache_subkeys) - key->handle->functions->fetch_subkeys(key, - &key->cache_subkeys_count, &key->cache_subkeys); - - if(idx < key->cache_subkeys_count) { - *subkey = reg_key_dup(key->cache_subkeys[idx]); - } else { - return WERR_NO_MORE_ITEMS; - } } else { return WERR_NOT_SUPPORTED; } - (*subkey)->path = talloc_asprintf((*subkey)->mem_ctx, "%s\\%s", - reg_key_get_path_abs(key), (*subkey)->name); - (*subkey)->handle = key->handle; - (*subkey)->hive = key->hive; - + if(key->hive->root == key) + (*subkey)->path = talloc_strdup(mem_ctx, (*subkey)->name); + else + (*subkey)->path = talloc_asprintf(mem_ctx, "%s\\%s", key->path, (*subkey)->name); + (*subkey)->hive = key->hive; return WERR_OK;; } -WERROR reg_key_get_subkey_by_name(REG_KEY *key, const char *name, REG_KEY **subkey) +WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key, const char *name, struct registry_key **subkey) { int i; WERROR error = WERR_OK; if(!key) return WERR_INVALID_PARAM; - if(key->handle->functions->get_subkey_by_name) { - error = key->handle->functions->get_subkey_by_name(key,name,subkey); - } else if(key->handle->functions->get_subkey_by_index || key->handle->functions->fetch_subkeys) { + if(key->hive->functions->get_subkey_by_name) { + error = key->hive->functions->get_subkey_by_name(mem_ctx, key,name,subkey); + } else if(key->hive->functions->get_subkey_by_index) { for(i = 0; W_ERROR_IS_OK(error); i++) { - error = reg_key_get_subkey_by_index(key, i, subkey); + error = reg_key_get_subkey_by_index(mem_ctx, key, i, subkey); if(W_ERROR_IS_OK(error) && !strcmp((*subkey)->name, name)) { return error; } - reg_key_free(*subkey); } } else { return WERR_NOT_SUPPORTED; @@ -356,29 +368,27 @@ WERROR reg_key_get_subkey_by_name(REG_KEY *key, const char *name, REG_KEY **subk if(!W_ERROR_IS_OK(error)) return error; - (*subkey)->path = talloc_asprintf((*subkey)->mem_ctx, "%s\\%s", reg_key_get_path_abs(key), (*subkey)->name); - (*subkey)->handle = key->handle; + (*subkey)->path = talloc_asprintf(mem_ctx, "%s\\%s", key->path, (*subkey)->name); (*subkey)->hive = key->hive; return WERR_OK; } -WERROR reg_key_get_value_by_name(REG_KEY *key, const char *name, REG_VAL **val) +WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key, const char *name, struct registry_value **val) { int i; WERROR error = WERR_OK; if(!key) return WERR_INVALID_PARAM; - if(key->handle->functions->get_value_by_name) { - error = key->handle->functions->get_value_by_name(key,name, val); + if(key->hive->functions->get_value_by_name) { + error = key->hive->functions->get_value_by_name(mem_ctx, key,name, val); } else { for(i = 0; W_ERROR_IS_OK(error); i++) { - error = reg_key_get_value_by_index(key, i, val); + error = reg_key_get_value_by_index(mem_ctx, key, i, val); if(W_ERROR_IS_OK(error) && StrCaseCmp((*val)->name, name)) { break; } - reg_val_free(*val); } } @@ -386,52 +396,49 @@ WERROR reg_key_get_value_by_name(REG_KEY *key, const char *name, REG_VAL **val) return error; (*val)->parent = key; - (*val)->handle = key->handle; + (*val)->hive = key->hive; return WERR_OK; } -WERROR reg_key_del(REG_KEY *key) +WERROR reg_key_del(struct registry_key *key) { WERROR error; if(!key) return WERR_INVALID_PARAM; - if(!key->handle->functions->del_key) + if(!key->hive->functions->del_key) return WERR_NOT_SUPPORTED; - error = key->handle->functions->del_key(key); + error = key->hive->functions->del_key(key); if(!W_ERROR_IS_OK(error)) return error; - /* Invalidate cache */ - key->cache_subkeys = NULL; - key->cache_subkeys_count = 0; return WERR_OK; } -WERROR reg_sync(REG_KEY *h, const char *location) -{ - if(!h->handle->functions->sync_key) - return WERR_OK; - - return h->handle->functions->sync_key(h, location); -} - -WERROR reg_key_del_recursive(REG_KEY *key) +WERROR reg_key_del_recursive(struct registry_key *key) { WERROR error = WERR_OK; int i; + + TALLOC_CTX *mem_ctx = talloc_init("del_recursive"); /* Delete all values for specified key */ for(i = 0; W_ERROR_IS_OK(error); i++) { - REG_VAL *val; - error = reg_key_get_value_by_index(key, i, &val); + struct registry_value *val; + error = reg_key_get_value_by_index(mem_ctx, key, i, &val); if(!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) + { + talloc_destroy(mem_ctx); return error; + } if(W_ERROR_IS_OK(error)) { - error = reg_val_del(val); - if(!W_ERROR_IS_OK(error)) return error; + error = reg_del_value(val); + if(!W_ERROR_IS_OK(error)) { + talloc_destroy(mem_ctx); + return error; + } } } @@ -439,204 +446,150 @@ WERROR reg_key_del_recursive(REG_KEY *key) /* Delete all keys below this one */ for(i = 0; W_ERROR_IS_OK(error); i++) { - REG_KEY *subkey; + struct registry_key *subkey; - error = reg_key_get_subkey_by_index(key, i, &subkey); - if(!W_ERROR_IS_OK(error)) return error; + error = reg_key_get_subkey_by_index(mem_ctx, key, i, &subkey); + if(!W_ERROR_IS_OK(error)) { talloc_destroy(mem_ctx); return error; } error = reg_key_del_recursive(subkey); - if(!W_ERROR_IS_OK(error)) return error; + if(!W_ERROR_IS_OK(error)) { talloc_destroy(mem_ctx); return error; } } + talloc_destroy(mem_ctx); return reg_key_del(key); } -WERROR reg_val_del(REG_VAL *val) -{ - WERROR error; - if (!val) return WERR_INVALID_PARAM; - - if (!val->handle->functions->del_value) { - DEBUG(1, ("Backend '%s' doesn't support method del_value\n", val->handle->functions->name)); - return WERR_NOT_SUPPORTED; - } - - error = val->handle->functions->del_value(val); - - if(!W_ERROR_IS_OK(error)) return error; - - val->parent->cache_values = NULL; - val->parent->cache_values_count = 0; - - return WERR_OK; -} - -WERROR reg_key_add_name_recursive_abs(REG_HANDLE *handle, const char *name) +WERROR reg_key_add_name_recursive_abs(struct registry_context *handle, const char *name) { - REG_KEY *hive; + struct registry_key *hive; WERROR error; - int i, hivelength; + int hivelength; + char *hivename; if(strchr(name, '\\')) hivelength = strchr(name, '\\')-name; else hivelength = strlen(name); - for(i = 0; W_ERROR_IS_OK(error); i++) { - error = reg_get_hive(handle, i, &hive); - if(W_ERROR_IS_OK(error) && !strncmp(reg_key_name(hive), name, hivelength)) { - return reg_key_add_name_recursive(hive, name); - } - } + hivename = strndup(name, hivelength); + error = reg_get_hive(handle, hivename, &hive); + SAFE_FREE(hivename); - return error; + if(!W_ERROR_IS_OK(error)) return error; + + return reg_key_add_name_recursive(hive, name); } -WERROR reg_key_add_name_recursive(REG_KEY *parent, const char *path) +WERROR reg_key_add_name_recursive(struct registry_key *parent, const char *path) { - REG_KEY *cur, *prevcur = parent; - WERROR error; - /* FIXME: we should never write to a 'const char *' !!! --metze */ - char *begin = (char *)path, *end; + struct registry_key *cur, *prevcur = parent; + WERROR error = WERR_OK; + char *dup, *begin, *end; + TALLOC_CTX *mem_ctx = talloc_init("add_recursive"); + + begin = dup = strdup(path); while(1) { end = strchr(begin, '\\'); if(end) *end = '\0'; - error = reg_key_get_subkey_by_name(prevcur, begin, &cur); + error = reg_key_get_subkey_by_name(mem_ctx, prevcur, begin, &cur); /* Key is not there, add it */ if(W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) { - error = reg_key_add_name(prevcur, begin, 0, NULL, &cur); - if(!W_ERROR_IS_OK(error)) return error; + error = reg_key_add_name(mem_ctx, prevcur, begin, 0, NULL, &cur); + if(!W_ERROR_IS_OK(error)) break; } if(!W_ERROR_IS_OK(error)) { if(end) *end = '\\'; - return error; + break; } - if(!end) break; + if(!end) { + error = WERR_OK; + break; + } + *end = '\\'; begin = end+1; prevcur = cur; } - return WERR_OK; + SAFE_FREE(dup); + talloc_destroy(mem_ctx); + return error; } -WERROR reg_key_add_name(REG_KEY *parent, const char *name, uint32_t access_mask, SEC_DESC *desc, REG_KEY **newkey) +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 error; if (!parent) return WERR_INVALID_PARAM; - if (!parent->handle->functions->add_key) { - DEBUG(1, ("Backend '%s' doesn't support method add_key\n", parent->handle->functions->name)); + if (!parent->hive->functions->add_key) { + DEBUG(1, ("Backend '%s' doesn't support method add_key\n", parent->hive->functions->name)); return WERR_NOT_SUPPORTED; } - error = parent->handle->functions->add_key(parent, name, access_mask, desc, newkey); + error = parent->hive->functions->add_key(mem_ctx, parent, name, access_mask, desc, newkey); if(!W_ERROR_IS_OK(error)) return error; - (*newkey)->handle = parent->handle; - (*newkey)->backend_data = talloc_asprintf((*newkey)->mem_ctx, "%s\\%s", reg_key_get_path(parent), name); + (*newkey)->hive = parent->hive; + (*newkey)->backend_data = talloc_asprintf(mem_ctx, "%s\\%s", parent->path, name); - parent->cache_subkeys = NULL; - parent->cache_subkeys_count = 0; return WERR_OK; } -WERROR reg_val_update(REG_VAL *val, int type, void *data, int len) +WERROR reg_val_set(struct registry_key *key, const char *value, int type, void *data, int len) { - WERROR error; - - /* A 'real' update function has preference */ - if (val->handle->functions->update_value) - return val->handle->functions->update_value(val, type, data, len); - - /* Otherwise, just remove and add again */ - if (val->handle->functions->add_value && - val->handle->functions->del_value) { - REG_VAL *new; - if(!W_ERROR_IS_OK(error = val->handle->functions->del_value(val))) - return error; - - error = val->handle->functions->add_value(val->parent, val->name, type, data, len); - if(!W_ERROR_IS_OK(error)) return error; - memcpy(val, new, sizeof(REG_VAL)); - val->parent->cache_values = NULL; - val->parent->cache_values_count = 0; - return WERR_OK; - } - - DEBUG(1, ("Backend '%s' doesn't support method update_value\n", val->handle->functions->name)); - return WERR_NOT_SUPPORTED; -} - -void reg_free(REG_HANDLE *h) -{ - if(!h->functions->close_registry) return; + /* A 'real' set function has preference */ + if (key->hive->functions->set_value) + return key->hive->functions->set_value(key, value, type, data, len); - h->functions->close_registry(h); + DEBUG(1, ("Backend '%s' doesn't support method set_value\n", key->hive->functions->name)); + return WERR_NOT_SUPPORTED; } -WERROR reg_get_hive(REG_HANDLE *h, int hivenum, REG_KEY **key) +WERROR reg_get_hive(struct registry_context *h, const char *name, struct registry_key **key) { - WERROR ret; - - if(h->functions->get_hive) { - ret = h->functions->get_hive(h, hivenum, key); - } else if(h->functions->open_key) { - if(hivenum == 0) ret = h->functions->open_key(h, hivenum, "", key); - else ret = WERR_NO_MORE_ITEMS; - } else { - DEBUG(0, ("Backend '%s' has neither open_root_key nor open_key or get_hive method implemented\n", h->functions->name)); - ret = WERR_NOT_SUPPORTED; - } - - if(W_ERROR_IS_OK(ret)) { - (*key)->handle = h; - if(!(*key)->path) { - (*key)->path = talloc_strdup((*key)->mem_ctx, (*key)->name); + int i; + for(i = 0; i < h->num_hives; i++) + { + if(!strcmp(h->hives[i]->name, name)) { + *key = h->hives[i]->root; + return WERR_OK; } - (*key)->hive = hivenum; } - return ret; + return WERR_NO_MORE_ITEMS; } -WERROR reg_key_add_value(REG_KEY *key, const char *name, int type, void *value, size_t vallen) +WERROR reg_del_value(struct registry_value *val) { WERROR ret = WERR_OK; - if(!key->handle->functions->add_value) + if(!val->hive->functions->del_value) return WERR_NOT_SUPPORTED; - ret = key->handle->functions->add_value(key, name, type, value, vallen); + ret = val->hive->functions->del_value(val); if(!W_ERROR_IS_OK(ret)) return ret; - /* Invalidate the cache */ - key->cache_values = NULL; - key->cache_values_count = 0; return ret; } -WERROR reg_save(REG_HANDLE *h, const char *location) +WERROR reg_save(struct registry_context *h, const char *location) { /* FIXME */ return WERR_NOT_SUPPORTED; } -WERROR reg_key_get_parent(REG_KEY *key, REG_KEY **parent) +WERROR reg_key_get_parent(TALLOC_CTX *mem_ctx, struct registry_key *key, struct registry_key **parent) { char *parent_name; char *last; - REG_KEY *root; + struct registry_key *root; WERROR error; - error = reg_get_hive(key->handle, key->hive, &root); - if(!W_ERROR_IS_OK(error)) return error; - - parent_name = strdup(reg_key_get_path(key)); + parent_name = strdup(key->path); last = strrchr(parent_name, '\\'); if(!last) { @@ -645,7 +598,7 @@ WERROR reg_key_get_parent(REG_KEY *key, REG_KEY **parent) } *last = '\0'; - error = reg_open_key(root, parent_name, parent); + error = reg_open_key(mem_ctx, root, parent_name, parent); SAFE_FREE(parent_name); return error; } diff --git a/source4/lib/registry/common/reg_objects.c b/source4/lib/registry/common/reg_objects.c deleted file mode 100644 index d911b4650b..0000000000 --- a/source4/lib/registry/common/reg_objects.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * RPC Pipe client / server routines - * Copyright (C) Gerald Carter 2002. - * Copyright (C) Jelmer Vernooij 2003-2004. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* Implementation of registry frontend view functions. */ - -#include "includes.h" -#include "lib/registry/common/registry.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - -/*********************************************************************** - allocate memory for and duplicate a REG_VAL. - This is malloc'd memory so the caller should free it when done - **********************************************************************/ - -REG_VAL* reg_val_dup( REG_VAL *val ) -{ - val->ref++; - return val; -} - -/********************************************************************** - free the memory allocated to a REG_VAL - *********************************************************************/ - -void reg_val_free( REG_VAL *val ) -{ - if ( !val ) - return; - - val->ref--; - if(val->ref) return; - - if(val->handle->functions->free_val_backend_data) - val->handle->functions->free_val_backend_data(val); - - talloc_destroy( val->mem_ctx ); - - return; -} - -/********************************************************************** - *********************************************************************/ - -uint8_t * reg_val_data_blk( REG_VAL *val ) -{ - return val->data_blk; -} - -/********************************************************************** - *********************************************************************/ - -int reg_val_size( REG_VAL *val ) -{ - return val->data_len; -} - -/********************************************************************** - *********************************************************************/ - -char *reg_val_name( REG_VAL *val ) -{ - return val->name; -} - -/********************************************************************** - *********************************************************************/ - -uint32_t reg_val_type( REG_VAL *val ) -{ - return val->data_type; -} - -/********************************************************************** - *********************************************************************/ - -REG_HANDLE *reg_key_handle (REG_KEY *key) -{ - return key->handle; -} - -char *reg_key_name( REG_KEY *key ) -{ - return key->name; -} - -char *reg_key_class( REG_KEY *key ) -{ - return key->class_name; -} - -NTTIME reg_key_last_modified( REG_KEY *key ) -{ - return key->last_mod; -} - -REG_KEY *reg_key_dup(REG_KEY *key) -{ - key->ref++; - return key; -} - -void reg_key_free(REG_KEY *key) -{ - if(!key) - return; - - key->ref--; - if(key->ref) return; - - if(key->handle->functions->free_key_backend_data) - key->handle->functions->free_key_backend_data(key); - - if(key->cache_values) { - int i; - for(i = 0; i < key->cache_values_count; i++) { - reg_val_free(key->cache_values[i]); - } - } - - if(key->cache_subkeys) { - int i; - for(i = 0; i < key->cache_subkeys_count; i++) { - reg_key_free(key->cache_subkeys[i]); - } - } - - talloc_destroy(key->mem_ctx); -} - -char *reg_val_get_path(REG_VAL *v) -{ - /* FIXME */ - return NULL; -} - -const char *reg_key_get_path(REG_KEY *k) -{ - SMB_REG_ASSERT(k); - return strchr(k->path, '\\')?strchr(k->path, '\\')+1:""; -} - -const char *reg_key_get_path_abs(REG_KEY *k) -{ - SMB_REG_ASSERT(k); - return k->path; -} - -/* For use by the backends _ONLY_ */ -REG_KEY *reg_key_new_abs(const char *path, REG_HANDLE *h, void *data) -{ - REG_KEY *r; - TALLOC_CTX *mem_ctx = talloc_init(path); - r = talloc(mem_ctx, sizeof(REG_KEY)); - ZERO_STRUCTP(r); - r->handle = h; - r->mem_ctx = mem_ctx; - r->path = talloc_strdup(mem_ctx, path); - r->name = talloc_strdup(mem_ctx, strrchr(path, '\\')?strrchr(path,'\\')+1:path); - r->backend_data = data; - r->ref = 1; - return r; -} - -REG_KEY *reg_key_new_rel(const char *name, REG_KEY *k, void *data) -{ - REG_KEY *r; - const char *parent_path = k?reg_key_get_path(k):""; - TALLOC_CTX *mem_ctx = talloc_init(name); - r = talloc(mem_ctx, sizeof(REG_KEY)); - ZERO_STRUCTP(r); - r->handle = k->handle; - r->hive = k->hive; - r->name = talloc_strdup(mem_ctx, name); - - r->path = talloc_asprintf(mem_ctx, "%s%s%s", parent_path, *parent_path && parent_path[strlen(parent_path)-1] != '\\'?"\\":"", name); - r->backend_data = data; - r->mem_ctx = mem_ctx; - r->ref = 1; - return r; -} - -REG_VAL *reg_val_new(REG_KEY *parent, void *data) -{ - REG_VAL *r; - TALLOC_CTX *mem_ctx = talloc_init("value"); - r = talloc(mem_ctx, sizeof(REG_VAL)); - ZERO_STRUCTP(r); - r->mem_ctx = mem_ctx; - r->handle = parent->handle; - r->backend_data = data; - r->ref = 1; - return r; -} diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index db5e97bf7f..21c925deab 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -34,90 +34,68 @@ const char *str_regtype(int type) return "Unknown"; } -char *reg_val_data_string(REG_VAL *v) +char *reg_val_data_string(TALLOC_CTX *mem_ctx, struct registry_value *v) { char *asciip; char *ret = NULL; int i; - if(reg_val_size(v) == 0) return strdup(""); + if(v->data_len == 0) return talloc_strdup(mem_ctx, ""); - switch (reg_val_type(v)) { + switch (v->data_type) { case REG_SZ: - /* FIXME: Convert to ascii */ - return strndup(reg_val_data_blk(v), reg_val_size(v)); + return talloc_strndup(mem_ctx, v->data_blk, v->data_len); case REG_EXPAND_SZ: - return strndup(reg_val_data_blk(v), reg_val_size(v)); + return talloc_strndup(mem_ctx, v->data_blk, v->data_len); case REG_BINARY: - ret = malloc(reg_val_size(v) * 3 + 2); + ret = talloc(mem_ctx, v->data_len * 3 + 2); asciip = ret; - for (i=0; i 0) + for (i=0; idata_len; i++) { + int str_rem = v->data_len * 3 - (asciip - ret); + asciip += snprintf(asciip, str_rem, "%02x", *(uint8_t *)(v->data_blk+i)); + if (i < v->data_len && str_rem > 0) *asciip = ' '; asciip++; } *asciip = '\0'; return ret; - break; case REG_DWORD: - if (*(int *)reg_val_data_blk(v) == 0) - ret = strdup("0"); - else - asprintf(&ret, "0x%x", *(int *)reg_val_data_blk(v)); - break; + if (*(int *)v->data_blk == 0) + return talloc_strdup(mem_ctx, "0"); + + return talloc_asprintf(mem_ctx, "0x%x", *(int *)v->data_blk); case REG_MULTI_SZ: /* FIXME */ break; default: - return 0; break; } return ret; } -char *reg_val_description(REG_VAL *val) +char *reg_val_description(TALLOC_CTX *mem_ctx, struct registry_value *val) { - char *ret, *ds = reg_val_data_string(val); - asprintf(&ret, "%s = %s : %s", reg_val_name(val)?reg_val_name(val):"", str_regtype(reg_val_type(val)), ds); - free(ds); - return ret; + 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(REG_VAL *val, char *str) +BOOL reg_val_set_string(struct registry_value *val, char *str) { /* FIXME */ return False; } -WERROR reg_key_get_subkey_val(REG_KEY *key, const char *subname, const char *valname, REG_VAL **val) +WERROR reg_key_get_subkey_val(TALLOC_CTX *mem_ctx, struct registry_key *key, const char *subname, const char *valname, struct registry_value **val) { - REG_KEY *k; - WERROR error = reg_key_get_subkey_by_name(key, subname, &k); - if(!W_ERROR_IS_OK(error)) return error; - - return reg_key_get_value_by_name(k, valname, val); -} - -WERROR reg_key_set_subkey_val(REG_KEY *key, const char *subname, const char *valname, uint32_t type, uint8_t *data, int real_len) -{ - REG_KEY *k; - REG_VAL *v; - WERROR error; - - error = reg_key_get_subkey_by_name(key, subname, &k); - if(!W_ERROR_IS_OK(error)) return error; - - error = reg_key_get_value_by_name(k, valname, &v); + struct registry_key *k; + WERROR error = reg_key_get_subkey_by_name(mem_ctx, key, subname, &k); if(!W_ERROR_IS_OK(error)) return error; - return reg_val_update(v, type, data, real_len); + return reg_key_get_value_by_name(mem_ctx, k, valname, val); } /*********************************************************************** diff --git a/source4/lib/registry/common/registry.h b/source4/lib/registry/common/registry.h deleted file mode 100644 index 89d0ac6b14..0000000000 --- a/source4/lib/registry/common/registry.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Registry interface - This file contains the _internal_ structs for the registry - subsystem. Backends and the subsystem itself are the only - files that need to include this file. - Copyright (C) Gerald Carter 2002. - Copyright (C) Jelmer Vernooij 2003-2004. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef _REGISTRY_REGISTRY_H /* _REGISTRY_REGISTRY_H */ -#define _REGISTRY_REGISTRY_H - -#define REGISTRY_INTERFACE_VERSION 1 - -/* structure to store the registry handles */ -struct reg_key_s { - char *name; /* Name of the key */ - char *path; /* Full path to the key */ - char *class_name; /* Name of key class */ - NTTIME last_mod; /* Time last modified */ - SEC_DESC *security; - REG_HANDLE *handle; - void *backend_data; - REG_VAL **cache_values; - int cache_values_count; - REG_KEY **cache_subkeys; - int cache_subkeys_count; - int hive; - TALLOC_CTX *mem_ctx; - int ref; -}; - -struct reg_val_s { - char *name; - int has_name; - int data_type; - int data_len; - void *data_blk; /* Might want a separate block */ - REG_HANDLE *handle; - REG_KEY *parent; - void *backend_data; - TALLOC_CTX *mem_ctx; - int ref; -}; - -/* FIXME */ -typedef void (*key_notification_function) (void); -typedef void (*value_notification_function) (void); - -/* - * Container for function pointers to enumeration routines - * for virtual registry view - * - * Backends can provide : - * - just one hive (example: nt4, w95) - * - several hives (example: rpc) - * - */ - -struct registry_ops { - const char *name; - WERROR (*open_registry) (REG_HANDLE *, const char *location, const char *credentials); - WERROR (*sync_key)(REG_KEY *, const char *location); - WERROR (*close_registry) (REG_HANDLE *); - - /* Implement this one */ - WERROR (*get_hive) (REG_HANDLE *, int , REG_KEY **); - - /* Or this one */ - WERROR (*open_key) (REG_HANDLE *, int hive, const char *name, REG_KEY **); - - /* Either implement these */ - WERROR (*num_subkeys) (REG_KEY *, int *count); - WERROR (*num_values) (REG_KEY *, int *count); - WERROR (*get_subkey_by_index) (REG_KEY *, int idx, REG_KEY **); - /* Can not contain more then one level */ - WERROR (*get_subkey_by_name) (REG_KEY *, const char *name, REG_KEY **); - WERROR (*get_value_by_index) (REG_KEY *, int idx, REG_VAL **); - /* Can not contain more then one level */ - WERROR (*get_value_by_name) (REG_KEY *, const char *name, REG_VAL **); - - /* Or these */ - WERROR (*fetch_subkeys) (REG_KEY *, int *count, REG_KEY ***); - WERROR (*fetch_values) (REG_KEY *, int *count, REG_VAL ***); - - /* Security control */ - WERROR (*key_get_sec_desc) (REG_KEY *, SEC_DESC **); - WERROR (*key_set_sec_desc) (REG_KEY *, SEC_DESC *); - - /* Notification */ - WERROR (*request_key_change_notify) (REG_KEY *, key_notification_function); - WERROR (*request_value_change_notify) (REG_VAL *, value_notification_function); - - /* Key management */ - WERROR (*add_key)(REG_KEY *, const char *name, uint32_t access_mask, SEC_DESC *, REG_KEY **); - WERROR (*del_key)(REG_KEY *); - - /* Value management */ - WERROR (*add_value)(REG_KEY *, const char *name, int type, void *data, int len); - WERROR (*del_value)(REG_VAL *); - - /* If update is not available, value will first be deleted and then added - * again */ - WERROR (*update_value)(REG_VAL *, int type, void *data, int len); - - void (*free_key_backend_data) (REG_KEY *); - void (*free_val_backend_data) (REG_VAL *); -}; - -struct reg_handle_s { - const struct registry_ops *functions; - char *location; - char *credentials; - void *backend_data; - TALLOC_CTX *mem_ctx; -}; - -struct reg_init_function_entry { - /* Function to create a member of the pdb_methods list */ - const struct registry_ops *functions; - struct reg_init_function_entry *prev, *next; -}; - -/* Used internally */ -#define SMB_REG_ASSERT(a) { if(!(a)) { DEBUG(0,("%s failed! (%s:%d)", #a, __FILE__, __LINE__)); }} - -#endif /* _REGISTRY_H */ diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 8100c798e6..659e705d5d 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -60,7 +60,6 @@ REQUIRED_SUBSYSTEMS = \ INIT_OBJ_FILES = \ lib/registry/common/reg_interface.o ADD_OBJ_FILES = \ - lib/registry/common/reg_objects.o \ lib/registry/common/reg_util.o REQUIRED_SUBSYSTEMS = \ LIBBASIC 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 b2bd34bf71..95d4c47af0 100644 --- a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c @@ -19,13 +19,12 @@ */ #include "includes.h" -#include "lib/registry/common/registry.h" -static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32_t access_mask, SEC_DESC *desc, REG_KEY **result) +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) { char *path; int ret; - asprintf(&path, "%s%s\\%s", parent->handle->location, reg_key_get_path(parent), name); + asprintf(&path, "%s%s\\%s", parent->hive->location, parent->path, name); path = reg_path_win2unix(path); ret = mkdir(path, 0700); SAFE_FREE(path); @@ -33,19 +32,16 @@ static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32_t access return WERR_INVALID_PARAM; } -static WERROR reg_dir_del_key(REG_KEY *k) +static WERROR reg_dir_del_key(struct registry_key *k) { return (rmdir((char *)k->backend_data) == 0)?WERR_OK:WERR_GENERAL_FAILURE; } -static WERROR reg_dir_open_key(REG_HANDLE *h, int hive, const char *name, REG_KEY **subkey) +static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **subkey) { DIR *d; char *fullpath; - REG_KEY *ret; - TALLOC_CTX *mem_ctx; - - if(hive != 0) return WERR_NO_MORE_ITEMS; + struct registry_key *ret; if(!name) { DEBUG(0, ("NULL pointer passed as directory name!")); @@ -53,33 +49,28 @@ static WERROR reg_dir_open_key(REG_HANDLE *h, int hive, const char *name, REG_KE } - mem_ctx = talloc_init("tmp"); fullpath = talloc_asprintf(mem_ctx, "%s%s", h->location, name); fullpath = reg_path_win2unix(fullpath); d = opendir(fullpath); if(!d) { DEBUG(3,("Unable to open '%s': %s\n", fullpath, strerror(errno))); - talloc_destroy(mem_ctx); return WERR_BADFILE; } closedir(d); - ret = reg_key_new_abs(name, h, fullpath); - talloc_steal(ret->mem_ctx, fullpath); - talloc_destroy(mem_ctx); + ret = talloc_p(mem_ctx, struct registry_key); + ret->hive = h; + ret->path = fullpath; *subkey = ret; return WERR_OK; } -static WERROR reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r) +static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_key **key) { struct dirent *e; - int max = 200; char *fullpath = k->backend_data; - REG_KEY **ar; + int i = 0; DIR *d; - (*count) = 0; - ar = talloc(k->mem_ctx, sizeof(REG_KEY *) * max); d = opendir(fullpath); @@ -96,13 +87,15 @@ static WERROR reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r) stat(thispath, &stbuf); if(S_ISDIR(stbuf.st_mode)) { - ar[(*count)] = reg_key_new_rel(e->d_name, k, NULL); - ar[(*count)]->backend_data = talloc_strdup(ar[*count]->mem_ctx, thispath); - if(ar[(*count)])(*count)++; - - if((*count) == max) { - max+=200; - ar = realloc(ar, sizeof(REG_KEY *) * max); + i++; + if(i == idx) { + (*key) = talloc_p(mem_ctx, struct registry_key); + (*key)->name = e->d_name; + (*key)->path = NULL; + (*key)->backend_data = talloc_strdup(mem_ctx, thispath); + SAFE_FREE(thispath); + closedir(d); + return WERR_OK; } } @@ -112,44 +105,38 @@ static WERROR reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r) closedir(d); - *r = ar; - return WERR_OK; + return WERR_NO_MORE_ITEMS; } -static WERROR reg_dir_open(REG_HANDLE *h, const char *loc, const char *credentials) { - if(!loc) return WERR_INVALID_PARAM; +static WERROR reg_dir_open(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **key) +{ + if(!h->location) return WERR_INVALID_PARAM; + + *key = talloc_p(mem_ctx, struct registry_key); + (*key)->backend_data = talloc_strdup(mem_ctx, h->location); return WERR_OK; } -static WERROR reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len) +static WERROR reg_dir_set_value(struct registry_key *p, const char *name, int type, void *data, int len) { /* FIXME */ return WERR_NOT_SUPPORTED; } -static WERROR reg_dir_get_hive(REG_HANDLE *h, int hive, REG_KEY **key) -{ - if(hive != 0) return WERR_NO_MORE_ITEMS; - *key = reg_key_new_abs("", h, NULL); - (*key)->backend_data = talloc_strdup((*key)->mem_ctx, h->location); - return WERR_OK; -} - -static WERROR reg_dir_del_value(REG_VAL *v) +static WERROR reg_dir_del_value(struct registry_value *v) { /* FIXME*/ return WERR_NOT_SUPPORTED; } -static struct registry_ops reg_backend_dir = { +static struct registry_operations reg_backend_dir = { .name = "dir", - .open_registry = reg_dir_open, + .open_hive = reg_dir_open, .open_key = reg_dir_open_key, - .get_hive = reg_dir_get_hive, - .fetch_subkeys = reg_dir_fetch_subkeys, .add_key = reg_dir_add_key, .del_key = reg_dir_del_key, - .add_value = reg_dir_add_value, + .get_subkey_by_index = reg_dir_key_by_index, + .set_value = reg_dir_set_value, .del_value = reg_dir_del_value, }; diff --git a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c index 15a8319711..d8c8d951c1 100644 --- a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c +++ b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c @@ -19,7 +19,6 @@ */ #include "includes.h" -#include "lib/registry/common/registry.h" #include static WERROR gerror_to_werror(GError *error) @@ -29,33 +28,24 @@ static WERROR gerror_to_werror(GError *error) return WERR_FOOBAR; } -static WERROR reg_open_gconf(REG_HANDLE *h, const char *location, const char *credentials) +static WERROR reg_open_gconf_hive(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **k) { + g_type_init(); h->backend_data = (void *)gconf_client_get_default(); if(!h->backend_data) return WERR_FOOBAR; + + *k = talloc_p(mem_ctx, struct registry_key); + (*k)->name = ""; + (*k)->path = ""; + (*k)->backend_data = talloc_strdup(mem_ctx, "/"); return WERR_OK; } -static WERROR reg_close_gconf(REG_HANDLE *h) -{ - return WERR_OK; -} - -static WERROR gconf_get_hive (REG_HANDLE *h, int hivenum, REG_KEY **key) -{ - if(hivenum != 0) return WERR_NO_MORE_ITEMS; - *key = reg_key_new_abs("", h, NULL); - (*key)->backend_data = talloc_strdup((*key)->mem_ctx, "/"); - return WERR_OK; -} - -static WERROR gconf_open_key (REG_HANDLE *h, int hivenum, const char *name, REG_KEY **key) +static WERROR gconf_open_key (TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **key) { - REG_KEY *ret; + struct registry_key *ret; char *fullpath; - if(hivenum != 0) return WERR_NO_MORE_ITEMS; - fullpath = reg_path_win2unix(strdup(name)); /* Check if key exists */ @@ -63,143 +53,134 @@ static WERROR gconf_open_key (REG_HANDLE *h, int hivenum, const char *name, REG_ SAFE_FREE(fullpath); return WERR_DEST_NOT_FOUND; } - ret = reg_key_new_abs(name, h, NULL); - ret->backend_data = talloc_strdup(ret->mem_ctx, fullpath); + + ret = talloc_p(mem_ctx, struct registry_key); + ret->backend_data = talloc_strdup(mem_ctx, fullpath); SAFE_FREE(fullpath); *key = ret; return WERR_OK; } -static WERROR gconf_fetch_values(REG_KEY *p, int *count, REG_VAL ***vals) +static WERROR gconf_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *p, int idx, struct registry_value **val) { GSList *entries; GSList *cur; - REG_VAL **ar = talloc(p->mem_ctx, sizeof(REG_VAL *)); + GConfEntry *entry; + GConfValue *value; + struct registry_value *newval; char *fullpath = p->backend_data; - cur = entries = gconf_client_all_entries((GConfClient*)p->handle->backend_data, fullpath, NULL); - - (*count) = 0; - while(cur) { - GConfEntry *entry = cur->data; - GConfValue *value = gconf_entry_get_value(entry); - REG_VAL *newval = reg_val_new(p, NULL); - newval->name = talloc_strdup(newval->mem_ctx, strrchr(gconf_entry_get_key(entry), '/')+1); - if(value) { - switch(value->type) { - case GCONF_VALUE_INVALID: - newval->data_type = REG_NONE; - break; - - case GCONF_VALUE_STRING: - newval->data_type = REG_SZ; - newval->data_blk = talloc_strdup(newval->mem_ctx, gconf_value_get_string(value)); - newval->data_len = strlen(newval->data_blk); - break; - - case GCONF_VALUE_INT: - newval->data_type = REG_DWORD; - newval->data_blk = talloc(newval->mem_ctx, sizeof(long)); - *((long *)newval->data_blk) = gconf_value_get_int(value); - newval->data_len = sizeof(long); - break; - - case GCONF_VALUE_FLOAT: - newval->data_blk = talloc(newval->mem_ctx, sizeof(double)); - newval->data_type = REG_BINARY; - *((double *)newval->data_blk) = gconf_value_get_float(value); - newval->data_len = sizeof(double); - break; - - case GCONF_VALUE_BOOL: - newval->data_blk = talloc(newval->mem_ctx, sizeof(BOOL)); - newval->data_type = REG_BINARY; - *((BOOL *)newval->data_blk) = gconf_value_get_bool(value); - newval->data_len = sizeof(BOOL); - break; - - default: - newval->data_type = REG_NONE; - DEBUG(0, ("Not implemented..\n")); - break; - } - } else newval->data_type = REG_NONE; - - ar[(*count)] = newval; - ar = talloc_realloc(ar, sizeof(REG_VAL *) * ((*count)+2)); - (*count)++; - g_free(cur->data); - cur = cur->next; - } + int i; + cur = entries = gconf_client_all_entries((GConfClient*)p->hive->backend_data, fullpath, NULL); + + for(i = 0; i < idx && cur; i++) cur = cur->next; + + if(!cur) return WERR_NO_MORE_ITEMS; + + entry = cur->data; + value = gconf_entry_get_value(entry); + + newval = talloc_p(mem_ctx, struct registry_value); + newval->name = talloc_strdup(mem_ctx, strrchr(gconf_entry_get_key(entry), '/')+1); + if(value) { + switch(value->type) { + case GCONF_VALUE_INVALID: + newval->data_type = REG_NONE; + break; + + case GCONF_VALUE_STRING: + newval->data_type = REG_SZ; + newval->data_blk = talloc_strdup(mem_ctx, gconf_value_get_string(value)); + newval->data_len = strlen(newval->data_blk); + break; + + case GCONF_VALUE_INT: + newval->data_type = REG_DWORD; + newval->data_blk = talloc_p(mem_ctx, long); + *((long *)newval->data_blk) = gconf_value_get_int(value); + newval->data_len = sizeof(long); + break; + + case GCONF_VALUE_FLOAT: + newval->data_blk = talloc_p(mem_ctx, double); + newval->data_type = REG_BINARY; + *((double *)newval->data_blk) = gconf_value_get_float(value); + newval->data_len = sizeof(double); + break; + + case GCONF_VALUE_BOOL: + newval->data_blk = talloc_p(mem_ctx, BOOL); + newval->data_type = REG_BINARY; + *((BOOL *)newval->data_blk) = gconf_value_get_bool(value); + newval->data_len = sizeof(BOOL); + break; + + default: + newval->data_type = REG_NONE; + DEBUG(0, ("Not implemented..\n")); + break; + } + } else newval->data_type = REG_NONE; g_slist_free(entries); - *vals = ar; + *val = newval; return WERR_OK; } -static WERROR gconf_fetch_subkeys(REG_KEY *p, int *count, REG_KEY ***subs) +static WERROR gconf_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *p, int idx, struct registry_key **sub) { GSList *dirs; GSList *cur; - REG_KEY **ar = talloc_array_p(p->mem_ctx, REG_KEY *, 1); + int i; char *fullpath = p->backend_data; - cur = dirs = gconf_client_all_dirs((GConfClient*)p->handle->backend_data, fullpath,NULL); - - (*count) = 0; - while(cur) { - char *winpath = reg_path_unix2win(strdup((char *)cur->data)); - ar[(*count)] = reg_key_new_abs(winpath, p->handle,NULL); - free(winpath); - ar[(*count)]->backend_data = reg_path_win2unix(talloc_strdup(ar[*count]->mem_ctx, cur->data)); - ar = talloc_realloc_p(ar, REG_KEY *, (*count)+2); - (*count)++; - g_free(cur->data); - cur = cur->next; - } + cur = dirs = gconf_client_all_dirs((GConfClient*)p->hive->backend_data, fullpath,NULL); + + for(i = 0; i < idx && cur; i++) cur = cur->next; + + if(!cur) return WERR_NO_MORE_ITEMS; + + *sub = talloc_p(mem_ctx, struct registry_key); + (*sub)->name = talloc_strdup(mem_ctx, strrchr((char *)cur->data, '/')+1); + (*sub)->backend_data = talloc_strdup(mem_ctx, cur->data); g_slist_free(dirs); - *subs = ar; return WERR_OK; } -static WERROR gconf_update_value(REG_VAL *val, int type, void *data, int len) +static WERROR gconf_set_value(struct registry_key *key, const char *valname, int type, void *data, int len) { GError *error = NULL; - char *keypath = val->backend_data; char *valpath; - if(val->name)asprintf(&valpath, "%s/%s", keypath, val->name); - else valpath = strdup(keypath); + asprintf(&valpath, "%s/%s", key->path, valname); switch(type) { case REG_SZ: case REG_EXPAND_SZ: - gconf_client_set_string((GConfClient *)val->handle->backend_data, valpath, data, &error); - free(valpath); + gconf_client_set_string((GConfClient *)key->hive->backend_data, valpath, data, &error); + SAFE_FREE(valpath); return gerror_to_werror(error); case REG_DWORD: - gconf_client_set_int((GConfClient *)val->handle->backend_data, valpath, + gconf_client_set_int((GConfClient *)key->hive->backend_data, valpath, *((int *)data), &error); - free(valpath); + SAFE_FREE(valpath); return gerror_to_werror(error); default: DEBUG(0, ("Unsupported type: %d\n", type)); - free(valpath); + SAFE_FREE(valpath); return WERR_NOT_SUPPORTED; } return WERR_NOT_SUPPORTED; } -static struct registry_ops reg_backend_gconf = { +static struct registry_operations reg_backend_gconf = { .name = "gconf", - .open_registry = reg_open_gconf, - .close_registry = reg_close_gconf, - .get_hive = gconf_get_hive, + .open_hive = reg_open_gconf_hive, .open_key = gconf_open_key, - .fetch_subkeys = gconf_fetch_subkeys, - .fetch_values = gconf_fetch_values, - .update_value = gconf_update_value, + .get_subkey_by_index = gconf_get_subkey_by_id, + .get_value_by_index = gconf_get_value_by_id, + .set_value = gconf_set_value, /* Note: * since GConf uses schemas for what keys and values are allowed, there diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index 47cb60d711..e0f65f2c37 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -19,7 +19,6 @@ */ #include "includes.h" -#include "lib/registry/common/registry.h" static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char *add) { @@ -55,40 +54,46 @@ static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char * return ret; } + +static int ldb_close_registry(void *data) +{ + ldb_close((struct ldb_context *)data); + return 0; +} + + /* * Saves the dn as private_data for every key/val */ -static WERROR ldb_open_registry(REG_HANDLE *handle, const char *location, const char *credentials) +static WERROR ldb_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *hive, struct registry_key **k) { struct ldb_context *c; - if (!location) return WERR_INVALID_PARAM; - c = ldb_connect(location, 0, NULL); + if (!hive->location) return WERR_INVALID_PARAM; + c = ldb_connect(hive->location, 0, NULL); ldb_set_debug_stderr(c); + if(!c) return WERR_FOOBAR; - handle->backend_data = c; + hive->backend_data = c; + talloc_set_destructor(c, ldb_close_registry); return WERR_OK; } -static WERROR ldb_close_registry(REG_HANDLE *h) -{ - ldb_close((struct ldb_context *)h->backend_data); - return WERR_OK; -} - -static WERROR ldb_add_key(REG_KEY *p, const char *name, uint32_t access_mask, SEC_DESC *sec, REG_KEY **new) +static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, struct registry_key *p, const char *name, uint32_t access_mask, SEC_DESC *sec, struct registry_key **new) { return WERR_NOT_SUPPORTED; } -static WERROR ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys) +#if 0 +FIXME +static WERROR ldb_fetch_subkeys(struct registry_key *k, int *count, struct registry_key ***subkeys) { - struct ldb_context *c = k->handle->backend_data; + struct ldb_context *c = k->hive->backend_data; int ret, i, j; struct ldb_message **msg; @@ -99,7 +104,7 @@ static WERROR ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys) return WERR_FOOBAR; } - *subkeys = talloc_array_p(k->mem_ctx, REG_KEY *, ret); + *subkeys = talloc_array_p(k->mem_ctx, struct registry_key *, ret); j = 0; for(i = 0; i < ret; i++) { struct ldb_message_element *el; @@ -121,9 +126,9 @@ static WERROR ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys) return WERR_OK; } -static WERROR ldb_fetch_values(REG_KEY *k, int *count, REG_VAL ***values) +static WERROR ldb_fetch_values(struct registry_key *k, int *count, REG_VAL ***values) { - struct ldb_context *c = k->handle->backend_data; + struct ldb_context *c = k->hive->backend_data; int ret, i, j; struct ldb_message **msg; @@ -156,21 +161,14 @@ static WERROR ldb_fetch_values(REG_KEY *k, int *count, REG_VAL ***values) return WERR_OK; } -static WERROR ldb_get_hive(REG_HANDLE *h, int num, REG_KEY **key) -{ - if(num != 0) return WERR_NO_MORE_ITEMS; - *key = reg_key_new_abs("", h, NULL); - return WERR_OK; -} +#endif -static WERROR ldb_open_key(REG_HANDLE *h, int num, const char *name, REG_KEY **key) +static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **key) { struct ldb_context *c = h->backend_data; struct ldb_message **msg; char *ldap_path; int ret; - TALLOC_CTX *mem_ctx = talloc_init("ldb_path"); - if(num != 0) return WERR_NO_MORE_ITEMS; ldap_path = reg_path_to_ldb(mem_ctx, name, NULL); ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "*", NULL,&msg); @@ -182,25 +180,20 @@ static WERROR ldb_open_key(REG_HANDLE *h, int num, const char *name, REG_KEY **k return WERR_FOOBAR; } - *key = reg_key_new_abs(name, h, ldap_path); - talloc_steal((*key)->mem_ctx, ldap_path); - printf("Got something!\n"); + *key = talloc_p(mem_ctx, struct registry_key); /* FIXME */ ldb_search_free(c, msg); - talloc_destroy(mem_ctx); return WERR_OK; } -static struct registry_ops reg_backend_ldb = { +static struct registry_operations reg_backend_ldb = { .name = "ldb", - .open_registry = ldb_open_registry, - .get_hive = ldb_get_hive, - .close_registry = ldb_close_registry, + .open_hive = ldb_open_hive, .open_key = ldb_open_key, - .fetch_subkeys = ldb_fetch_subkeys, - .fetch_values = ldb_fetch_values, +/* .fetch_subkeys = ldb_fetch_subkeys, + .fetch_values = ldb_fetch_values,*/ .add_key = ldb_add_key, }; diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index ee9f8bf24f..c271c55991 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -304,9 +304,9 @@ Hope this helps.... (Although it was "fun" for me to uncover this things, *************************************************************************/ #include "includes.h" -#include "lib/registry/common/registry.h" #define REG_KEY_LIST_SIZE 10 +#define FLAG_HAS_NAME 0x01 /*FIXME*/ /* @@ -514,7 +514,7 @@ static BOOL nt_create_ace(SEC_ACE *ace, int type, int flags, uint32_t perms, con /* * Create a default ACL */ -static SEC_ACL *nt_create_default_acl(REG_HANDLE *regf) +static SEC_ACL *nt_create_default_acl(struct registry_hive *regf) { SEC_ACE aces[8]; @@ -534,7 +534,7 @@ static SEC_ACL *nt_create_default_acl(REG_HANDLE *regf) * Create a default security descriptor. We pull in things from env * if need be */ -static SEC_DESC *nt_create_def_sec_desc(REG_HANDLE *regf) +static SEC_DESC *nt_create_def_sec_desc(struct registry_hive *regf) { SEC_DESC *tmp; @@ -559,7 +559,7 @@ static SEC_DESC *nt_create_def_sec_desc(REG_HANDLE *regf) * says, but the Owner and Group SIDs can be overwridden from the command line * and additional ACEs can be applied from the command line etc. */ -static KEY_SEC_DESC *nt_inherit_security(REG_KEY *key) +static KEY_SEC_DESC *nt_inherit_security(struct registry_key *key) { if (!key) return NULL; @@ -570,7 +570,7 @@ static KEY_SEC_DESC *nt_inherit_security(REG_KEY *key) * Create an initial security descriptor and init other structures, if needed * We assume that the initial security stuff is empty ... */ -static KEY_SEC_DESC *nt_create_init_sec(REG_HANDLE *h) +static KEY_SEC_DESC *nt_create_init_sec(struct registry_hive *h) { REGF *regf = h->backend_data; KEY_SEC_DESC *tsec = NULL; @@ -618,7 +618,7 @@ static KEY_SEC_DESC *nt_create_init_sec(REG_HANDLE *h) /* Get the header of the registry. Return a pointer to the structure * If the mmap'd area has not been allocated, then mmap the input file */ -static REGF_HDR *nt_get_regf_hdr(REG_HANDLE *h) +static REGF_HDR *nt_get_regf_hdr(struct registry_hive *h) { REGF *regf = h->backend_data; SMB_REG_ASSERT(regf); @@ -676,7 +676,7 @@ static int valid_regf_hdr(REGF_HDR *regf_hdr) /* * Create a new entry in the map, and increase the size of the map if needed */ -static SK_MAP *alloc_sk_map_entry(REG_HANDLE *h, KEY_SEC_DESC *tmp, int sk_off) +static SK_MAP *alloc_sk_map_entry(struct registry_hive *h, KEY_SEC_DESC *tmp, int sk_off) { REGF *regf = h->backend_data; if (!regf->sk_map) { /* Allocate a block of 10 */ @@ -731,7 +731,7 @@ KEY_SEC_DESC *lookup_sec_key(SK_MAP *sk_map, int count, int sk_off) /* * Allocate a KEY_SEC_DESC if we can't find one in the map */ -static KEY_SEC_DESC *lookup_create_sec_key(REG_HANDLE *h, SK_MAP *sk_map, int sk_off) +static KEY_SEC_DESC *lookup_create_sec_key(struct registry_hive *h, SK_MAP *sk_map, int sk_off) { REGF *regf = h->backend_data; KEY_SEC_DESC *tmp = lookup_sec_key(regf->sk_map, regf->sk_count, sk_off); @@ -750,7 +750,7 @@ static KEY_SEC_DESC *lookup_create_sec_key(REG_HANDLE *h, SK_MAP *sk_map, int sk } } -static SEC_DESC *process_sec_desc(REG_HANDLE *regf, SEC_DESC *sec_desc) +static SEC_DESC *process_sec_desc(struct registry_hive *regf, SEC_DESC *sec_desc) { SEC_DESC *tmp = NULL; @@ -790,7 +790,7 @@ static SEC_DESC *process_sec_desc(REG_HANDLE *regf, SEC_DESC *sec_desc) return tmp; } -static KEY_SEC_DESC *process_sk(REG_HANDLE *regf, SK_HDR *sk_hdr, int sk_off, int size) +static KEY_SEC_DESC *process_sk(struct registry_hive *regf, SK_HDR *sk_hdr, int sk_off, int size) { KEY_SEC_DESC *tmp = NULL; int sk_next_off, sk_prev_off, sk_size; @@ -879,38 +879,34 @@ static KEY_SEC_DESC *process_sk(REG_HANDLE *regf, SK_HDR *sk_hdr, int sk_off, in /* * Process a VK header and return a value */ -static WERROR vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size, REG_VAL **value) +static WERROR vk_to_val(TALLOC_CTX *mem_ctx, struct registry_key *parent, VK_HDR *vk_hdr, int size, struct registry_value **value) { - char val_name[1024]; - REGF *regf = parent->handle->backend_data; + REGF *regf = parent->hive->backend_data; int nam_len, dat_len, flag, dat_type, dat_off, vk_id; - REG_VAL *tmp = NULL; + struct registry_value *tmp = NULL; if (!vk_hdr) return WERR_INVALID_PARAM; if ((vk_id = SVAL(&vk_hdr->VK_ID,0)) != str_to_dword("vk")) { DEBUG(0, ("Unrecognized VK header ID: %0X, block: %0X, %s\n", - vk_id, (int)vk_hdr, parent->handle->location)); + vk_id, (int)vk_hdr, parent->hive->location)); return WERR_GENERAL_FAILURE; } nam_len = SVAL(&vk_hdr->nam_len,0); - val_name[nam_len] = '\0'; flag = SVAL(&vk_hdr->flag,0); dat_type = IVAL(&vk_hdr->dat_type,0); dat_len = IVAL(&vk_hdr->dat_len,0); /* If top bit, offset contains data */ dat_off = IVAL(&vk_hdr->dat_off,0); - tmp = reg_val_new(parent, NULL); - tmp->has_name = flag; + tmp = talloc_p(mem_ctx, struct registry_value); tmp->data_type = dat_type; - if (flag & 0x01) { - strncpy(val_name, vk_hdr->dat_name, nam_len); - tmp->name = strdup(val_name); + if (flag & FLAG_HAS_NAME) { + tmp->name = talloc_strndup(mem_ctx, vk_hdr->dat_name, nam_len); + } else { + tmp->name = NULL; } - else - strncpy(val_name, "", 10); /* * Allocate space and copy the data as a BLOB @@ -918,9 +914,7 @@ static WERROR vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size, REG_VAL **val if (dat_len&0x7FFFFFFF) { - char *dtmp = (char *)talloc(tmp->mem_ctx, dat_len&0x7FFFFFFF); - - tmp->data_blk = dtmp; + char *dtmp = (char *)talloc(mem_ctx, dat_len&0x7FFFFFFF); if ((dat_len&0x80000000) == 0) { /* The data is pointed to by the offset */ char *dat_ptr = LOCN(regf->base, dat_off); @@ -937,6 +931,15 @@ static WERROR vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size, REG_VAL **val memcpy(dtmp, &dat_off, dat_len); } + + if(tmp->data_type == REG_SZ) { + char *ret; + dat_len = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, dtmp, dat_len, (const void **)&ret); + dtmp = ret; + } + + + tmp->data_blk = dtmp; tmp->data_len = dat_len; } @@ -958,7 +961,7 @@ static BOOL vl_verify(VL_TYPE vl, int count, int size) #endif -static WERROR lf_verify(REG_HANDLE *h, LF_HDR *lf_hdr, int size) +static WERROR lf_verify(struct registry_hive *h, LF_HDR *lf_hdr, int size) { int lf_id; if ((lf_id = SVAL(&lf_hdr->LF_ID,0)) != str_to_dword("lf")) { @@ -969,7 +972,7 @@ static WERROR lf_verify(REG_HANDLE *h, LF_HDR *lf_hdr, int size) return WERR_OK; } -static WERROR lf_num_entries(REG_HANDLE *h, LF_HDR *lf_hdr, int size, int *count) +static WERROR lf_num_entries(struct registry_hive *h, LF_HDR *lf_hdr, int size, int *count) { WERROR error; @@ -986,23 +989,23 @@ static WERROR lf_num_entries(REG_HANDLE *h, LF_HDR *lf_hdr, int size, int *count } -static WERROR nk_to_key(REG_HANDLE *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent, REG_KEY **); +static WERROR nk_to_key(TALLOC_CTX *, struct registry_hive *regf, NK_HDR *nk_hdr, int size, struct registry_key *parent, struct registry_key **); /* * Process an LF Header and return a list of sub-keys */ -static WERROR lf_get_entry(REG_KEY *parent, LF_HDR *lf_hdr, int size, int n, REG_KEY **key) +static WERROR lf_get_entry(TALLOC_CTX *mem_ctx, struct registry_key *parent, LF_HDR *lf_hdr, int size, int n, struct registry_key **key) { - REGF *regf = parent->handle->backend_data; + REGF *regf = parent->hive->backend_data; int count, nk_off; NK_HDR *nk_hdr; WERROR error; if (!lf_hdr) return WERR_INVALID_PARAM; - error = lf_verify(parent->handle, lf_hdr, size); + error = lf_verify(parent->hive, lf_hdr, size); if(!W_ERROR_IS_OK(error)) return error; SMB_REG_ASSERT(size < 0); @@ -1015,13 +1018,13 @@ static WERROR lf_get_entry(REG_KEY *parent, LF_HDR *lf_hdr, int size, int n, REG nk_off = IVAL(&lf_hdr->hr[n].nk_off,0); DEBUG(2, ("NK Offset: %0X\n", nk_off)); nk_hdr = (NK_HDR *)LOCN(regf->base, nk_off); - return nk_to_key(parent->handle, nk_hdr, BLK_SIZE(nk_hdr), parent, key); + return nk_to_key(mem_ctx, parent->hive, nk_hdr, BLK_SIZE(nk_hdr), parent, key); } -static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent, REG_KEY **key) +static WERROR nk_to_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, NK_HDR *nk_hdr, int size, struct registry_key *parent, struct registry_key **key) { REGF *regf = h->backend_data; - REG_KEY *tmp = NULL, *own; + struct registry_key *tmp = NULL, *own; int namlen, clsname_len, sk_off, own_off; uint_t nk_id; SK_HDR *sk_hdr; @@ -1032,7 +1035,7 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent if ((nk_id = SVAL(&nk_hdr->NK_ID,0)) != str_to_dword("nk")) { DEBUG(0, ("Unrecognized NK Header format: %08X, Block: %0X. %s\n", - nk_id, (int)nk_hdr, parent->handle->location)); + nk_id, (int)nk_hdr, parent->hive->location)); return WERR_INVALID_PARAM; } @@ -1071,8 +1074,9 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent return WERR_GENERAL_FAILURE; } - if(type == REG_ROOT_KEY) tmp = reg_key_new_abs(key_name, h, nk_hdr); - else tmp = reg_key_new_rel(key_name, parent, nk_hdr); + tmp = talloc_p(mem_ctx, struct registry_key); + tmp->name = talloc_strdup(mem_ctx, key_name); + tmp->backend_data = nk_hdr; DEBUG(2, ("Key name: %s\n", key_name)); @@ -1089,7 +1093,7 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent clsnamep = (smb_ucs2_t *)LOCN(regf->base, clsnam_off); DEBUG(2, ("Class Name Offset: %0X\n", clsnam_off)); - pull_ucs2_talloc(tmp->mem_ctx, &tmp->class_name, clsnamep); + pull_ucs2_talloc(mem_ctx, &tmp->class_name, clsnamep); DEBUGADD(2,(" Class Name: %s\n", cls_name)); @@ -1100,7 +1104,7 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent */ own_off = IVAL(&nk_hdr->own_off,0); - own = (REG_KEY *)LOCN(regf->base, own_off); + own = (struct registry_key *)LOCN(regf->base, own_off); DEBUG(2, ("Owner Offset: %0X\n", own_off)); DEBUGADD(2, (" Owner locn: %0X, Our locn: %0X\n", @@ -1136,7 +1140,7 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent /* * Allocate a new hbin block, set up the header for the block etc */ -static HBIN_BLK *nt_create_hbin_blk(REG_HANDLE *h, int size) +static HBIN_BLK *nt_create_hbin_blk(struct registry_hive *h, int size) { REGF *regf = h->backend_data; HBIN_BLK *tmp; @@ -1185,7 +1189,7 @@ static HBIN_BLK *nt_create_hbin_blk(REG_HANDLE *h, int size) * Allocate a unit of space ... and return a pointer as function param * and the block's offset as a side effect */ -static void *nt_alloc_regf_space(REG_HANDLE *h, int size, uint_t *off) +static void *nt_alloc_regf_space(struct registry_hive *h, int size, uint_t *off) { REGF *regf = h->backend_data; int tmp = 0; @@ -1268,7 +1272,7 @@ static void *nt_alloc_regf_space(REG_HANDLE *h, int size, uint_t *off) /* * Store a SID at the location provided */ -static int nt_store_SID(REG_HANDLE *regf, DOM_SID *sid, uint8_t *locn) +static int nt_store_SID(struct registry_hive *regf, DOM_SID *sid, uint8_t *locn) { int i; uint8_t *p = locn; @@ -1290,7 +1294,7 @@ static int nt_store_SID(REG_HANDLE *regf, DOM_SID *sid, uint8_t *locn) } -static int nt_store_ace(REG_HANDLE *regf, SEC_ACE *ace, uint8_t *locn) +static int nt_store_ace(struct registry_hive *regf, SEC_ACE *ace, uint8_t *locn) { int size = 0; SEC_ACE *reg_ace = (SEC_ACE *)locn; @@ -1321,7 +1325,7 @@ static int nt_store_ace(REG_HANDLE *regf, SEC_ACE *ace, uint8_t *locn) /* * Store an ACL at the location provided */ -static int nt_store_acl(REG_HANDLE *regf, SEC_ACL *acl, uint8_t *locn) { +static int nt_store_acl(struct registry_hive *regf, SEC_ACL *acl, uint8_t *locn) { int size = 0, i; uint8_t *p = locn, *s; @@ -1357,7 +1361,7 @@ static int nt_store_acl(REG_HANDLE *regf, SEC_ACL *acl, uint8_t *locn) { * that first, then the owner, then the group SID. So, we do it that way * too. */ -static uint_t nt_store_sec_desc(REG_HANDLE *regf, SEC_DESC *sd, char *locn) +static uint_t nt_store_sec_desc(struct registry_hive *regf, SEC_DESC *sd, char *locn) { SEC_DESC *rsd = (SEC_DESC *)locn; uint_t size = 0, off = 0; @@ -1424,7 +1428,7 @@ static uint_t nt_store_sec_desc(REG_HANDLE *regf, SEC_DESC *sd, char *locn) * If it has already been stored, just get its offset from record * otherwise, store it and record its offset */ -static uint_t nt_store_security(REG_HANDLE *regf, KEY_SEC_DESC *sec) +static uint_t nt_store_security(struct registry_hive *regf, KEY_SEC_DESC *sec) { int size = 0; uint_t sk_off; @@ -1480,7 +1484,7 @@ static uint_t nt_store_security(REG_HANDLE *regf, KEY_SEC_DESC *sec) * We return the offset of the NK struct * FIXME, FIXME, FIXME: Convert to using SIVAL and SSVAL ... */ -static int nt_store_reg_key(REG_HANDLE *regf, REG_KEY *key) +static int nt_store_reg_key(struct registry_hive *regf, struct registry_key *key) { NK_HDR *nk_hdr; uint_t nk_off, sk_off, size; @@ -1543,7 +1547,7 @@ error: * We actually create the registry header block and link it to the chain * of output blocks. */ -static REGF_HDR *nt_get_reg_header(REG_HANDLE *h) { +static REGF_HDR *nt_get_reg_header(struct registry_hive *h) { REGF *regf = h->backend_data; HBIN_BLK *tmp = NULL; @@ -1567,7 +1571,7 @@ error: #endif -static WERROR nt_close_registry (REG_HANDLE *h) +static WERROR nt_close_registry (struct registry_hive *h) { REGF *regf = h->backend_data; if (regf->base) munmap(regf->base, regf->sbuf.st_size); @@ -1577,16 +1581,16 @@ static WERROR nt_close_registry (REG_HANDLE *h) return WERR_OK; } -static WERROR nt_open_registry (REG_HANDLE *h, const char *location, const char *credentials) +static WERROR nt_open_hive (TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **key) { REGF *regf; REGF_HDR *regf_hdr; uint_t regf_id, hbin_id; HBIN_HDR *hbin_hdr; - regf = (REGF *)talloc_p(h->mem_ctx, REGF); + regf = (REGF *)talloc_p(mem_ctx, REGF); memset(regf, 0, sizeof(REGF)); - regf->owner_sid_str = credentials; + regf->owner_sid_str = h->credentials; h->backend_data = regf; DEBUG(5, ("Attempting to load registry file\n")); @@ -1659,18 +1663,13 @@ static WERROR nt_open_registry (REG_HANDLE *h, const char *location, const char h->backend_data = regf; - return WERR_OK; + return nk_to_key(mem_ctx, h, ((REGF *)h->backend_data)->first_key, BLK_SIZE(((REGF *)h->backend_data)->first_key), NULL, key); } -static WERROR nt_get_root_key(REG_HANDLE *h, int hive, REG_KEY **key) -{ - if(hive != 0) return WERR_NO_MORE_ITEMS; - return nk_to_key(h, ((REGF *)h->backend_data)->first_key, BLK_SIZE(((REGF *)h->backend_data)->first_key), NULL, key); -} -static WERROR nt_num_subkeys(REG_KEY *k, int *num) +static WERROR nt_num_subkeys(struct registry_key *k, int *num) { - REGF *regf = k->handle->backend_data; + REGF *regf = k->hive->backend_data; LF_HDR *lf_hdr; int lf_off; NK_HDR *nk_hdr = k->backend_data; @@ -1682,23 +1681,23 @@ static WERROR nt_num_subkeys(REG_KEY *k, int *num) } lf_hdr = (LF_HDR *)LOCN(regf->base, lf_off); - return lf_num_entries(k->handle, lf_hdr, BLK_SIZE(lf_hdr), num); + return lf_num_entries(k->hive, lf_hdr, BLK_SIZE(lf_hdr), num); } -static WERROR nt_num_values(REG_KEY *k, int *count) +static WERROR nt_num_values(struct registry_key *k, int *count) { NK_HDR *nk_hdr = k->backend_data; *count = IVAL(&nk_hdr->val_cnt,0); return WERR_OK; } -static WERROR nt_value_by_index(REG_KEY *k, int n, REG_VAL **value) +static WERROR nt_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *k, int n, struct registry_value **value) { VL_TYPE *vl; int val_off, vk_off; int val_count; VK_HDR *vk_hdr; - REGF *regf = k->handle->backend_data; + REGF *regf = k->hive->backend_data; NK_HDR *nk_hdr = k->backend_data; val_count = IVAL(&nk_hdr->val_cnt,0); val_off = IVAL(&nk_hdr->val_off,0); @@ -1709,12 +1708,12 @@ static WERROR nt_value_by_index(REG_KEY *k, int n, REG_VAL **value) vk_off = IVAL(&vl[n],0); vk_hdr = (VK_HDR *)LOCN(regf->base, vk_off); - return vk_to_val(k, vk_hdr, BLK_SIZE(vk_hdr), value); + return vk_to_val(mem_ctx, k, vk_hdr, BLK_SIZE(vk_hdr), value); } -static WERROR nt_key_by_index(REG_KEY *k, int n, REG_KEY **subkey) +static WERROR nt_key_by_index(TALLOC_CTX *mem_ctx, struct registry_key *k, int n, struct registry_key **subkey) { - REGF *regf = k->handle->backend_data; + REGF *regf = k->hive->backend_data; int lf_off; NK_HDR *nk_hdr = k->backend_data; LF_HDR *lf_hdr; @@ -1727,17 +1726,15 @@ static WERROR nt_key_by_index(REG_KEY *k, int n, REG_KEY **subkey) if (lf_off != -1) { lf_hdr = (LF_HDR *)LOCN(regf->base, lf_off); - return lf_get_entry(k, lf_hdr, BLK_SIZE(lf_hdr), n, subkey); + return lf_get_entry(mem_ctx, k, lf_hdr, BLK_SIZE(lf_hdr), n, subkey); } return WERR_NO_MORE_ITEMS; } -static struct registry_ops reg_backend_nt4 = { +static struct registry_operations reg_backend_nt4 = { .name = "nt4", - .open_registry = nt_open_registry, - .close_registry = nt_close_registry, - .get_hive = nt_get_root_key, + .open_hive = nt_open_hive, .num_subkeys = nt_num_subkeys, .num_values = nt_num_values, .get_subkey_by_index = nt_key_by_index, 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 0d8d935a4a..1c887fc411 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -18,7 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "includes.h" -#include "lib/registry/common/registry.h" /** * This is the RPC backend for the registry library. @@ -37,7 +36,7 @@ static void init_winreg_String(struct winreg_String *name, const char *s) } -#define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, REG_KEY *h, struct policy_handle *hnd) \ +#define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *hnd) \ { \ struct winreg_Open ## u r; \ struct winreg_OpenUnknown unknown; \ @@ -49,7 +48,7 @@ static void init_winreg_String(struct winreg_String *name, const char *s) r.in.access_required = SEC_RIGHTS_MAXIMUM_ALLOWED; \ r.out.handle = hnd;\ \ - status = dcerpc_winreg_Open ## u(p, h->mem_ctx, &r); \ + status = dcerpc_winreg_Open ## u(p, mem_ctx, &r); \ if (NT_STATUS_IS_ERR(status)) {\ DEBUG(0,("Error executing open\n"));\ return ntstatus_to_werror(status);\ @@ -74,7 +73,7 @@ struct rpc_key_data { struct { const char *name; - WERROR (*open) (struct dcerpc_pipe *p, REG_KEY *k, struct policy_handle *h); + WERROR (*open) (struct dcerpc_pipe *p, TALLOC_CTX *, struct policy_handle *h); } known_hives[] = { { "HKEY_LOCAL_MACHINE", open_HKLM }, { "HKEY_CURRENT_USER", open_HKCU }, @@ -84,122 +83,124 @@ struct { { NULL, NULL } }; -static WERROR rpc_query_key(REG_KEY *k); +static WERROR rpc_query_key(struct registry_key *k); -static WERROR rpc_open_registry(REG_HANDLE *h, const char *location, const char *credentials) +WERROR rpc_list_hives (TALLOC_CTX *mem_ctx, const char *location, const char *credentials, char ***hives) +{ + int i = 0; + *hives = talloc_p(mem_ctx, char *); + for(i = 0; known_hives[i].name; i++) { + *hives = talloc_realloc_p(*hives, char *, i+2); + (*hives)[i] = talloc_strdup(mem_ctx, known_hives[i].name); + } + (*hives)[i] = NULL; + return WERR_OK; +} + +static WERROR rpc_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **k) { NTSTATUS status; char *user, *pass; + struct rpc_key_data *mykeydata; + struct dcerpc_pipe *p; + int n; - if(!credentials || !location) return WERR_INVALID_PARAM; + if(!h->credentials || !h->location) return WERR_INVALID_PARAM; - user = talloc_strdup(h->mem_ctx, credentials); + user = talloc_strdup(mem_ctx, h->credentials); pass = strchr(user, '%'); - *pass = '\0'; pass++; + if(pass) + { + *pass = '\0'; pass++; + } else { + pass = ""; + } - status = dcerpc_pipe_connect((struct dcerpc_pipe **)&h->backend_data, h->location, + status = dcerpc_pipe_connect(&p, h->location, DCERPC_WINREG_UUID, DCERPC_WINREG_VERSION, lp_workgroup(), user, pass); - - return ntstatus_to_werror(status); -} -static WERROR rpc_get_hive(REG_HANDLE *h, int n, REG_KEY **k) -{ - struct rpc_key_data *mykeydata; - WERROR error; + h->backend_data = p; + + if(NT_STATUS_IS_ERR(status)) return ntstatus_to_werror(status); + + for(n = 0; known_hives[n].name; n++) + { + if(!strcmp(known_hives[n].name, h->backend_hivename)) break; + } + if(!known_hives[n].name) return WERR_NO_MORE_ITEMS; - *k = reg_key_new_abs(known_hives[n].name, h, NULL); - (*k)->backend_data = mykeydata = talloc_p((*k)->mem_ctx, struct rpc_key_data); + + *k = talloc_p(mem_ctx, struct registry_key); + (*k)->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data); mykeydata->num_values = -1; mykeydata->num_subkeys = -1; - error = known_hives[n].open((struct dcerpc_pipe *)h->backend_data, *k, &mykeydata->pol); - return error; + return known_hives[n].open((struct dcerpc_pipe *)h->backend_data, *k, &(mykeydata->pol)); } -static WERROR rpc_close_registry(REG_HANDLE *h) +static WERROR rpc_close_registry(struct registry_hive *h) { dcerpc_pipe_close((struct dcerpc_pipe *)h->backend_data); return WERR_OK; } -static WERROR rpc_key_put_rpc_data(REG_KEY *k, struct rpc_key_data **data) +static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) { struct winreg_OpenKey r; - WERROR error; - REG_KEY *hivekey; struct rpc_key_data *mykeydata; - if(k->backend_data) { - *data = k->backend_data; - return WERR_OK; - } - - k->backend_data = mykeydata = talloc_p(k->mem_ctx, struct rpc_key_data); - *data = mykeydata; + k->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data); mykeydata->num_values = -1; mykeydata->num_subkeys = -1; /* Then, open the handle using the hive */ memset(&r, 0, sizeof(struct winreg_OpenKey)); - error = rpc_get_hive(k->handle, k->hive, &hivekey); - if(!W_ERROR_IS_OK(error))return error; - r.in.handle = &(((struct rpc_key_data *)hivekey->backend_data)->pol); - init_winreg_String(&r.in.keyname, reg_key_get_path(k)); + r.in.handle = &(((struct rpc_key_data *)k->hive->root->backend_data)->pol); + init_winreg_String(&r.in.keyname, k->path); r.in.unknown = 0x00000000; r.in.access_mask = 0x02000000; r.out.handle = &mykeydata->pol; - dcerpc_winreg_OpenKey((struct dcerpc_pipe *)k->handle->backend_data, k->mem_ctx, &r); + dcerpc_winreg_OpenKey((struct dcerpc_pipe *)k->hive->backend_data, mem_ctx, &r); return r.out.result; } -static WERROR rpc_open_key(REG_HANDLE *h, int hive, const char *name, REG_KEY **key) +static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **key) { struct rpc_key_data *mykeydata; struct winreg_OpenKey r; - REG_KEY *hivekey; - WERROR error; - - *key = reg_key_new_abs(name, h, NULL); - (*key)->backend_data = mykeydata = talloc_p((*key)->mem_ctx, struct rpc_key_data); + *key = talloc_p(mem_ctx, struct registry_key); + (*key)->name = talloc_strdup(mem_ctx, name); + + (*key)->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data); mykeydata->num_values = -1; mykeydata->num_subkeys = -1; /* Then, open the handle using the hive */ memset(&r, 0, sizeof(struct winreg_OpenKey)); - error = rpc_get_hive(h, hive, &hivekey); - if(!W_ERROR_IS_OK(error))return error; - r.in.handle = &(((struct rpc_key_data *)hivekey->backend_data)->pol); + r.in.handle = &(((struct rpc_key_data *)h->root->backend_data)->pol); init_winreg_String(&r.in.keyname, name); r.in.unknown = 0x00000000; r.in.access_mask = 0x02000000; r.out.handle = &mykeydata->pol; - dcerpc_winreg_OpenKey((struct dcerpc_pipe *)(*key)->handle->backend_data, (*key)->mem_ctx, &r); + dcerpc_winreg_OpenKey((struct dcerpc_pipe *)(h->backend_data), mem_ctx, &r); return r.out.result; } -static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value) +static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_value **value) { - struct winreg_EnumValue r; - struct winreg_Uint8buf vb; - struct winreg_EnumValueName vn; - NTSTATUS status; - struct rpc_key_data *mykeydata; - uint32_t type = 0x0, requested_len = 0, returned_len = 0; + struct rpc_key_data *mykeydata = parent->backend_data; + uint32_t requested_len = 0; WERROR error; - error = rpc_key_put_rpc_data(parent, &mykeydata); - if(!W_ERROR_IS_OK(error)) return error; - if(mykeydata->num_values == -1) { error = rpc_query_key(parent); if(!W_ERROR_IS_OK(error)) return error; @@ -207,6 +208,7 @@ static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value) requested_len = mykeydata->max_valdatalen; +#if 0 /* EnumValue is not working yet ... */ r.in.handle = &mykeydata->pol; r.in.enum_index = n; r.in.type = r.out.type = &type; @@ -225,7 +227,7 @@ static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value) vb.max_len = mykeydata->max_valdatalen; vb.offset = 0x0; vb.len = 0x0; - vb.buffer = talloc_array_p(parent->mem_ctx, uint8, mykeydata->max_valdatalen); + vb.buffer = talloc_array_p(mem_ctx, uint8, mykeydata->max_valdatalen); r.in.value = r.out.value = &vb; status = dcerpc_winreg_EnumValue((struct dcerpc_pipe *)parent->handle->backend_data, parent->mem_ctx, &r); @@ -242,23 +244,20 @@ static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value) exit(1); return WERR_OK; } +#endif - return r.out.result; + return WERR_NOT_SUPPORTED; } -static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey) +static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_key **subkey) { struct winreg_EnumKey r; struct winreg_EnumKeyNameRequest keyname; struct winreg_String classname; struct winreg_Time tm; struct rpc_key_data *mykeydata = parent->backend_data; - WERROR error; NTSTATUS status; - error = rpc_key_put_rpc_data(parent, &mykeydata); - if(!W_ERROR_IS_OK(error)) return error; - r.in.handle = &mykeydata->pol; keyname.unknown = 0x0000020a; init_winreg_String(&keyname.key_name, NULL); @@ -271,40 +270,33 @@ static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey) r.in.enum_index = n; r.in.unknown = r.out.unknown = 0x0414; r.in.key_name_len = r.out.key_name_len = 0; - status = dcerpc_winreg_EnumKey((struct dcerpc_pipe *)parent->handle->backend_data, parent->mem_ctx, &r); + status = dcerpc_winreg_EnumKey((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r); if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { - *subkey = reg_key_new_rel(r.out.out_name->name, parent, NULL); + if(parent->hive->root == parent) + return rpc_open_key(mem_ctx, parent->hive, talloc_strdup(mem_ctx, r.out.out_name->name), subkey); + return rpc_open_key(mem_ctx, parent->hive, talloc_asprintf(mem_ctx, "%s\\%s", parent->path, r.out.out_name->name), subkey); } return r.out.result; } -static WERROR rpc_add_key(REG_KEY *parent, const char *name, uint32_t access_mask, SEC_DESC *sec, REG_KEY **key) +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) { - struct rpc_key_data *mykeydata; - WERROR error; - - error = rpc_key_put_rpc_data(parent, &mykeydata); - if(!W_ERROR_IS_OK(error)) return error; - - /* FIXME */ return WERR_NOT_SUPPORTED; } -static WERROR rpc_query_key(REG_KEY *k) +static WERROR rpc_query_key(struct registry_key *k) { NTSTATUS status; - WERROR error; struct winreg_QueryInfoKey r; - struct rpc_key_data *mykeydata; - - error = rpc_key_put_rpc_data(k, &mykeydata); - if(!W_ERROR_IS_OK(error)) return error; + struct rpc_key_data *mykeydata = k->backend_data; + TALLOC_CTX *mem_ctx = talloc_init("query_key"); init_winreg_String(&r.in.class, NULL); r.in.handle = &mykeydata->pol; - status = dcerpc_winreg_QueryInfoKey((struct dcerpc_pipe *)k->handle->backend_data, k->mem_ctx, &r); + status = dcerpc_winreg_QueryInfoKey((struct dcerpc_pipe *)(k->hive->backend_data), mem_ctx, &r); + talloc_destroy(mem_ctx); if (!NT_STATUS_IS_OK(status)) { printf("QueryInfoKey failed - %s\n", nt_errstr(status)); @@ -321,40 +313,37 @@ static WERROR rpc_query_key(REG_KEY *k) return r.out.result; } -static WERROR rpc_del_key(REG_KEY *k) +static WERROR rpc_del_key(struct registry_key *k) { NTSTATUS status; struct rpc_key_data *mykeydata = k->backend_data; struct winreg_DeleteKey r; - REG_KEY *parent; + struct registry_key *parent; WERROR error; + TALLOC_CTX *mem_ctx = talloc_init("del_key"); - error = reg_key_get_parent(k, &parent); - if(!W_ERROR_IS_OK(error)) return error; + error = reg_key_get_parent(mem_ctx, k, &parent); + if(!W_ERROR_IS_OK(error)) { + talloc_destroy(mem_ctx); + return error; + } + + mykeydata = parent->backend_data; - error = rpc_key_put_rpc_data(parent, &mykeydata); - if(!W_ERROR_IS_OK(error)) return error; - r.in.handle = &mykeydata->pol; init_winreg_String(&r.in.key, k->name); - status = dcerpc_winreg_DeleteKey((struct dcerpc_pipe *)k->handle->backend_data, k->mem_ctx, &r); + status = dcerpc_winreg_DeleteKey((struct dcerpc_pipe *)k->hive->backend_data, mem_ctx, &r); - return r.out.result; -} + talloc_destroy(mem_ctx); -static void rpc_close_key(REG_KEY *k) -{ - reg_key_free(k); + return r.out.result; } -static WERROR rpc_num_values(REG_KEY *key, int *count) { +static WERROR rpc_num_values(struct registry_key *key, int *count) { struct rpc_key_data *mykeydata = key->backend_data; WERROR error; - error = rpc_key_put_rpc_data(key, &mykeydata); - if(!W_ERROR_IS_OK(error)) return error; - if(mykeydata->num_values == -1) { error = rpc_query_key(key); if(!W_ERROR_IS_OK(error)) return error; @@ -364,13 +353,10 @@ static WERROR rpc_num_values(REG_KEY *key, int *count) { return WERR_OK; } -static WERROR rpc_num_subkeys(REG_KEY *key, int *count) { +static WERROR rpc_num_subkeys(struct registry_key *key, int *count) { struct rpc_key_data *mykeydata = key->backend_data; WERROR error; - error = rpc_key_put_rpc_data(key, &mykeydata); - if(!W_ERROR_IS_OK(error)) return error; - if(mykeydata->num_subkeys == -1) { error = rpc_query_key(key); if(!W_ERROR_IS_OK(error)) return error; @@ -380,19 +366,17 @@ static WERROR rpc_num_subkeys(REG_KEY *key, int *count) { return WERR_OK; } -static struct registry_ops reg_backend_rpc = { +static struct registry_operations reg_backend_rpc = { .name = "rpc", - .open_registry = rpc_open_registry, - .close_registry = rpc_close_registry, - .get_hive = rpc_get_hive, + .open_hive = rpc_open_hive, .open_key = rpc_open_key, .get_subkey_by_index = rpc_get_subkey_by_index, .get_value_by_index = rpc_get_value_by_index, .add_key = rpc_add_key, .del_key = rpc_del_key, - .free_key_backend_data = rpc_close_key, .num_subkeys = rpc_num_subkeys, .num_values = rpc_num_values, + .list_available_hives = rpc_list_hives, }; NTSTATUS registry_rpc_init(void) diff --git a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c index f392759b8d..2184a8855d 100644 --- a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c @@ -20,7 +20,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "includes.h" -#include "lib/registry/common/registry.h" /** * The registry starts with a header that contains pointers to @@ -179,67 +178,18 @@ static void parse_rgdb_block(CREG *creg, RGDB_HDR *rgdb_hdr) } } -static WERROR w95_open_root (REG_HANDLE *h, int hive, REG_KEY **key) -{ - CREG *creg = h->backend_data; - - if(hive != 0) return WERR_NO_MORE_ITEMS; - - /* First element in rgkn should be root key */ - *key = reg_key_new_abs("", h, LOCN_RGKN(creg, sizeof(RGKN_HDR))); - - return WERR_OK; -} - -static WERROR w95_get_subkey_by_index (REG_KEY *parent, int n, REG_KEY **key) -{ - CREG *creg = parent->handle->backend_data; - RGKN_KEY *rgkn_key = parent->backend_data; - RGKN_KEY *child; - DWORD child_offset; - DWORD cur = 0; - - /* Get id of first child */ - child_offset = rgkn_key->first_child_offset; - - while(child_offset != 0xFFFFFFFF) { - child = LOCN_RGKN(creg, child_offset); - - /* n == cur ? return! */ - if(cur == n) { - RGDB_KEY *rgdb_key; - char *name; - rgdb_key = LOCN_RGDB_KEY(creg, child->id.rgdb, child->id.id); - if(!rgdb_key) { - DEBUG(0, ("Can't find %d,%d in RGDB table!\n", child->id.rgdb, child->id.id)); - return WERR_FOOBAR; - } - name = strndup((char *)rgdb_key + sizeof(RGDB_KEY), rgdb_key->name_len); - *key = reg_key_new_rel(name, parent, child); - SAFE_FREE(name); - return WERR_OK; - } - - cur++; - - child_offset = child->next_offset; - } - - return WERR_NO_MORE_ITEMS; -} - -static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *credentials) +static WERROR w95_open_reg (TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **root) { CREG *creg; DWORD creg_id, rgkn_id; DWORD i; DWORD offset; - creg = talloc_p(h->mem_ctx, CREG); + creg = talloc_p(mem_ctx, CREG); memset(creg, 0, sizeof(CREG)); h->backend_data = creg; - if((creg->fd = open(location, O_RDONLY, 0000)) < 0) { + if((creg->fd = open(h->location, O_RDONLY, 0000)) < 0) { return WERR_FOOBAR; } @@ -250,7 +200,7 @@ static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *cre creg->base = mmap(0, creg->sbuf.st_size, PROT_READ, MAP_SHARED, creg->fd, 0); if ((int)creg->base == 1) { - DEBUG(0,("Could not mmap file: %s, %s\n", location, strerror(errno))); + DEBUG(0,("Could not mmap file: %s, %s\n", h->location, strerror(errno))); return WERR_FOOBAR; } @@ -258,7 +208,7 @@ static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *cre if ((creg_id = IVAL(&creg->creg_hdr->CREG_ID,0)) != str_to_dword("CREG")) { DEBUG(0, ("Unrecognized Windows 95 registry header id: 0x%0X, %s\n", - creg_id, location)); + creg_id, h->location)); return WERR_FOOBAR; } @@ -266,7 +216,7 @@ static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *cre if ((rgkn_id = IVAL(&creg->rgkn_hdr->RGKN_ID,0)) != str_to_dword("RGKN")) { DEBUG(0, ("Unrecognized Windows 95 registry key index id: 0x%0X, %s\n", - rgkn_id, location)); + rgkn_id, h->location)); return WERR_FOOBAR; } @@ -282,7 +232,7 @@ static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *cre } #endif - creg->rgdb_keys = talloc_array_p(h->mem_ctx, RGDB_KEY **, creg->creg_hdr->num_rgdb); + creg->rgdb_keys = talloc_array_p(mem_ctx, RGDB_KEY **, creg->creg_hdr->num_rgdb); offset = 0; DEBUG(3, ("Reading %d rgdb entries\n", creg->creg_hdr->num_rgdb)); @@ -291,14 +241,14 @@ static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *cre if(strncmp((char *)&(rgdb_hdr->RGDB_ID), "RGDB", 4)) { DEBUG(0, ("unrecognized rgdb entry: %4d, %s\n", - rgdb_hdr->RGDB_ID, location)); + rgdb_hdr->RGDB_ID, h->location)); return WERR_FOOBAR; } else { DEBUG(3, ("Valid rgdb entry, first free id: %d, max id: %d\n", rgdb_hdr->first_free_id, rgdb_hdr->max_id)); } - creg->rgdb_keys[i] = talloc_array_p(h->mem_ctx, RGDB_KEY *, rgdb_hdr->max_id+1); + creg->rgdb_keys[i] = talloc_array_p(mem_ctx, RGDB_KEY *, rgdb_hdr->max_id+1); memset(creg->rgdb_keys[i], 0, sizeof(RGDB_KEY *) * (rgdb_hdr->max_id+1)); parse_rgdb_block(creg, rgdb_hdr); @@ -306,11 +256,51 @@ static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *cre offset+=rgdb_hdr->size; } - + /* First element in rgkn should be root key */ + *root = talloc_p(mem_ctx, struct registry_key); + (*root)->name = NULL; + (*root)->backend_data = LOCN_RGKN(creg, sizeof(RGKN_HDR)); + return WERR_OK; } -static WERROR w95_close_reg(REG_HANDLE *h) +static WERROR w95_get_subkey_by_index (TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_key **key) +{ + CREG *creg = parent->hive->backend_data; + RGKN_KEY *rgkn_key = parent->backend_data; + RGKN_KEY *child; + DWORD child_offset; + DWORD cur = 0; + + /* Get id of first child */ + child_offset = rgkn_key->first_child_offset; + + while(child_offset != 0xFFFFFFFF) { + child = LOCN_RGKN(creg, child_offset); + + /* n == cur ? return! */ + if(cur == n) { + RGDB_KEY *rgdb_key; + rgdb_key = LOCN_RGDB_KEY(creg, child->id.rgdb, child->id.id); + if(!rgdb_key) { + DEBUG(0, ("Can't find %d,%d in RGDB table!\n", child->id.rgdb, child->id.id)); + return WERR_FOOBAR; + } + *key = talloc_p(mem_ctx, struct registry_key); + (*key)->backend_data = child; + (*key)->name = talloc_strndup(mem_ctx, (char *)rgdb_key + sizeof(RGDB_KEY), rgdb_key->name_len); + return WERR_OK; + } + + cur++; + + child_offset = child->next_offset; + } + + return WERR_NO_MORE_ITEMS; +} + +static WERROR w95_close_reg(struct registry_hive *h) { CREG *creg = h->backend_data; if (creg->base) munmap(creg->base, creg->sbuf.st_size); @@ -319,47 +309,51 @@ static WERROR w95_close_reg(REG_HANDLE *h) return WERR_OK; } +static WERROR w95_num_values(struct registry_key *k, int *count) +{ + RGKN_KEY *rgkn_key = k->backend_data; + RGDB_KEY *rgdb_key = LOCN_RGDB_KEY((CREG *)k->hive->backend_data, rgkn_key->id.rgdb, rgkn_key->id.id); + + if(!rgdb_key) return WERR_FOOBAR; + + *count = rgdb_key->num_values; + + return WERR_OK; +} -static WERROR w95_fetch_values(REG_KEY *k, int *count, REG_VAL ***values) +static WERROR w95_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_value **value) { RGKN_KEY *rgkn_key = k->backend_data; DWORD i; DWORD offset = 0; - RGDB_KEY *rgdb_key = LOCN_RGDB_KEY((CREG *)k->handle->backend_data, rgkn_key->id.rgdb, rgkn_key->id.id); + RGDB_KEY *rgdb_key = LOCN_RGDB_KEY((CREG *)k->hive->backend_data, rgkn_key->id.rgdb, rgkn_key->id.id); + RGDB_VALUE *curval; if(!rgdb_key) return WERR_FOOBAR; - *count = rgdb_key->num_values; + if(idx >= rgdb_key->num_values) return WERR_NO_MORE_ITEMS; - if((*count) == 0) return WERR_OK; + for(i = 0; i < idx; i++) { + curval = (RGDB_VALUE *)(((char *)rgdb_key) + sizeof(RGDB_KEY) + rgdb_key->name_len + offset); + offset+=sizeof(RGDB_VALUE) + curval->name_len + curval->data_len; + } - (*values) = talloc_array_p(k->mem_ctx, REG_VAL *, (*count)+1); - for(i = 0; i < rgdb_key->num_values; i++) { - RGDB_VALUE *val = (RGDB_VALUE *)(((char *)rgdb_key) + sizeof(RGDB_KEY) + rgdb_key->name_len + offset); - (*values)[i] = reg_val_new(k, val); - - /* Name */ - (*values)[i]->name = talloc_strndup(k->mem_ctx, (char *)val+sizeof(RGDB_VALUE), val->name_len); + *value = talloc_p(mem_ctx, struct registry_value); + (*value)->backend_data = curval; + (*value)->name = talloc_strndup(mem_ctx, (char *)curval+sizeof(RGDB_VALUE), curval->name_len); - /* Value */ - (*values)[i]->data_len = val->data_len; - (*values)[i]->data_blk = talloc_memdup((*values)[i]->mem_ctx, (char *)val+sizeof(RGDB_VALUE)+val->name_len, val->data_len); - - /* Type */ - (*values)[i]->data_type = val->type; - - offset+=sizeof(RGDB_VALUE) + val->name_len + val->data_len; - } + (*value)->data_len = curval->data_len; + (*value)->data_blk = talloc_memdup(mem_ctx, (char *)curval+sizeof(RGDB_VALUE)+curval->name_len, curval->data_len); + (*value)->data_type = curval->type; return WERR_OK; } -static struct registry_ops reg_backend_w95 = { +static struct registry_operations reg_backend_w95 = { .name = "w95", - .open_registry = w95_open_reg, - .close_registry = w95_close_reg, - .get_hive = w95_open_root, - .fetch_values = w95_fetch_values, + .open_hive = w95_open_reg, + .get_value_by_index = w95_get_value_by_id, + .num_values = w95_num_values, .get_subkey_by_index = w95_get_subkey_by_index, }; diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index c46411ae31..524e538591 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -21,47 +21,57 @@ #include "includes.h" -static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) +static void writediff(struct registry_key *oldkey, struct registry_key *newkey, FILE *out) { int i; - REG_KEY *t1, *t2; - REG_VAL *v1, *v2; + struct registry_key *t1, *t2; + struct registry_value *v1, *v2; WERROR error1, error2; + TALLOC_CTX *mem_ctx = talloc_init("writediff"); - for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_subkey_by_index(oldkey, i, &t1)); i++) { - error2 = reg_key_get_subkey_by_name(newkey, reg_key_name(t1), &t2); + for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_subkey_by_index(mem_ctx, oldkey, i, &t1)); i++) { + error2 = reg_key_get_subkey_by_name(mem_ctx, newkey, t1->name, &t2); if(W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - fprintf(out, "-%s\n", reg_key_get_path(t1)+1); + fprintf(out, "-%s\n", t1->path+1); } else if(!W_ERROR_IS_OK(error2)) { DEBUG(0, ("Error occured while getting subkey by name: %d\n", W_ERROR_V(error2))); } } + talloc_destroy(mem_ctx); + if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { DEBUG(0, ("Error occured while getting subkey by index: %d\n", W_ERROR_V(error1))); return; } - for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_subkey_by_index(newkey, i, &t1)); i++) { - error2 = reg_key_get_subkey_by_name(oldkey, reg_key_name(t1), &t2); + mem_ctx = talloc_init("writediff"); + + for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_subkey_by_index(mem_ctx, newkey, i, &t1)); i++) { + error2 = reg_key_get_subkey_by_name(mem_ctx, oldkey, t1->name, &t2); if(W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - fprintf(out, "\n[%s]\n", reg_key_get_path(t1)+1); + fprintf(out, "\n[%s]\n", t1->path+1); } else if(!W_ERROR_IS_OK(error2)) { DEBUG(0, ("Error occured while getting subkey by name: %d\n", W_ERROR_V(error2))); } writediff(t2, t1, out); } + talloc_destroy(mem_ctx); + if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { DEBUG(0, ("Error occured while getting subkey by index: %d\n", W_ERROR_V(error1))); return; } - for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(newkey, i, &v1)); i++) { - error2 = reg_key_get_value_by_name(oldkey, reg_val_name(v1), &v2); - if ((W_ERROR_IS_OK(error2) && (reg_val_size(v2) != reg_val_size(v1) || memcmp(reg_val_data_blk(v1), reg_val_data_blk(v2), reg_val_size(v1)))) + + mem_ctx = talloc_init("writediff"); + + for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(mem_ctx, newkey, i, &v1)); i++) { + error2 = reg_key_get_value_by_name(mem_ctx, oldkey, v1->name, &v2); + if ((W_ERROR_IS_OK(error2) && (v2->data_len != v1->data_len || memcmp(v1->data_blk, v2->data_blk, v1->data_len))) || W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - fprintf(out, "\"%s\"=%s:%s\n", reg_val_name(v1), str_regtype(reg_val_type(v1)), reg_val_data_string(v1)); + fprintf(out, "\"%s\"=%s:%s\n", v1->name, str_regtype(v1->data_type), reg_val_data_string(mem_ctx, v1)); } if(!W_ERROR_IS_OK(error2) && !W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { @@ -69,22 +79,27 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) } } + talloc_destroy(mem_ctx); + if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { DEBUG(0, ("Error occured while getting value by index: %d\n", W_ERROR_V(error1))); return; } + mem_ctx = talloc_init("writediff"); - for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(oldkey, i, &v1)); i++) { - error2 = reg_key_get_value_by_name(newkey, reg_val_name(v1), &v2); + for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(mem_ctx, oldkey, i, &v1)); i++) { + error2 = reg_key_get_value_by_name(mem_ctx, newkey, v1->name, &v2); if(W_ERROR_IS_OK(error2)) { } else if(W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - fprintf(out, "\"%s\"=-\n", reg_val_name(v1)); + fprintf(out, "\"%s\"=-\n", v1->name); } else { DEBUG(0, ("Error occured while getting value by name: %d\n", W_ERROR_V(error2))); } } + talloc_destroy(mem_ctx); + if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { DEBUG(0, ("Error occured while getting value by index: %d\n", W_ERROR_V(error1))); return; @@ -100,8 +115,7 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) const char *credentials1= NULL, *credentials2 = NULL; char *outputfile = NULL; FILE *fd = stdout; - REG_HANDLE *h1, *h2; - REG_KEY *root1 = NULL, *root2; + struct registry_context *h1, *h2; int from_null = 0; int i; WERROR error, error2; @@ -114,6 +128,12 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) POPT_TABLEEND }; + + if (!lp_load(dyn_CONFIGFILE,True,False,False)) { + fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE); + } + + pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); while((opt = poptGetNextOpt(pc)) != -1) { @@ -140,7 +160,7 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) if(!backend1) backend1 = "dir"; - error = reg_open(backend1, location1, credentials1, &h1); + error = reg_open(&h1, backend1, location1, credentials1); if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location1, backend1); return 1; @@ -155,7 +175,7 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) if(!backend2) backend2 = "dir"; - error = reg_open(backend2, location2, credentials2, &h2); + error = reg_open(&h2, backend2, location2, credentials2); if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location2, backend2); return 1; @@ -176,20 +196,8 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out) error2 = error = WERR_OK; - for(i = 0; ; i++) { - if(backend1) error = reg_get_hive(h1, i, &root1); - else root1 = NULL; - - if(!W_ERROR_IS_OK(error)) break; - - if(backend2) error2 = reg_get_hive(h2, i, &root2); - else root2 = NULL; - - if(!W_ERROR_IS_OK(error2)) break; - - writediff(root1, root2, fd); - - if(!root1 && !root2) break; + for(i = 0; i < h1->num_hives && i < h2->num_hives; i++) { + writediff(h1->hives[i]->root, h2->hives[i]->root, fd); } fclose(fd); diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 7eddea2b93..1b33628a71 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -664,12 +664,13 @@ static CMD_FILE *cmd_file_create(const char *file) char *str_type(uint8_t type); -static int nt_apply_reg_command_file(REG_HANDLE *r, const char *cmd_file_name) +static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd_file_name) { CMD *cmd; BOOL modified = False; CMD_FILE *cmd_file = NULL; - REG_KEY *tmp = NULL; + TALLOC_CTX *mem_ctx = talloc_init("apply_cmd_file"); + struct registry_key *tmp = NULL; WERROR error; cmd_file = cmd_file_create(cmd_file_name); @@ -680,12 +681,12 @@ static int nt_apply_reg_command_file(REG_HANDLE *r, const char *cmd_file_name) */ switch (cmd->cmd) { case CMD_ADD_KEY: - error = reg_open_key_abs(r, cmd->key, &tmp); + error = reg_open_key_abs(mem_ctx, r, cmd->key, &tmp); /* If we found it, apply the other bits, else create such a key */ if (W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) { if(W_ERROR_IS_OK(reg_key_add_name_recursive_abs(r, cmd->key))) { - error = reg_open_key_abs(r, cmd->key, &tmp); + error = reg_open_key_abs(mem_ctx, r, cmd->key, &tmp); if(!W_ERROR_IS_OK(error)) { DEBUG(0, ("Error finding new key '%s' after it has been added\n", cmd->key)); continue; @@ -699,12 +700,12 @@ static int nt_apply_reg_command_file(REG_HANDLE *r, const char *cmd_file_name) while (cmd->val_count) { VAL_SPEC_LIST *val = cmd->val_spec_list; - REG_VAL *reg_val = NULL; + struct registry_value *reg_val = NULL; if (val->type == REG_DELETE) { - error = reg_key_get_value_by_name( tmp, val->name, ®_val); + error = reg_key_get_value_by_name( mem_ctx, tmp, val->name, ®_val); if(W_ERROR_IS_OK(error)) { - error = reg_val_del(reg_val); + error = reg_del_value(reg_val); } if(!W_ERROR_IS_OK(error)) { DEBUG(0, ("Error removing value '%s'\n", val->name)); @@ -712,7 +713,7 @@ static int nt_apply_reg_command_file(REG_HANDLE *r, const char *cmd_file_name) modified = True; } else { - if(!W_ERROR_IS_OK(reg_key_add_value(tmp, val->name, val->type, val->val, strlen(val->val)))) { + if(!W_ERROR_IS_OK(reg_val_set(tmp, val->name, val->type, val->val, strlen(val->val)))) { DEBUG(0, ("Error adding new value '%s'\n", val->name)); continue; } @@ -732,7 +733,7 @@ static int nt_apply_reg_command_file(REG_HANDLE *r, const char *cmd_file_name) * Find the key if it exists, and delete it ... */ - error = reg_open_key_abs(r, cmd->key, &tmp); + error = reg_open_key_abs(mem_ctx, r, cmd->key, &tmp); if(!W_ERROR_IS_OK(error)) { DEBUG(0, ("Unable to open key '%s'\n", cmd->key)); continue; @@ -760,7 +761,7 @@ static int nt_apply_reg_command_file(REG_HANDLE *r, const char *cmd_file_name) const char *credentials = NULL; const char *patch; const char *backend = "dir"; - REG_HANDLE *h; + struct registry_context *h; WERROR error; struct poptOption long_options[] = { POPT_AUTOHELP @@ -769,6 +770,12 @@ static int nt_apply_reg_command_file(REG_HANDLE *r, const char *cmd_file_name) POPT_TABLEEND }; + + if (!lp_load(dyn_CONFIGFILE,True,False,False)) { + fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE); + } + + pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); while((opt = poptGetNextOpt(pc)) != -1) { @@ -782,7 +789,7 @@ static int nt_apply_reg_command_file(REG_HANDLE *r, const char *cmd_file_name) return 1; } - error = reg_open(backend, location, credentials, &h); + error = reg_open(&h, backend, location, credentials); if(!h) { fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location, backend); return 1; @@ -794,7 +801,7 @@ static int nt_apply_reg_command_file(REG_HANDLE *r, const char *cmd_file_name) nt_apply_reg_command_file(h, patch); - reg_free(h); + talloc_destroy(h->mem_ctx); return 0; } diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 638ed70d5e..78fe36f1a0 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -33,96 +33,96 @@ * exit */ -static REG_KEY *cmd_info(REG_KEY *cur, int argc, char **argv) +static struct registry_key *cmd_info(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) { time_t last_mod; - printf("Name: %s\n", reg_key_name(cur)); - printf("Full path: %s\n", reg_key_get_path(cur)); - printf("Key Class: %s\n", reg_key_class(cur)); - last_mod = nt_time_to_unix(reg_key_last_modified(cur)); + printf("Name: %s\n", cur->name); + printf("Full path: %s\n", cur->path); + printf("Key Class: %s\n", cur->class_name); + last_mod = nt_time_to_unix(cur->last_mod); printf("Time Last Modified: %s\n", ctime(&last_mod)); /* FIXME: Security info */ return cur; } -static REG_KEY *cmd_pwd(REG_KEY *cur, int argc, char **argv) +static struct registry_key *cmd_pwd(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) { - printf("%s\n", reg_key_get_path_abs(cur)); + printf("%s\n", cur->path); return cur; } -static REG_KEY *cmd_set(REG_KEY *cur, int argc, char **argv) +static struct registry_key *cmd_set(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) { /* FIXME */ return NULL; } -static REG_KEY *cmd_ck(REG_KEY *cur, int argc, char **argv) +static struct registry_key *cmd_ck(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) { - REG_KEY *new = NULL; + struct registry_key *new = NULL; WERROR error; if(argc < 2) { new = cur; } else { - error = reg_open_key(cur, argv[1], &new); + error = reg_open_key(mem_ctx, cur, argv[1], &new); if(!W_ERROR_IS_OK(error)) { DEBUG(0, ("Error opening specified key: %s\n", win_errstr(error))); return NULL; } } - printf("Current path is: %s\n", reg_key_get_path_abs(new)); + printf("Current path is: %s\n", new->path); return new; } -static REG_KEY *cmd_ls(REG_KEY *cur, int argc, char **argv) +static struct registry_key *cmd_ls(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) { int i; WERROR error; - REG_VAL *value; - REG_KEY *sub; - for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(cur, i, &sub)); i++) { - printf("K %s\n", reg_key_name(sub)); + struct registry_value *value; + struct registry_key *sub; + for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(mem_ctx, cur, i, &sub)); i++) { + printf("K %s\n", sub->name); } if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { DEBUG(0, ("Error occured while browsing thru keys: %s\n", win_errstr(error))); } - for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(cur, i, &value)); i++) { - printf("V \"%s\" %s %s\n", reg_val_name(value), str_regtype(reg_val_type(value)), reg_val_data_string(value)); + for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(mem_ctx, cur, i, &value)); i++) { + printf("V \"%s\" %s %s\n", value->name, str_regtype(value->data_type), reg_val_data_string(mem_ctx, value)); } return NULL; } -static REG_KEY *cmd_mkkey(REG_KEY *cur, int argc, char **argv) +static struct registry_key *cmd_mkkey(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) { - REG_KEY *tmp; + struct registry_key *tmp; if(argc < 2) { fprintf(stderr, "Usage: mkkey \n"); return NULL; } - if(!W_ERROR_IS_OK(reg_key_add_name(cur, argv[1], 0, NULL, &tmp))) { + if(!W_ERROR_IS_OK(reg_key_add_name(mem_ctx, cur, argv[1], 0, NULL, &tmp))) { fprintf(stderr, "Error adding new subkey '%s'\n", argv[1]); return NULL; } - fprintf(stderr, "Successfully added new subkey '%s' to '%s'\n", argv[1], reg_key_get_path_abs(cur)); + fprintf(stderr, "Successfully added new subkey '%s' to '%s'\n", argv[1], cur->path); return NULL; } -static REG_KEY *cmd_rmkey(REG_KEY *cur, int argc, char **argv) +static struct registry_key *cmd_rmkey(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) { - REG_KEY *key; + struct registry_key *key; if(argc < 2) { fprintf(stderr, "Usage: rmkey \n"); return NULL; } - if(!W_ERROR_IS_OK(reg_open_key(cur, argv[1], &key))) { + if(!W_ERROR_IS_OK(reg_open_key(mem_ctx, cur, argv[1], &key))) { fprintf(stderr, "No such subkey '%s'\n", argv[1]); return NULL; } @@ -136,20 +136,20 @@ static REG_KEY *cmd_rmkey(REG_KEY *cur, int argc, char **argv) return NULL; } -static REG_KEY *cmd_rmval(REG_KEY *cur, int argc, char **argv) +static struct registry_key *cmd_rmval(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) { - REG_VAL *val; + struct registry_value *val; if(argc < 2) { fprintf(stderr, "Usage: rmval \n"); return NULL; } - if(!W_ERROR_IS_OK(reg_key_get_value_by_name(cur, argv[1], &val))) { + if(!W_ERROR_IS_OK(reg_key_get_value_by_name(mem_ctx, cur, argv[1], &val))) { fprintf(stderr, "No such value '%s'\n", argv[1]); return NULL; } - if(!W_ERROR_IS_OK(reg_val_del(val))) { + if(!W_ERROR_IS_OK(reg_del_value(val))) { fprintf(stderr, "Error deleting value '%s'\n", argv[1]); } else { fprintf(stderr, "Successfully deleted value '%s'\n", argv[1]); @@ -158,38 +158,33 @@ static REG_KEY *cmd_rmval(REG_KEY *cur, int argc, char **argv) return NULL; } -static REG_KEY *cmd_hive(REG_KEY *cur, int argc, char **argv) +static struct registry_key *cmd_hive(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) { int i; - WERROR error = WERR_OK; - for(i = 0; W_ERROR_IS_OK(error); i++) { - REG_KEY *hive; - error = reg_get_hive(reg_key_handle(cur), i, &hive); - if(!W_ERROR_IS_OK(error)) break; + for(i = 0; i < cur->hive->reg_ctx->num_hives; i++) { if(argc == 1) { - printf("%s\n", reg_key_name(hive)); - } else if(!strcmp(reg_key_name(hive), argv[1])) { - return hive; + printf("%s\n", cur->hive->reg_ctx->hives[i]->name); + } else if(!strcmp(cur->hive->reg_ctx->hives[i]->name, argv[1])) { + return cur->hive->reg_ctx->hives[i]->root; } - reg_key_free(hive); } return NULL; } -static REG_KEY *cmd_exit(REG_KEY *cur, int argc, char **argv) +static struct registry_key *cmd_exit(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) { exit(0); return NULL; } -static REG_KEY *cmd_help(REG_KEY *, int, char **); +static struct registry_key *cmd_help(TALLOC_CTX *mem_ctx, struct registry_key *, int, char **); struct { const char *name; const char *alias; const char *help; - REG_KEY *(*handle)(REG_KEY *, int argc, char **argv); + struct registry_key *(*handle)(TALLOC_CTX *mem_ctx, struct registry_key *, int argc, char **argv); } regshell_cmds[] = { {"ck", "cd", "Change current key", cmd_ck }, {"ch", "hive", "Change current hive", cmd_hive }, @@ -205,7 +200,7 @@ struct { {NULL } }; -static REG_KEY *cmd_help(REG_KEY *cur, int argc, char **argv) +static struct registry_key *cmd_help(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) { int i; printf("Available commands:\n"); @@ -215,7 +210,7 @@ static REG_KEY *cmd_help(REG_KEY *cur, int argc, char **argv) return NULL; } -static REG_KEY *process_cmd(REG_KEY *k, char *line) +static struct registry_key *process_cmd(TALLOC_CTX *mem_ctx, struct registry_key *k, char *line) { int argc; char **argv = NULL; @@ -229,7 +224,7 @@ static REG_KEY *process_cmd(REG_KEY *k, char *line) 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(k, argc, argv); + return regshell_cmds[i].handle(mem_ctx, k, argc, argv); } } @@ -240,7 +235,7 @@ static REG_KEY *process_cmd(REG_KEY *k, char *line) #define MAX_COMPLETIONS 100 -static REG_KEY *current_key = NULL; +static struct registry_key *current_key = NULL; static char **reg_complete_command(const char *text, int end) { @@ -295,10 +290,11 @@ cleanup: static char **reg_complete_key(const char *text, int end) { - REG_KEY *subkey; + struct registry_key *subkey; int i, j = 0; int len; char **matches; + TALLOC_CTX *mem_ctx; /* Complete argument */ matches = (char **)malloc(sizeof(matches[0])*MAX_COMPLETIONS); @@ -306,22 +302,24 @@ static char **reg_complete_key(const char *text, int end) matches[0] = NULL; len = strlen(text); + mem_ctx = talloc_init("completion"); for(i = 0; j < MAX_COMPLETIONS-1; i++) { - WERROR status = reg_key_get_subkey_by_index(current_key, i, &subkey); + WERROR status = reg_key_get_subkey_by_index(mem_ctx, current_key, i, &subkey); if(W_ERROR_IS_OK(status)) { - if(!strncmp(text, reg_key_name(subkey), len)) { - matches[j] = strdup(reg_key_name(subkey)); + if(!strncmp(text, subkey->name, len)) { + matches[j] = strdup(subkey->name); j++; } - reg_key_free(subkey); } else if(W_ERROR_EQUAL(status, WERR_NO_MORE_ITEMS)) { break; } else { printf("Error creating completion list: %s\n", win_errstr(status)); + talloc_destroy(mem_ctx); return NULL; } } matches[j] = NULL; + talloc_destroy(mem_ctx); return matches; } @@ -341,10 +339,11 @@ static char **reg_completion(const char *text, int start, int end) int opt; const char *backend = "dir"; const char *credentials = NULL; - REG_KEY *curkey = NULL; + struct registry_key *curkey = NULL; poptContext pc; WERROR error; - REG_HANDLE *h; + TALLOC_CTX *mem_ctx = talloc_init("cmd"); + struct registry_context *h; struct poptOption long_options[] = { POPT_AUTOHELP POPT_COMMON_SAMBA @@ -352,13 +351,19 @@ static char **reg_completion(const char *text, int start, int end) {"credentials", 'c', POPT_ARG_STRING, &credentials, 0, "credentials", NULL}, POPT_TABLEEND }; + + + if (!lp_load(dyn_CONFIGFILE,True,False,False)) { + fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE); + } + pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); while((opt = poptGetNextOpt(pc)) != -1) { } - error = reg_open(backend, poptPeekArg(pc), credentials, &h); + error = reg_open(&h, backend, poptPeekArg(pc), credentials); if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open '%s' with backend '%s'\n", poptGetArg(pc), backend); return 1; @@ -367,14 +372,16 @@ static char **reg_completion(const char *text, int start, int end) setup_logging("regtree", True); - error = reg_get_hive(h, 0, &curkey); - - if(!W_ERROR_IS_OK(error)) return 1; + curkey = h->hives[0]->root; while(True) { char *line, *prompt; - asprintf(&prompt, "%s> ", reg_key_get_path_abs(curkey)); + if(curkey->hive->name) { + asprintf(&prompt, "%s:%s> ", curkey->hive->name, curkey->path); + } else { + asprintf(&prompt, "%s> ", curkey->path); + } current_key = curkey; /* No way to pass a void * pointer via readline :-( */ @@ -384,10 +391,11 @@ static char **reg_completion(const char *text, int start, int end) break; if(line[0] != '\n') { - REG_KEY *new = process_cmd(curkey, line); + struct registry_key *new = process_cmd(mem_ctx, curkey, line); if(new)curkey = new; } } + talloc_destroy(mem_ctx); return 0; } diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index b1ca9b3fb2..9748ca3438 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -21,39 +21,45 @@ #include "includes.h" -static void print_tree(int l, REG_KEY *p, int fullpath, int novals) +static void print_tree(int l, struct registry_key *p, int fullpath, int novals) { - REG_KEY *subkey; - REG_VAL *value; + struct registry_key *subkey; + struct registry_value *value; WERROR error; int i; + TALLOC_CTX *mem_ctx; for(i = 0; i < l; i++) putchar(' '); - if(fullpath) printf("%s\n", reg_key_get_path_abs(p)); - else printf("%s\n", reg_key_name(p)); + + /* Hive name */ + if(p->hive->root == p) printf("%s\n", p->hive->name); + else if(!p->name) printf("\n"); + else if(fullpath) printf("%s\n", p->path); + else printf("%s\n", p->name); - for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(p, i, &subkey)); i++) { + mem_ctx = talloc_init("print_tree"); + for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(mem_ctx, p, i, &subkey)); i++) { print_tree(l+1, subkey, fullpath, novals); - reg_key_free(subkey); } + talloc_destroy(mem_ctx); if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while fetching subkeys for '%s': %s\n", reg_key_get_path_abs(p), win_errstr(error))); + DEBUG(0, ("Error occured while fetching subkeys for '%s': %s\n", p->path, win_errstr(error))); } if(!novals) { - for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(p, i, &value)); i++) { + mem_ctx = talloc_init("print_tree"); + for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(mem_ctx, p, i, &value)); i++) { int j; char *desc; for(j = 0; j < l+1; j++) putchar(' '); - desc = reg_val_description(value); + desc = reg_val_description(mem_ctx, value); printf("%s\n", desc); - free(desc); - reg_val_free(value); } + talloc_destroy(mem_ctx); if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while fetching values for '%s': %s\n", reg_key_get_path_abs(p), win_errstr(error))); + DEBUG(0, ("Error occured while fetching values for '%s': %s\n", p->path, win_errstr(error))); } } } @@ -64,8 +70,7 @@ static void print_tree(int l, REG_KEY *p, int fullpath, int novals) const char *backend = "dir"; const char *credentials = NULL; poptContext pc; - REG_KEY *root; - REG_HANDLE *h; + struct registry_context *h; WERROR error; int fullpath = 0, no_values = 0; struct poptOption long_options[] = { @@ -77,6 +82,12 @@ static void print_tree(int l, REG_KEY *p, int fullpath, int novals) POPT_TABLEEND }; + + if (!lp_load(dyn_CONFIGFILE,True,False,False)) { + fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE); + } + + pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); while((opt = poptGetNextOpt(pc)) != -1) { @@ -84,7 +95,7 @@ static void print_tree(int l, REG_KEY *p, int fullpath, int novals) setup_logging("regtree", True); - error = reg_open(backend, poptPeekArg(pc), credentials, &h); + error = reg_open(&h, backend, poptPeekArg(pc), credentials); if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open '%s' with backend '%s':%s \n", poptGetArg(pc), backend, win_errstr(error)); return 1; @@ -93,11 +104,8 @@ static void print_tree(int l, REG_KEY *p, int fullpath, int novals) error = WERR_OK; - for(i = 0; W_ERROR_IS_OK(error); i++) { - error = reg_get_hive(h, i, &root); - if(!W_ERROR_IS_OK(error)) return 1; - - print_tree(0, root, fullpath, no_values); + for(i = 0; i < h->num_hives; i++) { + print_tree(0, h->hives[i]->root, fullpath, no_values); } return 0; -- cgit From 368802bc867f544355b5a8c4bc5e4b6ab47dd408 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 25 Sep 2004 11:17:09 +0000 Subject: r2623: don't do pointer arithmetic on void*, as it doesn't work with non-GNU compilers (This used to be commit c2be7b696ccb338df06a5212ed1f7b78e4c116c2) --- source4/lib/registry/common/reg_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index 21c925deab..c7354fe909 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -54,7 +54,7 @@ char *reg_val_data_string(TALLOC_CTX *mem_ctx, struct registry_value *v) asciip = ret; for (i=0; idata_len; i++) { int str_rem = v->data_len * 3 - (asciip - ret); - asciip += snprintf(asciip, str_rem, "%02x", *(uint8_t *)(v->data_blk+i)); + asciip += snprintf(asciip, str_rem, "%02x", *(uint8_t *)(((char *)v->data_blk)+i)); if (i < v->data_len && str_rem > 0) *asciip = ' '; asciip++; } -- cgit From 5b44130afad1bb1764d986de3ef0e8e04b0e7357 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Sep 2004 01:36:19 +0000 Subject: r2671: we're getting too many errors caused by the talloc_realloc() API not taking a context (so when you pass a NULL pointer you end up with memory in a top level context). Fixed it by changing the API to take a context. The context is only used if the pointer you are reallocing is NULL. (This used to be commit 8dc23821c9f54b2f13049b5e608a0cafb81aa540) --- source4/lib/registry/common/reg_interface.c | 2 +- source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index ec6188be71..ba92369194 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -190,7 +190,7 @@ WERROR reg_import_hive(struct registry_context *h, const char *backend, const ch /* Add hive to context */ h->num_hives++; - h->hives = talloc_realloc_p(h->hives, struct registry_hive *, h->num_hives); + h->hives = talloc_realloc_p(h, h->hives, struct registry_hive *, h->num_hives); h->hives[h->num_hives-1] = ret; return WERR_OK; 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 1c887fc411..3dd73162be 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -90,7 +90,7 @@ WERROR rpc_list_hives (TALLOC_CTX *mem_ctx, const char *location, const char *cr int i = 0; *hives = talloc_p(mem_ctx, char *); for(i = 0; known_hives[i].name; i++) { - *hives = talloc_realloc_p(*hives, char *, i+2); + *hives = talloc_realloc_p(mem_ctx, *hives, char *, i+2); (*hives)[i] = talloc_strdup(mem_ctx, known_hives[i].name); } (*hives)[i] = NULL; -- cgit From d13bbcf9e35deed8a7ad2b4e37bea56832ba3563 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Sep 2004 04:00:23 +0000 Subject: r2672: don't call a variable "dup" as that conflicts with a standard system call name (This used to be commit 015db2ed8cdde6d6eb79857cb9b6d72185382acc) --- source4/lib/registry/common/reg_interface.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index ba92369194..c55ecd5a41 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -482,10 +482,10 @@ WERROR reg_key_add_name_recursive(struct registry_key *parent, const char *path) { struct registry_key *cur, *prevcur = parent; WERROR error = WERR_OK; - char *dup, *begin, *end; + char *dups, *begin, *end; TALLOC_CTX *mem_ctx = talloc_init("add_recursive"); - begin = dup = strdup(path); + begin = dups = strdup(path); while(1) { end = strchr(begin, '\\'); @@ -513,7 +513,7 @@ WERROR reg_key_add_name_recursive(struct registry_key *parent, const char *path) begin = end+1; prevcur = cur; } - SAFE_FREE(dup); + SAFE_FREE(dups); talloc_destroy(mem_ctx); return error; } -- cgit From f63e3ae1f74966ba2e6eeb4a3830b81d3df5c67f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 27 Sep 2004 11:38:36 +0000 Subject: r2686: remove unused gtk+ check metze (This used to be commit d1e8b340a9942553ec7f281affd11ea4315ac448) --- source4/lib/registry/config.m4 | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index 4fdde67faf..f3681e7828 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -15,8 +15,6 @@ if test t$SMB_EXT_LIB_ENABLE_gconf = tYES; then SMB_MODULE_DEFAULT(registry_gconf, STATIC) fi -SMB_EXT_LIB_FROM_PKGCONFIG(gtk, [glib-2.0 gtk+-2.0]) - SMB_MODULE_MK(registry_nt4, REGISTRY, STATIC, lib/registry/config.mk) SMB_MODULE_MK(registry_w95, REGISTRY, STATIC, lib/registry/config.mk) SMB_MODULE_MK(registry_dir, REGISTRY, STATIC, lib/registry/config.mk) -- cgit From 7d32679e9683c81aca538f0267684332a28a286f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Oct 2004 08:13:00 +0000 Subject: r2857: this commit gets rid of smb_ucs2_t, wpstring and fpstring, plus lots of associated functions. The motivation for this change was to avoid having to convert to/from ucs2 strings for so many operations. Doing that was slow, used many static buffers, and was also incorrect as it didn't cope properly with unicode codepoints above 65536 (which could not be represented correctly as smb_ucs2_t chars) The two core functions that allowed this change are next_codepoint() and push_codepoint(). These functions allow you to correctly walk a arbitrary multi-byte string a character at a time without converting the whole string to ucs2. While doing this cleanup I also fixed several ucs2 string handling bugs. See the commit for details. The following code (which counts the number of occuraces of 'c' in a string) shows how to use the new interface: size_t count_chars(const char *s, char c) { size_t count = 0; while (*s) { size_t size; codepoint_t c2 = next_codepoint(s, &size); if (c2 == c) count++; s += size; } return count; } (This used to be commit 814881f0e50019196b3aa9fbe4aeadbb98172040) --- source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index c271c55991..14fff5b60d 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -1029,7 +1029,7 @@ static WERROR nk_to_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, NK_HDR *nk uint_t nk_id; SK_HDR *sk_hdr; int type; - char key_name[1024], cls_name[1024]; + char key_name[1024]; if (!nk_hdr) return WERR_INVALID_PARAM; @@ -1086,16 +1086,16 @@ static WERROR nk_to_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, NK_HDR *nk */ if (clsname_len) { /* Just print in Ascii for now */ - smb_ucs2_t *clsnamep; + void *clsnamep; int clsnam_off; clsnam_off = IVAL(&nk_hdr->clsnam_off,0); - clsnamep = (smb_ucs2_t *)LOCN(regf->base, clsnam_off); + clsnamep = LOCN(regf->base, clsnam_off); DEBUG(2, ("Class Name Offset: %0X\n", clsnam_off)); pull_ucs2_talloc(mem_ctx, &tmp->class_name, clsnamep); - DEBUGADD(2,(" Class Name: %s\n", cls_name)); + DEBUGADD(2,(" Class Name: %s\n", tmp->class_name)); } -- cgit From ffa0cf3af05c82df558bb2484e04a8f2220f6ea0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 10 Oct 2004 23:52:06 +0000 Subject: r2897: Fix double registration (of the registry subsystem) bug (This used to be commit f4860afc486da9fcd43798c81181d01eb0120a59) --- source4/lib/registry/common/reg_interface.c | 40 +++++++++++++++++------------ 1 file changed, 24 insertions(+), 16 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index c55ecd5a41..28025e4d84 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -37,6 +37,7 @@ NTSTATUS registry_register(const void *_function) struct reg_init_function_entry *entry = backends; if (!functions || !functions->name) { + DEBUG(0, ("Invalid arguments while registering registry backend\n")); return NT_STATUS_INVALID_PARAMETER; } @@ -56,30 +57,37 @@ NTSTATUS registry_register(const void *_function) return NT_STATUS_OK; } +static BOOL registry_init(void) +{ + static BOOL initialised; + NTSTATUS status; + + if(initialised) { + return True; + } + + status = register_subsystem("registry", registry_register); + if (NT_STATUS_IS_ERR(status)) { + DEBUG(0, ("Error registering registry subsystem: %s\n", nt_errstr(status))); + return False; + } + + initialised = True; + static_init_registry; + return True; +} + /* Find a backend in the list of available backends */ static struct reg_init_function_entry *reg_find_backend_entry(const char *name) { struct reg_init_function_entry *entry; - static BOOL reg_first_init = True; - NTSTATUS status; - if(reg_first_init) { - status = register_subsystem("registry", registry_register); - if (NT_STATUS_IS_ERR(status)) { - DEBUG(0, ("Error registering registry subsystem: %s\n", nt_errstr(status))); - /* Don't try the initialisation again */ - reg_first_init = False; - return NULL; - } - - static_init_registry; - reg_first_init = False; - } + if(registry_init() == False) return NULL; entry = backends; while(entry) { - if (strcmp(entry->functions->name, name)==0) return entry; + if (strcmp(entry->functions->name, name) == 0) return entry; entry = entry->next; } @@ -186,7 +194,7 @@ WERROR reg_import_hive(struct registry_context *h, const char *backend, const ch ret->root->hive = ret; ret->root->name = NULL; - ret->root->path = ""; + ret->root->path = talloc_strdup(mem_ctx, ""); /* Add hive to context */ h->num_hives++; -- cgit From e2a47719097291dac9e2ff33fbb1d1b26f26517c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 11 Oct 2004 00:29:55 +0000 Subject: r2898: - Support enumerating remote registry values - Some LDB updates (This used to be commit 4b5bf739f5a8f39ff3633d738f6de42681a6b30f) --- .../lib/registry/reg_backend_ldb/reg_backend_ldb.c | 80 ++++++++++------------ .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 63 +++++++++-------- 2 files changed, 67 insertions(+), 76 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index e0f65f2c37..cc0432d9ea 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -40,7 +40,7 @@ static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char * ret = talloc_asprintf_append(ret, "key=%s,", keyname); if(begin) { - begin[0] = '\0'; + *begin = '\0'; end = begin-1; } else { end = NULL; @@ -50,6 +50,10 @@ static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char * SAFE_FREE(mypath); ret[strlen(ret)-1] = '\0'; + + printf("RETURNING: %s\n", ret); + + if(strlen(ret) == 0) return NULL; return ret; } @@ -62,40 +66,19 @@ static int ldb_close_registry(void *data) } -/* - * Saves the dn as private_data for every key/val - */ - -static WERROR ldb_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *hive, struct registry_key **k) -{ - struct ldb_context *c; - - if (!hive->location) return WERR_INVALID_PARAM; - c = ldb_connect(hive->location, 0, NULL); - - ldb_set_debug_stderr(c); - - - if(!c) return WERR_FOOBAR; - hive->backend_data = c; - talloc_set_destructor(c, ldb_close_registry); - - return WERR_OK; -} static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, struct registry_key *p, const char *name, uint32_t access_mask, SEC_DESC *sec, struct registry_key **new) { return WERR_NOT_SUPPORTED; } -#if 0 -FIXME -static WERROR ldb_fetch_subkeys(struct registry_key *k, int *count, struct registry_key ***subkeys) +static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_key **subkey) { struct ldb_context *c = k->hive->backend_data; - int ret, i, j; + int ret; struct ldb_message **msg; + struct ldb_message_element *el; ret = ldb_search(c, (char *)k->backend_data, LDB_SCOPE_ONELEVEL, "(key=*)", NULL,&msg); @@ -104,27 +87,19 @@ static WERROR ldb_fetch_subkeys(struct registry_key *k, int *count, struct regis return WERR_FOOBAR; } - *subkeys = talloc_array_p(k->mem_ctx, struct registry_key *, ret); - j = 0; - for(i = 0; i < ret; i++) { - struct ldb_message_element *el; - char *name; - el = ldb_msg_find_element(msg[i], "key"); - - name = el->values[0].data; - - /* Dirty hack to circumvent ldb_tdb bug */ - if(k->backend_data && !strcmp(msg[i]->dn, (char *)k->backend_data)) continue; - - (*subkeys)[j] = reg_key_new_rel(name, k, NULL); - (*subkeys)[j]->backend_data = talloc_strdup((*subkeys)[j]->mem_ctx, msg[i]->dn); - j++; - } - *count = j; + if(idx >= ret) return WERR_NO_MORE_ITEMS; + + el = ldb_msg_find_element(msg[idx], "key"); + + *subkey = talloc_p(mem_ctx, struct registry_key); + (*subkey)->name = talloc_strdup(mem_ctx, el->values[0].data); + (*subkey)->backend_data = talloc_strdup(mem_ctx, msg[idx]->dn); + printf("Retrieved: %s\n", (*subkey)->backend_data); ldb_search_free(c, msg); return WERR_OK; } +#if 0 static WERROR ldb_fetch_values(struct registry_key *k, int *count, REG_VAL ***values) { @@ -171,7 +146,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const c int ret; ldap_path = reg_path_to_ldb(mem_ctx, name, NULL); - ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "*", NULL,&msg); + ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL,&msg); if(ret == 0) { return WERR_NO_MORE_ITEMS; @@ -181,19 +156,36 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const c } *key = talloc_p(mem_ctx, struct registry_key); - /* FIXME */ + (*key)->name = talloc_strdup(mem_ctx, strrchr(name, '\\')); + (*key)->backend_data = talloc_strdup(mem_ctx, msg[0]->dn); + printf("Retrieved: %s\n", (*key)->backend_data); ldb_search_free(c, msg); return WERR_OK; } +static WERROR ldb_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *hive, struct registry_key **k) +{ + struct ldb_context *c; + + if (!hive->location) return WERR_INVALID_PARAM; + c = ldb_connect(hive->location, 0, NULL); + + if(!c) return WERR_FOOBAR; + ldb_set_debug_stderr(c); + hive->backend_data = c; + + return ldb_open_key(mem_ctx, hive, "", k); +} + static struct registry_operations reg_backend_ldb = { .name = "ldb", .open_hive = ldb_open_hive, .open_key = ldb_open_key, /* .fetch_subkeys = ldb_fetch_subkeys, .fetch_values = ldb_fetch_values,*/ + .get_subkey_by_index = ldb_get_subkey_by_id, .add_key = ldb_add_key, }; 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 3dd73162be..db1ab9364e 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -198,55 +198,54 @@ static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const c static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_value **value) { struct rpc_key_data *mykeydata = parent->backend_data; - uint32_t requested_len = 0; WERROR error; - + struct winreg_EnumValue r; + uint32 type, len1, len2 = 0; + struct EnumValueIn buf_name, buf_val; + NTSTATUS status; + if(mykeydata->num_values == -1) { error = rpc_query_key(parent); if(!W_ERROR_IS_OK(error)) return error; } - requested_len = mykeydata->max_valdatalen; - -#if 0 /* EnumValue is not working yet ... */ + len1 = mykeydata->max_valdatalen; + r.in.handle = &mykeydata->pol; r.in.enum_index = n; - r.in.type = r.out.type = &type; - r.in.requested_len = r.out.requested_len = &requested_len; - r.in.returned_len = r.out.returned_len = &returned_len; - vn.max_len = mykeydata->max_valnamelen * 2; - vn.len = 0; - vn.buf = NULL; - if(vn.max_len > 0) { - vn.len = 0; - vn.max_len = mykeydata->max_valnamelen*2; - /* FIXME: we should not point a 'char *' to a const buffer!!! --metze*/ - vn.buf = ""; - } - r.in.name = r.out.name = &vn; - vb.max_len = mykeydata->max_valdatalen; - vb.offset = 0x0; - vb.len = 0x0; - vb.buffer = talloc_array_p(mem_ctx, uint8, mykeydata->max_valdatalen); - r.in.value = r.out.value = &vb; - - status = dcerpc_winreg_EnumValue((struct dcerpc_pipe *)parent->handle->backend_data, parent->mem_ctx, &r); + r.in.name_in.len = 0; + r.in.name_in.max_len = mykeydata->max_valnamelen * 2; + buf_name.max_len = mykeydata->max_valnamelen; + buf_name.offset = 0; + buf_name.len = 0; + r.in.name_in.buffer = &buf_name; + r.in.type = &type; + buf_val.max_len = mykeydata->max_valdatalen; + buf_val.offset = 0; + buf_val.len = 0; + r.in.value_in = &buf_val; + r.in.value_len1 = &len1; + r.in.value_len2 = &len2; + + + status = dcerpc_winreg_EnumValue((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r); if(NT_STATUS_IS_ERR(status)) { DEBUG(0, ("Error in EnumValue: %s\n", nt_errstr(status))); + return WERR_GENERAL_FAILURE; } if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { - *value = reg_val_new(parent, NULL); - (*value)->name = r.out.name->buf; + *value = talloc_p(mem_ctx, struct registry_value); + (*value)->parent = parent; + (*value)->name = talloc_strdup(mem_ctx, r.out.name_out.name); + printf("Type: %d\n", type); (*value)->data_type = type; - (*value)->data_len = r.out.value->len; - (*value)->data_blk = r.out.value->buffer; - exit(1); + (*value)->data_len = r.out.value_out->buffer.length; + (*value)->data_blk = talloc_memdup(mem_ctx, r.out.value_out->buffer.data, r.out.value_out->buffer.length); return WERR_OK; } -#endif - return WERR_NOT_SUPPORTED; + return r.out.result; } static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_key **subkey) -- cgit From 6df5d77c893a844c74af8c879986150742b1bc58 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 11 Oct 2004 11:52:44 +0000 Subject: r2911: Fix bug in opening relative keys (This used to be commit e7c256a92cc6cbe1cd6cc11a8fb37feba272d01c) --- .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'source4/lib/registry') 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 db1ab9364e..fd81983227 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -169,7 +169,8 @@ static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) return r.out.result; } -static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **key) + +static WERROR rpc_open_rel_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const char *name, struct registry_key **key) { struct rpc_key_data *mykeydata; struct winreg_OpenKey r; @@ -184,17 +185,22 @@ static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const c /* Then, open the handle using the hive */ memset(&r, 0, sizeof(struct winreg_OpenKey)); - r.in.handle = &(((struct rpc_key_data *)h->root->backend_data)->pol); + r.in.handle = &(((struct rpc_key_data *)h->backend_data)->pol); init_winreg_String(&r.in.keyname, name); r.in.unknown = 0x00000000; r.in.access_mask = 0x02000000; r.out.handle = &mykeydata->pol; - dcerpc_winreg_OpenKey((struct dcerpc_pipe *)(h->backend_data), mem_ctx, &r); + dcerpc_winreg_OpenKey((struct dcerpc_pipe *)(h->hive->backend_data), mem_ctx, &r); return r.out.result; } +static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **key) +{ + return rpc_open_rel_key(mem_ctx, h->root, name, key); +} + static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_value **value) { struct rpc_key_data *mykeydata = parent->backend_data; @@ -226,6 +232,7 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *p r.in.value_in = &buf_val; r.in.value_len1 = &len1; r.in.value_len2 = &len2; + r.out.type = &type; status = dcerpc_winreg_EnumValue((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r); @@ -238,7 +245,6 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *p *value = talloc_p(mem_ctx, struct registry_value); (*value)->parent = parent; (*value)->name = talloc_strdup(mem_ctx, r.out.name_out.name); - printf("Type: %d\n", type); (*value)->data_type = type; (*value)->data_len = r.out.value_out->buffer.length; (*value)->data_blk = talloc_memdup(mem_ctx, r.out.value_out->buffer.data, r.out.value_out->buffer.length); @@ -271,9 +277,7 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key * r.in.key_name_len = r.out.key_name_len = 0; status = dcerpc_winreg_EnumKey((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r); if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { - if(parent->hive->root == parent) - return rpc_open_key(mem_ctx, parent->hive, talloc_strdup(mem_ctx, r.out.out_name->name), subkey); - return rpc_open_key(mem_ctx, parent->hive, talloc_asprintf(mem_ctx, "%s\\%s", parent->path, r.out.out_name->name), subkey); + return rpc_open_rel_key(mem_ctx, parent, talloc_strdup(mem_ctx, r.out.out_name->name), subkey); } return r.out.result; @@ -298,7 +302,7 @@ static WERROR rpc_query_key(struct registry_key *k) talloc_destroy(mem_ctx); if (!NT_STATUS_IS_OK(status)) { - printf("QueryInfoKey failed - %s\n", nt_errstr(status)); + DEBUG(1, ("QueryInfoKey failed - %s\n", nt_errstr(status))); return ntstatus_to_werror(status); } -- cgit From aed95ba66f29b9536e99027fab5327548b984b70 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 11 Oct 2004 13:57:30 +0000 Subject: r2913: - Don't print hive name if it is NULL (regtree) - Initialise hive name (reg_interface) - Fix LDB backend (enumerating keys works now!) (This used to be commit 5086d6b2494f236ef67096b2dd4da4f7402a65c5) --- source4/lib/registry/common/reg_interface.c | 1 + source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c | 9 +-------- source4/lib/registry/tools/regtree.c | 11 +++++++---- 3 files changed, 9 insertions(+), 12 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 28025e4d84..16edadfcbb 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -185,6 +185,7 @@ WERROR reg_import_hive(struct registry_context *h, const char *backend, const ch ret->functions = entry->functions; ret->backend_data = NULL; ret->reg_ctx = h; + ret->name = NULL; werr = entry->functions->open_hive(mem_ctx, ret, &ret->root); diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index cc0432d9ea..7e228412d5 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -51,8 +51,6 @@ static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char * ret[strlen(ret)-1] = '\0'; - printf("RETURNING: %s\n", ret); - if(strlen(ret) == 0) return NULL; return ret; @@ -65,9 +63,6 @@ static int ldb_close_registry(void *data) return 0; } - - - static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, struct registry_key *p, const char *name, uint32_t access_mask, SEC_DESC *sec, struct registry_key **new) { return WERR_NOT_SUPPORTED; @@ -94,7 +89,6 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, *subkey = talloc_p(mem_ctx, struct registry_key); (*subkey)->name = talloc_strdup(mem_ctx, el->values[0].data); (*subkey)->backend_data = talloc_strdup(mem_ctx, msg[idx]->dn); - printf("Retrieved: %s\n", (*subkey)->backend_data); ldb_search_free(c, msg); return WERR_OK; @@ -158,7 +152,6 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const c *key = talloc_p(mem_ctx, struct registry_key); (*key)->name = talloc_strdup(mem_ctx, strrchr(name, '\\')); (*key)->backend_data = talloc_strdup(mem_ctx, msg[0]->dn); - printf("Retrieved: %s\n", (*key)->backend_data); ldb_search_free(c, msg); @@ -183,7 +176,7 @@ static struct registry_operations reg_backend_ldb = { .name = "ldb", .open_hive = ldb_open_hive, .open_key = ldb_open_key, -/* .fetch_subkeys = ldb_fetch_subkeys, +/* .fetch_values = ldb_fetch_values,*/ .get_subkey_by_index = ldb_get_subkey_by_id, .add_key = ldb_add_key, diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 9748ca3438..bc0055a891 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -32,10 +32,13 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) for(i = 0; i < l; i++) putchar(' '); /* Hive name */ - if(p->hive->root == p) printf("%s\n", p->hive->name); - else if(!p->name) printf("\n"); - else if(fullpath) printf("%s\n", p->path); - else printf("%s\n", p->name); + if(p->hive->root == p) { + if(p->hive->name) printf("%s\n", p->hive->name); else printf("\n"); + } else { + if(!p->name) printf("\n"); + if(fullpath) printf("%s\n", p->path); + else printf("%s\n", p->name); + } mem_ctx = talloc_init("print_tree"); for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(mem_ctx, p, i, &subkey)); i++) { -- cgit From fe8aaa5d07eaeb54954a9a36207dbc02a6f39504 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 11 Oct 2004 14:07:20 +0000 Subject: r2914: ... and support enumerating values (data is not handled yet, only the names) (This used to be commit b3bc055ac73ff239c2b267717ee91669ecdd4c9b) --- .../lib/registry/reg_backend_ldb/reg_backend_ldb.c | 41 ++++++---------------- 1 file changed, 11 insertions(+), 30 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index 7e228412d5..d76b7715da 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -63,11 +63,6 @@ static int ldb_close_registry(void *data) return 0; } -static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, struct registry_key *p, const char *name, uint32_t access_mask, SEC_DESC *sec, struct registry_key **new) -{ - return WERR_NOT_SUPPORTED; -} - static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_key **subkey) { struct ldb_context *c = k->hive->backend_data; @@ -93,13 +88,13 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, ldb_search_free(c, msg); return WERR_OK; } -#if 0 -static WERROR ldb_fetch_values(struct registry_key *k, int *count, REG_VAL ***values) +static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_value **value) { struct ldb_context *c = k->hive->backend_data; - int ret, i, j; + int ret; struct ldb_message **msg; + struct ldb_message_element *el; ret = ldb_search(c, (char *)k->backend_data, LDB_SCOPE_ONELEVEL, "(value=*)", NULL,&msg); @@ -108,30 +103,18 @@ static WERROR ldb_fetch_values(struct registry_key *k, int *count, REG_VAL ***va return WERR_FOOBAR; } - *values = talloc_array_p(k->mem_ctx, REG_VAL *, ret); - j = 0; - for(i = 0; i < ret; i++) { - struct ldb_message_element *el; - char *name; - el = ldb_msg_find_element(msg[i], "key"); - - name = el->values[0].data; - - /* Dirty hack to circumvent ldb_tdb bug */ - if(k->backend_data && !strcmp(msg[i]->dn, (char *)k->backend_data)) continue; - - (*values)[j] = reg_val_new(k, NULL); - (*values)[j]->backend_data = talloc_strdup((*values)[j]->mem_ctx, msg[i]->dn); - j++; - } - *count = j; + if(idx >= ret) return WERR_NO_MORE_ITEMS; + + el = ldb_msg_find_element(msg[idx], "value"); + + *value = talloc_p(mem_ctx, struct registry_value); + (*value)->name = talloc_strdup(mem_ctx, el->values[0].data); + (*value)->backend_data = talloc_strdup(mem_ctx, msg[idx]->dn); ldb_search_free(c, msg); return WERR_OK; } -#endif - static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **key) { struct ldb_context *c = h->backend_data; @@ -176,10 +159,8 @@ static struct registry_operations reg_backend_ldb = { .name = "ldb", .open_hive = ldb_open_hive, .open_key = ldb_open_key, -/* - .fetch_values = ldb_fetch_values,*/ + .get_value_by_index = ldb_get_value_by_id, .get_subkey_by_index = ldb_get_subkey_by_id, - .add_key = ldb_add_key, }; NTSTATUS registry_ldb_init(void) -- cgit From b9956de1b1319f1869efa79d76674484b7f41166 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 24 Oct 2004 16:31:00 +0000 Subject: r3164: Look up ncalrpc identifiers using the EPMAPPER. ncalrpc now works nicely :-) The various interface that support ncalrpc work nicely when tested with smbtorture and ncalrpc. Running RPC-SAMR against local smbd here is slightly faster using ncalrpc: ncalrpc: 1.8 sec ncacn_ip_tcp: 1.9 sec ncacn_np: 2.5 sec (This used to be commit 2cfc8f24ce209f47153d3a5bd7007dd1b0578b26) --- source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') 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 fd81983227..c819eb4254 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -105,7 +105,12 @@ static WERROR rpc_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct struct dcerpc_pipe *p; int n; - if(!h->credentials || !h->location) return WERR_INVALID_PARAM; + if (!h->credentials) return WERR_INVALID_PARAM; + + /* Default to local smbd if no connection is specified */ + if (!h->location) { + h->location = talloc_strdup(mem_ctx, "ncalrpc:"); + } user = talloc_strdup(mem_ctx, h->credentials); pass = strchr(user, '%'); -- cgit From a6ae640313a47ac2950c0948e4385fa934a5ef09 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 28 Oct 2004 13:19:39 +0000 Subject: r3323: more warning reductions (This used to be commit 5921587ec26e4892efc678421277e4969417d7f5) --- .../lib/registry/reg_backend_ldb/reg_backend_ldb.c | 6 ----- .../lib/registry/reg_backend_nt4/reg_backend_nt4.c | 12 +--------- .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 28 ++++++++++------------ .../lib/registry/reg_backend_w95/reg_backend_w95.c | 9 ------- 4 files changed, 13 insertions(+), 42 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index d76b7715da..faa8a5e62c 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -57,12 +57,6 @@ static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char * } -static int ldb_close_registry(void *data) -{ - ldb_close((struct ldb_context *)data); - return 0; -} - static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_key **subkey) { struct ldb_context *c = k->hive->backend_data; diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index 14fff5b60d..805f95fca1 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -934,7 +934,7 @@ static WERROR vk_to_val(TALLOC_CTX *mem_ctx, struct registry_key *parent, VK_HDR if(tmp->data_type == REG_SZ) { char *ret; - dat_len = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, dtmp, dat_len, (const void **)&ret); + dat_len = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, dtmp, dat_len, (void **)&ret); dtmp = ret; } @@ -1571,16 +1571,6 @@ error: #endif -static WERROR nt_close_registry (struct registry_hive *h) -{ - REGF *regf = h->backend_data; - if (regf->base) munmap(regf->base, regf->sbuf.st_size); - regf->base = NULL; - close(regf->fd); /* Ignore the error :-) */ - - return WERR_OK; -} - static WERROR nt_open_hive (TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **key) { REGF *regf; 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 c819eb4254..76c19d01ad 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -100,7 +100,8 @@ WERROR rpc_list_hives (TALLOC_CTX *mem_ctx, const char *location, const char *cr static WERROR rpc_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **k) { NTSTATUS status; - char *user, *pass; + char *user; + char *pass; struct rpc_key_data *mykeydata; struct dcerpc_pipe *p; int n; @@ -114,18 +115,18 @@ static WERROR rpc_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct user = talloc_strdup(mem_ctx, h->credentials); pass = strchr(user, '%'); - if(pass) - { - *pass = '\0'; pass++; + if (pass) { + pass = strdup(pass+1); } else { - pass = ""; + pass = strdup(""); } status = dcerpc_pipe_connect(&p, h->location, - DCERPC_WINREG_UUID, - DCERPC_WINREG_VERSION, - lp_workgroup(), - user, pass); + DCERPC_WINREG_UUID, + DCERPC_WINREG_VERSION, + lp_workgroup(), + user, pass); + free(pass); h->backend_data = p; @@ -145,12 +146,7 @@ static WERROR rpc_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct return known_hives[n].open((struct dcerpc_pipe *)h->backend_data, *k, &(mykeydata->pol)); } -static WERROR rpc_close_registry(struct registry_hive *h) -{ - dcerpc_pipe_close((struct dcerpc_pipe *)h->backend_data); - return WERR_OK; -} - +#if 0 static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) { struct winreg_OpenKey r; @@ -173,7 +169,7 @@ static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) return r.out.result; } - +#endif static WERROR rpc_open_rel_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const char *name, struct registry_key **key) { diff --git a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c index 2184a8855d..c285dac7c9 100644 --- a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c @@ -300,15 +300,6 @@ static WERROR w95_get_subkey_by_index (TALLOC_CTX *mem_ctx, struct registry_key return WERR_NO_MORE_ITEMS; } -static WERROR w95_close_reg(struct registry_hive *h) -{ - CREG *creg = h->backend_data; - if (creg->base) munmap(creg->base, creg->sbuf.st_size); - creg->base = NULL; - close(creg->fd); - return WERR_OK; -} - static WERROR w95_num_values(struct registry_key *k, int *count) { RGKN_KEY *rgkn_key = k->backend_data; -- cgit From 479bf22c813501f040adf7b6267b961748baa63f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 28 Oct 2004 23:06:12 +0000 Subject: r3340: Various fixes in the registry code. Implement the EnumKey call in the server. (This used to be commit da65a248c292a90342e1394ee4132ef2c7afd3c8) --- source4/lib/registry/common/reg_interface.c | 5 ++++- source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c | 5 ++++- source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 16edadfcbb..6237a788b7 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -191,7 +191,10 @@ WERROR reg_import_hive(struct registry_context *h, const char *backend, const ch if(!W_ERROR_IS_OK(werr)) return werr; - if(!ret->root) return WERR_GENERAL_FAILURE; + if(!ret->root) { + DEBUG(0, ("Backend %s didn't provide root key!\n", backend)); + return WERR_GENERAL_FAILURE; + } ret->root->hive = ret; ret->root->name = NULL; diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index faa8a5e62c..b26ee6ec60 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -146,7 +146,10 @@ static WERROR ldb_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *hive, str ldb_set_debug_stderr(c); hive->backend_data = c; - return ldb_open_key(mem_ctx, hive, "", k); + hive->root = talloc_zero_p(mem_ctx, struct registry_key); + hive->root->name = talloc_strdup(mem_ctx, ""); + + return WERR_OK; } static struct registry_operations reg_backend_ldb = { 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 76c19d01ad..5ed03c062c 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -85,7 +85,7 @@ struct { static WERROR rpc_query_key(struct registry_key *k); -WERROR rpc_list_hives (TALLOC_CTX *mem_ctx, const char *location, const char *credentials, char ***hives) +static WERROR rpc_list_hives (TALLOC_CTX *mem_ctx, const char *location, const char *credentials, char ***hives) { int i = 0; *hives = talloc_p(mem_ctx, char *); -- cgit From 7ce7137ad4edb03acf6189568d4c3c4f6d8798fe Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 29 Oct 2004 01:10:40 +0000 Subject: r3348: More registry fixes and additions. The following functions work right now against samba 4, at least with a ldb backend: winreg_Open* winreg_OpenKey winreg_EnumKey winreg_DeleteKey winreg_CreateKey (This used to be commit a71d51dd3b136a1bcde1704fe9830985e06bb01b) --- source4/lib/registry/common/reg_interface.c | 1 + .../registry/reg_backend_gconf/reg_backend_gconf.c | 10 ++--- .../lib/registry/reg_backend_ldb/reg_backend_ldb.c | 46 +++++++++++++++++++++- 3 files changed, 50 insertions(+), 7 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 6237a788b7..a9f7bf1d5f 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -367,6 +367,7 @@ WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key, if(key->hive->functions->get_subkey_by_name) { error = key->hive->functions->get_subkey_by_name(mem_ctx, key,name,subkey); + /* FIXME: Fall back to reg_open_key rather then get_subkey_by_index */ } else if(key->hive->functions->get_subkey_by_index) { for(i = 0; W_ERROR_IS_OK(error); i++) { error = reg_key_get_subkey_by_index(mem_ctx, key, i, subkey); diff --git a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c index d8c8d951c1..4f8cc5466e 100644 --- a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c +++ b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c @@ -35,8 +35,8 @@ static WERROR reg_open_gconf_hive(TALLOC_CTX *mem_ctx, struct registry_hive *h, if(!h->backend_data) return WERR_FOOBAR; *k = talloc_p(mem_ctx, struct registry_key); - (*k)->name = ""; - (*k)->path = ""; + (*k)->name = talloc_strdup(mem_ctx, ""); + (*k)->path = talloc_strdup(mem_ctx, ""); (*k)->backend_data = talloc_strdup(mem_ctx, "/"); return WERR_OK; } @@ -46,17 +46,15 @@ static WERROR gconf_open_key (TALLOC_CTX *mem_ctx, struct registry_hive *h, cons struct registry_key *ret; char *fullpath; - fullpath = reg_path_win2unix(strdup(name)); + fullpath = talloc_asprintf(mem_ctx, "/%s", reg_path_win2unix(talloc_strdup(mem_ctx, name))); /* Check if key exists */ if(!gconf_client_dir_exists((GConfClient *)h->backend_data, fullpath, NULL)) { - SAFE_FREE(fullpath); return WERR_DEST_NOT_FOUND; } ret = talloc_p(mem_ctx, struct registry_key); - ret->backend_data = talloc_strdup(mem_ctx, fullpath); - SAFE_FREE(fullpath); + ret->backend_data = fullpath; *key = ret; return WERR_OK; diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index b26ee6ec60..a18bed5591 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -142,7 +142,10 @@ static WERROR ldb_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *hive, str if (!hive->location) return WERR_INVALID_PARAM; c = ldb_connect(hive->location, 0, NULL); - if(!c) return WERR_FOOBAR; + if(!c) { + DEBUG(1, ("ldb_open_hive: %s\n", ldb_errstring(hive->backend_data))); + return WERR_FOOBAR; + } ldb_set_debug_stderr(c); hive->backend_data = c; @@ -152,8 +155,49 @@ static WERROR ldb_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *hive, str 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) +{ + struct ldb_context *ctx = parent->hive->backend_data; + struct ldb_message msg; + int ret; + + ZERO_STRUCT(msg); + + msg.dn = reg_path_to_ldb(mem_ctx, parent->path, talloc_asprintf(mem_ctx, "key=%s,", name)); + + ldb_msg_add_string(ctx, &msg, "key", talloc_strdup(mem_ctx, name)); + + ret = ldb_add(ctx, &msg); + if (ret < 0) { + DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parent->hive->backend_data))); + return WERR_FOOBAR; + } + + *newkey = talloc_zero_p(mem_ctx, struct registry_key); + (*newkey)->backend_data = msg.dn; + (*newkey)->name = talloc_strdup(mem_ctx, name); + + return WERR_OK; +} + +static WERROR ldb_del_key (struct registry_key *key) +{ + int ret; + + ret = ldb_delete(key->hive->backend_data, key->backend_data); + + if (ret < 0) { + DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(key->hive->backend_data))); + return WERR_FOOBAR; + } + + return WERR_OK; +} + static struct registry_operations reg_backend_ldb = { .name = "ldb", + .add_key = ldb_add_key, + .del_key = ldb_del_key, .open_hive = ldb_open_hive, .open_key = ldb_open_key, .get_value_by_index = ldb_get_value_by_id, -- cgit From a29c24f180cc21b358c51a86632eb1cc2cb17868 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 29 Oct 2004 11:44:59 +0000 Subject: r3367: More registry updates. Add support flush_key and close_hive. (This used to be commit c526273df238c994c4de3c1704c6e95433f2331c) --- source4/lib/registry/common/reg_interface.c | 33 ++++++++++++++++++++-- .../lib/registry/reg_backend_ldb/reg_backend_ldb.c | 7 +++++ .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 7 +++++ 3 files changed, 44 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index a9f7bf1d5f..999203f4d1 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -157,6 +157,19 @@ WERROR reg_open(struct registry_context **ret, const char *backend, const char * return WERR_OK; } +WERROR reg_close (struct registry_context *ctx) +{ + int i; + for (i = 0; i < ctx->num_hives; i++) { + if (ctx->hives[i]->functions->close_hive) { + ctx->hives[i]->functions->close_hive(ctx->hives[i]); + } + } + talloc_destroy(ctx); + + return WERR_OK; +} + /* Open a registry file/host/etc */ WERROR reg_import_hive(struct registry_context *h, const char *backend, const char *location, const char *credentials, const char *hivename) { @@ -367,7 +380,8 @@ WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key, if(key->hive->functions->get_subkey_by_name) { error = key->hive->functions->get_subkey_by_name(mem_ctx, key,name,subkey); - /* FIXME: Fall back to reg_open_key rather then get_subkey_by_index */ + } else if(key->hive->functions->open_key) { + error = key->hive->functions->open_key(mem_ctx, key->hive, talloc_asprintf(mem_ctx, "%s\\%s", key->path, name), subkey); } else if(key->hive->functions->get_subkey_by_index) { for(i = 0; W_ERROR_IS_OK(error); i++) { error = reg_key_get_subkey_by_index(mem_ctx, key, i, subkey); @@ -589,9 +603,8 @@ WERROR reg_del_value(struct registry_value *val) return ret; } -WERROR reg_save(struct registry_context *h, const char *location) +WERROR reg_save (struct registry_context *ctx, const char *location) { - /* FIXME */ return WERR_NOT_SUPPORTED; } @@ -615,3 +628,17 @@ WERROR reg_key_get_parent(TALLOC_CTX *mem_ctx, struct registry_key *key, struct SAFE_FREE(parent_name); return error; } + +WERROR reg_key_flush(struct registry_key *key) +{ + if (!key) { + return WERR_INVALID_PARAM; + } + + if (key->hive->functions->flush_key) { + return key->hive->functions->flush_key(key); + } + + /* No need for flushing, apparently */ + return WERR_OK; +} diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index a18bed5591..bd3afbdedf 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -194,11 +194,18 @@ static WERROR ldb_del_key (struct registry_key *key) return WERR_OK; } +static WERROR ldb_close_hive (struct registry_hive *hive) +{ + ldb_close (hive->backend_data); + return WERR_OK; +} + static struct registry_operations reg_backend_ldb = { .name = "ldb", .add_key = ldb_add_key, .del_key = ldb_del_key, .open_hive = ldb_open_hive, + .close_hive = ldb_close_hive, .open_key = ldb_open_key, .get_value_by_index = ldb_get_value_by_id, .get_subkey_by_index = ldb_get_subkey_by_id, 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 5ed03c062c..31e55bc9a3 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -97,6 +97,12 @@ static WERROR rpc_list_hives (TALLOC_CTX *mem_ctx, const char *location, const c return WERR_OK; } +static WERROR rpc_close_hive (struct registry_hive *h) +{ + dcerpc_pipe_close(h->backend_data); + return WERR_OK; +} + static WERROR rpc_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **k) { NTSTATUS status; @@ -373,6 +379,7 @@ static WERROR rpc_num_subkeys(struct registry_key *key, int *count) { static struct registry_operations reg_backend_rpc = { .name = "rpc", .open_hive = rpc_open_hive, + .close_hive = rpc_close_hive, .open_key = rpc_open_key, .get_subkey_by_index = rpc_get_subkey_by_index, .get_value_by_index = rpc_get_value_by_index, -- cgit From 9ba6c3885acb79d9c35e600f9a67f8ed0200edfd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 29 Oct 2004 12:12:24 +0000 Subject: r3368: Default to rpc backend with binding "ncalrpc:" if no backend was specified in the various registry tools. Allow opening a remote registry to partly fail (I.e. if not all hives could be opened) (This used to be commit 313034b10d7a70d079e2bec1af38cf2a7cd918c1) --- source4/lib/registry/common/reg_interface.c | 12 ++++++++---- source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c | 11 +++++++++-- source4/lib/registry/tools/regdiff.c | 4 ++-- source4/lib/registry/tools/regpatch.c | 2 +- source4/lib/registry/tools/regshell.c | 6 +++--- source4/lib/registry/tools/regtree.c | 2 +- 6 files changed, 24 insertions(+), 13 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 999203f4d1..044dc9a0ad 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -132,9 +132,9 @@ WERROR reg_list_available_hives(TALLOC_CTX *mem_ctx, const char *backend, const WERROR reg_open(struct registry_context **ret, const char *backend, const char *location, const char *credentials) { - WERROR error = reg_create(ret); + WERROR error = reg_create(ret), reterror = WERR_NO_MORE_ITEMS; char **hives; - int i; + int i, j; TALLOC_CTX *mem_ctx = talloc_init("reg_open"); if(!W_ERROR_IS_OK(error)) return error; @@ -147,11 +147,15 @@ WERROR reg_open(struct registry_context **ret, const char *backend, const char * if(!W_ERROR_IS_OK(error)) return error; + j = 0; for(i = 0; hives[i]; i++) { error = reg_import_hive(*ret, backend, location, credentials, hives[i]); - if(!W_ERROR_IS_OK(error)) return error; - (*ret)->hives[i]->name = talloc_strdup((*ret)->mem_ctx, hives[i]); + if (W_ERROR_IS_OK(error)) { + reterror = WERR_OK; + (*ret)->hives[j]->name = talloc_strdup((*ret)->mem_ctx, hives[i]); + j++; + } else if (!W_ERROR_IS_OK(reterror)) reterror = error; } return WERR_OK; 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 31e55bc9a3..27bd3ff957 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -122,6 +122,7 @@ static WERROR rpc_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct user = talloc_strdup(mem_ctx, h->credentials); pass = strchr(user, '%'); if (pass) { + *pass = '\0'; pass = strdup(pass+1); } else { pass = strdup(""); @@ -136,14 +137,20 @@ static WERROR rpc_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct h->backend_data = p; - if(NT_STATUS_IS_ERR(status)) return ntstatus_to_werror(status); + if(NT_STATUS_IS_ERR(status)) { + DEBUG(1, ("Unable to open '%s': %s\n", h->location, nt_errstr(status))); + return ntstatus_to_werror(status); + } for(n = 0; known_hives[n].name; n++) { if(!strcmp(known_hives[n].name, h->backend_hivename)) break; } - if(!known_hives[n].name) return WERR_NO_MORE_ITEMS; + if(!known_hives[n].name) { + DEBUG(1, ("No such hive %s\n", known_hives[n].name)); + return WERR_NO_MORE_ITEMS; + } *k = talloc_p(mem_ctx, struct registry_key); (*k)->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data); diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 524e538591..41a29e46d3 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -158,7 +158,7 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, return 1; } - if(!backend1) backend1 = "dir"; + if(!backend1) backend1 = "rpc"; error = reg_open(&h1, backend1, location1, credentials1); if(!W_ERROR_IS_OK(error)) { @@ -173,7 +173,7 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, return 2; } - if(!backend2) backend2 = "dir"; + if(!backend2) backend2 = "rpc"; error = reg_open(&h2, backend2, location2, credentials2); if(!W_ERROR_IS_OK(error)) { diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 1b33628a71..eed249d353 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -760,7 +760,7 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd const char *location; const char *credentials = NULL; const char *patch; - const char *backend = "dir"; + const char *backend = "rpc"; struct registry_context *h; WERROR error; struct poptOption long_options[] = { diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 78fe36f1a0..db7af9d5b6 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -337,7 +337,7 @@ static char **reg_completion(const char *text, int start, int end) int main(int argc, char **argv) { int opt; - const char *backend = "dir"; + const char *backend = "rpc"; const char *credentials = NULL; struct registry_key *curkey = NULL; poptContext pc; @@ -363,6 +363,8 @@ static char **reg_completion(const char *text, int start, int end) while((opt = poptGetNextOpt(pc)) != -1) { } + setup_logging("regtree", True); + error = reg_open(&h, backend, poptPeekArg(pc), credentials); if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open '%s' with backend '%s'\n", poptGetArg(pc), backend); @@ -370,8 +372,6 @@ static char **reg_completion(const char *text, int start, int end) } poptFreeContext(pc); - setup_logging("regtree", True); - curkey = h->hives[0]->root; while(True) { diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index bc0055a891..66bce1e499 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -70,7 +70,7 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) int main(int argc, char **argv) { int opt, i; - const char *backend = "dir"; + const char *backend = "rpc"; const char *credentials = NULL; poptContext pc; struct registry_context *h; -- cgit From 9dc3f789c41cc63a784e087dc0f061e495e04bab Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 29 Oct 2004 13:38:37 +0000 Subject: r3369: More registry updates We now pass the RPC-WINREG torture test. Also, constructions like the following work now: regtree <-> smbd <-> NTUSER.DAT (This used to be commit df952e95cd1cbbfb62b4620e9452993aaef44ad3) --- source4/lib/registry/common/reg_interface.c | 76 +++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 044dc9a0ad..09267a6370 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/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; +} -- cgit From def0a74030714d07ed852178d9a8f2ec4ed16bab Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 29 Oct 2004 14:53:23 +0000 Subject: r3370: Initial work on Add Key/Delete Key/Add Value/Mod Value/Del Value support in gregedit (This used to be commit 33f429c61f2859e3ad60fa38823174bbd331d91a) --- source4/lib/registry/tools/regdiff.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 41a29e46d3..bedf3222d1 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -115,7 +115,7 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, const char *credentials1= NULL, *credentials2 = NULL; char *outputfile = NULL; FILE *fd = stdout; - struct registry_context *h1, *h2; + struct registry_context *h1 = NULL, *h2; int from_null = 0; int i; WERROR error, error2; @@ -165,7 +165,7 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location1, backend1); return 1; } - } + } location2 = poptGetArg(pc); if(!location2) { @@ -196,8 +196,8 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, error2 = error = WERR_OK; - for(i = 0; i < h1->num_hives && i < h2->num_hives; i++) { - writediff(h1->hives[i]->root, h2->hives[i]->root, fd); + for(i = 0; (!h1 || i < h1->num_hives) && i < h2->num_hives; i++) { + writediff(h1?h1->hives[i]->root:NULL, h2->hives[i]->root, fd); } fclose(fd); -- cgit From 3ab24d0d2236241c3f7f04db1b08d1ee80ce5530 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 29 Oct 2004 21:53:42 +0000 Subject: r3374: Couple of bug fixes (This used to be commit f8e45e143087d333da4afc193b4fa1991ba04c63) --- source4/lib/registry/common/reg_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 09267a6370..70b600ba33 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -158,7 +158,7 @@ WERROR reg_open(struct registry_context **ret, const char *backend, const char * } else if (!W_ERROR_IS_OK(reterror)) reterror = error; } - return WERR_OK; + return reterror; } WERROR reg_close (struct registry_context *ctx) -- cgit From 90067934cd3195df80f8b1e614629d51fffcb38b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Nov 2004 10:30:34 +0000 Subject: r3428: switched to using minimal includes for the auto-generated RPC code. The thing that finally convinced me that minimal includes was worth pursuing for rpc was a compiler (tcc) that failed to build Samba due to reaching internal limits of the size of include files. Also the fact that includes.h.gch was 16MB, which really seems excessive. This patch brings it back to 12M, which is still too large, but better. Note that this patch speeds up compile times for both the pch and non-pch case. This change also includes the addition iof a "depends()" option in our IDL files, allowing you to specify that one IDL file depends on another. This capability was needed for the auto-includes generation. (This used to be commit b8f5fa8ac8e8725f3d321004f0aedf4246fc6b49) --- source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') 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 27bd3ff957..f90b123bfc 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -18,6 +18,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "includes.h" +#include "librpc/gen_ndr/ndr_winreg.h" /** * This is the RPC backend for the registry library. -- cgit From ead3508ac81ff3ed2a48753f3b5e23537ba6ec73 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 00:24:21 +0000 Subject: r3447: more include/system/XXX.h include files (This used to be commit 264ce9181089922547e8f6f67116f2d7277a5105) --- source4/lib/registry/reg_backend_dir/reg_backend_dir.c | 1 + source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c | 1 + source4/lib/registry/reg_backend_w95/reg_backend_w95.c | 1 + source4/lib/registry/tools/regshell.c | 1 + 4 files changed, 4 insertions(+) (limited to 'source4/lib/registry') 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 95d4c47af0..2273a86771 100644 --- a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c @@ -19,6 +19,7 @@ */ #include "includes.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) { diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index 805f95fca1..a8d1752070 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -304,6 +304,7 @@ Hope this helps.... (Although it was "fun" for me to uncover this things, *************************************************************************/ #include "includes.h" +#include "system/shmem.h" #define REG_KEY_LIST_SIZE 10 #define FLAG_HAS_NAME 0x01 diff --git a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c index c285dac7c9..448af66eec 100644 --- a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c @@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "includes.h" +#include "system/shmem.h" /** * The registry starts with a header that contains pointers to diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index db7af9d5b6..8449446c86 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "system/time.h" /* * ck/cd - change key -- cgit From edbfc0f6e70150e321822365bf0eead2821551bd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 02:57:18 +0000 Subject: r3453: - split out the auth and popt includes - tidied up some of the system includes - moved a few more structures back from misc.idl to netlogon.idl and samr.idl now that pidl knows about inter-IDL dependencies (This used to be commit 7b7477ac42d96faac1b0ff361525d2c63cedfc64) --- source4/lib/registry/tools/regdiff.c | 1 + source4/lib/registry/tools/regpatch.c | 1 + source4/lib/registry/tools/regshell.c | 1 + source4/lib/registry/tools/regtree.c | 1 + 4 files changed, 4 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index bedf3222d1..1d69734f21 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "lib/cmdline/popt_common.h" static void writediff(struct registry_key *oldkey, struct registry_key *newkey, FILE *out) { diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index eed249d353..298a922fbf 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "lib/cmdline/popt_common.h" /* * Routines to parse a REGEDIT4 file diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 8449446c86..fcc7204423 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "lib/cmdline/popt_common.h" #include "system/time.h" /* diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 66bce1e499..64948b06fe 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "lib/cmdline/popt_common.h" static void print_tree(int l, struct registry_key *p, int fullpath, int novals) { -- cgit From 3643fb11092e28a9538ef32cedce8ff21ad86a28 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 06:42:15 +0000 Subject: r3463: separated out some more headers (asn_1.h, messages.h, dlinklist.h and ioctl.h) (This used to be commit b97e395c814762024336c1cf4d7c25be8da5813a) --- source4/lib/registry/common/reg_interface.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 70b600ba33..76a1d04b08 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "dlinklist.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_REGISTRY -- cgit From a42142439aee9e75796e25cdf05e042174926abf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 06:52:59 +0000 Subject: r3464: split out registry.h, rap.h and ldap_server.h (This used to be commit 70d2090f6bf2c7e0caf1e9c020f330de88871f8e) --- source4/lib/registry/common/reg_interface.c | 1 + source4/lib/registry/common/reg_util.c | 1 + source4/lib/registry/reg_backend_dir/reg_backend_dir.c | 1 + source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c | 1 + source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c | 1 + source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c | 1 + source4/lib/registry/reg_backend_w95/reg_backend_w95.c | 1 + source4/lib/registry/tools/regdiff.c | 1 + source4/lib/registry/tools/regpatch.c | 1 + source4/lib/registry/tools/regshell.c | 1 + source4/lib/registry/tools/regtree.c | 1 + 11 files changed, 11 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 76a1d04b08..b2d659258d 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -20,6 +20,7 @@ #include "includes.h" #include "dlinklist.h" +#include "registry.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_REGISTRY diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index c7354fe909..052ccc347b 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "registry.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_REGISTRY 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 2273a86771..247d723252 100644 --- a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#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) diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index bd3afbdedf..22c81018c7 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "registry.h" static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char *add) { diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index a8d1752070..c1b9b43445 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -304,6 +304,7 @@ Hope this helps.... (Although it was "fun" for me to uncover this things, *************************************************************************/ #include "includes.h" +#include "registry.h" #include "system/shmem.h" #define REG_KEY_LIST_SIZE 10 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 f90b123bfc..954e7684bb 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -18,6 +18,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "includes.h" +#include "registry.h" #include "librpc/gen_ndr/ndr_winreg.h" /** diff --git a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c index 448af66eec..72ec882b8a 100644 --- a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c @@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "includes.h" +#include "registry.h" #include "system/shmem.h" /** diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 1d69734f21..c1b8d2949e 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "registry.h" #include "lib/cmdline/popt_common.h" static void writediff(struct registry_key *oldkey, struct registry_key *newkey, FILE *out) diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 298a922fbf..ae4d331e3c 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "registry.h" #include "lib/cmdline/popt_common.h" /* diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index fcc7204423..583624fbab 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "registry.h" #include "lib/cmdline/popt_common.h" #include "system/time.h" diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 64948b06fe..8fd73aef85 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "registry.h" #include "lib/cmdline/popt_common.h" static void print_tree(int l, struct registry_key *p, int fullpath, int novals) -- cgit From c2c044386109fc61d71ac89e2a4b8a0d9c6ac186 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 10:13:26 +0000 Subject: r3472: fixed build of reg_backend_gconf (This used to be commit d8a4af5282a1a3002def250f4857469ffb84d183) --- source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c index 4f8cc5466e..382bc6dba5 100644 --- a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c +++ b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "registry.h" #include static WERROR gerror_to_werror(GError *error) -- cgit From 6f214cc510a59b7a65ee9d4486baf14a3e579f73 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 3 Nov 2004 00:17:12 +0000 Subject: r3494: got rid of include/rewrite.h, and split out the dynconfig.h header (This used to be commit 558de54ec6432a4ae90aa14a585f32c6cd03ced2) --- source4/lib/registry/tools/regdiff.c | 1 + source4/lib/registry/tools/regpatch.c | 1 + source4/lib/registry/tools/regshell.c | 1 + source4/lib/registry/tools/regtree.c | 1 + 4 files changed, 4 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index c1b8d2949e..80f4a5c49f 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "dynconfig.h" #include "registry.h" #include "lib/cmdline/popt_common.h" diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index ae4d331e3c..38eabb60a9 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "dynconfig.h" #include "registry.h" #include "lib/cmdline/popt_common.h" diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 583624fbab..d705a0b802 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "dynconfig.h" #include "registry.h" #include "lib/cmdline/popt_common.h" #include "system/time.h" diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 8fd73aef85..a8225c026d 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "dynconfig.h" #include "registry.h" #include "lib/cmdline/popt_common.h" -- cgit From e8010adffe44f1ad0d82c7b5c7d5fe2cf7d53afd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 5 Nov 2004 07:23:06 +0000 Subject: r3543: fixed some #include lines to make them more consistent, and fixed conditional compilation of xattr client code (This used to be commit 321fb06a627f4deae649ab014bc881721d37b3dd) --- source4/lib/registry/tools/regpatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 38eabb60a9..4ad7e162a3 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -59,7 +59,7 @@ #define CMD_KEY 1 #define CMD_VAL 2 -#include +#include "includes.h" typedef struct val_spec_list { struct val_spec_list *next; -- cgit From 3a7eff64f27158dc428d3f881c4dc1e613ac6665 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 5 Nov 2004 09:19:42 +0000 Subject: r3546: including includes.h twice causes gcc 3.4 to crash with pch (This used to be commit 51c1c2af687ed351d12e6d933659d94f5925728c) --- source4/lib/registry/tools/regpatch.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 4ad7e162a3..d70d7b8457 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -59,8 +59,6 @@ #define CMD_KEY 1 #define CMD_VAL 2 -#include "includes.h" - typedef struct val_spec_list { struct val_spec_list *next; char *name; -- cgit From 71db46ea665606384f2be1be708c74c97c9adfb2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 6 Nov 2004 23:23:15 +0000 Subject: r3586: Fix some of the issues with the module init functions. Both subsystems and modules can now have init functions, which can be specified in .mk files (INIT_FUNCTION = ...) The build system will define : - SUBSYSTEM_init_static_modules that calls the init functions of all statically compiled modules. Failing to load will generate an error which is not fatal - BINARY_init_subsystems that calls the init functions (if defined) for the subsystems the binary depends on This removes the hack with the "static bool Initialised = " and the "lazy_init" functions (This used to be commit 7a8244761bfdfdfb48f8264d76951ebdfbf7bd8a) --- source4/lib/registry/common/reg_interface.c | 17 +++++------------ source4/lib/registry/config.mk | 7 +++++++ source4/lib/registry/tools/regdiff.c | 1 + source4/lib/registry/tools/regpatch.c | 1 + source4/lib/registry/tools/regshell.c | 1 + source4/lib/registry/tools/regtree.c | 1 + 6 files changed, 16 insertions(+), 12 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index b2d659258d..0399fc26aa 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -59,24 +59,19 @@ NTSTATUS registry_register(const void *_function) return NT_STATUS_OK; } -static BOOL registry_init(void) +NTSTATUS registry_init(void) { - static BOOL initialised; NTSTATUS status; - if(initialised) { - return True; - } - status = register_subsystem("registry", registry_register); if (NT_STATUS_IS_ERR(status)) { DEBUG(0, ("Error registering registry subsystem: %s\n", nt_errstr(status))); - return False; + return status; } - initialised = True; - static_init_registry; - return True; + registry_init_static_modules; + + return NT_STATUS_OK; } /* Find a backend in the list of available backends */ @@ -84,8 +79,6 @@ static struct reg_init_function_entry *reg_find_backend_entry(const char *name) { struct reg_init_function_entry *entry; - if(registry_init() == False) return NULL; - entry = backends; while(entry) { diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 659e705d5d..dacd6d5295 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -3,6 +3,7 @@ ################################################ # Start MODULE registry_nt4 [MODULE::registry_nt4] +INIT_FUNCTION = registry_nt4_init INIT_OBJ_FILES = \ lib/registry/reg_backend_nt4/reg_backend_nt4.o # End MODULE registry_nt4 @@ -11,6 +12,7 @@ INIT_OBJ_FILES = \ ################################################ # Start MODULE registry_w95 [MODULE::registry_w95] +INIT_FUNCTION = registry_w95_init INIT_OBJ_FILES = \ lib/registry/reg_backend_w95/reg_backend_w95.o # End MODULE registry_w95 @@ -19,6 +21,7 @@ INIT_OBJ_FILES = \ ################################################ # Start MODULE registry_dir [MODULE::registry_dir] +INIT_FUNCTION = registry_dir_init INIT_OBJ_FILES = \ lib/registry/reg_backend_dir/reg_backend_dir.o # End MODULE registry_dir @@ -27,6 +30,7 @@ INIT_OBJ_FILES = \ ################################################ # Start MODULE registry_rpc [MODULE::registry_rpc] +INIT_FUNCTION = registry_rpc_init INIT_OBJ_FILES = \ lib/registry/reg_backend_rpc/reg_backend_rpc.o REQUIRED_SUBSYSTEMS = \ @@ -37,6 +41,7 @@ REQUIRED_SUBSYSTEMS = \ ################################################ # Start MODULE registry_gconf [MODULE::registry_gconf] +INIT_FUNCTION = registry_gconf_init INIT_OBJ_FILES = \ lib/registry/reg_backend_gconf/reg_backend_gconf.o REQUIRED_LIBRARIES = \ @@ -47,6 +52,7 @@ REQUIRED_LIBRARIES = \ ################################################ # Start MODULE registry_ldb [MODULE::registry_ldb] +INIT_FUNCTION = registry_ldb_init INIT_OBJ_FILES = \ lib/registry/reg_backend_ldb/reg_backend_ldb.o REQUIRED_SUBSYSTEMS = \ @@ -57,6 +63,7 @@ REQUIRED_SUBSYSTEMS = \ ################################################ # Start SUBSYSTEM REGISTRY [SUBSYSTEM::REGISTRY] +INIT_FUNCTION = registry_init INIT_OBJ_FILES = \ lib/registry/common/reg_interface.o ADD_OBJ_FILES = \ diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 80f4a5c49f..55c8f1e72f 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -131,6 +131,7 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, POPT_TABLEEND }; + regdiff_init_subsystems; if (!lp_load(dyn_CONFIGFILE,True,False,False)) { fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE); diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index d70d7b8457..a8b2f83ee1 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -771,6 +771,7 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd POPT_TABLEEND }; + regpatch_init_subsystems; if (!lp_load(dyn_CONFIGFILE,True,False,False)) { fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE); diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index d705a0b802..8d044f6fa2 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -356,6 +356,7 @@ static char **reg_completion(const char *text, int start, int end) POPT_TABLEEND }; + regshell_init_subsystems; if (!lp_load(dyn_CONFIGFILE,True,False,False)) { fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE); diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index a8225c026d..ced7a00f94 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -88,6 +88,7 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) POPT_TABLEEND }; + regtree_init_subsystems; if (!lp_load(dyn_CONFIGFILE,True,False,False)) { fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE); -- cgit From 7367d23713a34a6c29a492adb365292399adffe8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 14 Nov 2004 13:52:16 +0000 Subject: r3730: More build system fixes and simplifications the hierarchy in the init functions is correct now will also make it easier to implement some other features (This used to be commit cbe819a75568403ac8850ea4d344c607a46d61c2) --- source4/lib/registry/config.mk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index dacd6d5295..bebd8bf1d7 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -44,8 +44,7 @@ REQUIRED_SUBSYSTEMS = \ INIT_FUNCTION = registry_gconf_init INIT_OBJ_FILES = \ lib/registry/reg_backend_gconf/reg_backend_gconf.o -REQUIRED_LIBRARIES = \ - gconf +REQUIRED_SUBSYSTEMS = EXT_LIB_gconf # End MODULE registry_gconf ################################################ -- cgit From 8e16d8a76f8a3b8ccc89eb317c8e5daa6cf43b71 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 14 Nov 2004 16:22:01 +0000 Subject: r3733: More build system fixes/features: - Use .mk files directly (no need for a SMB_*_MK() macro when adding a new SUBSYSTEM, MODULE or BINARY). This allows addition of new modules and subsystems without running configure - Add support for generating .dot files with the Samba4 dependency tree (as used by the graphviz and springgraph utilities) (This used to be commit 64826da834e26ee0488674e27a0eae36491ee179) --- source4/lib/registry/config.m4 | 16 ---------------- source4/lib/registry/config.mk | 6 ++++++ 2 files changed, 6 insertions(+), 16 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index f3681e7828..abadcbe1a0 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -15,22 +15,6 @@ if test t$SMB_EXT_LIB_ENABLE_gconf = tYES; then SMB_MODULE_DEFAULT(registry_gconf, STATIC) fi -SMB_MODULE_MK(registry_nt4, REGISTRY, STATIC, lib/registry/config.mk) -SMB_MODULE_MK(registry_w95, REGISTRY, STATIC, lib/registry/config.mk) -SMB_MODULE_MK(registry_dir, REGISTRY, STATIC, lib/registry/config.mk) -SMB_MODULE_MK(registry_rpc, REGISTRY, STATIC, lib/registry/config.mk) -SMB_MODULE_MK(registry_gconf, REGISTRY, STATIC, lib/registry/config.mk) -SMB_MODULE_MK(registry_ldb, REGISTRY, STATIC, lib/registry/config.mk) - -SMB_SUBSYSTEM_MK(REGISTRY,lib/registry/config.mk) - -SMB_BINARY_MK(regdiff, lib/registry/config.mk) -SMB_BINARY_MK(regpatch, lib/registry/config.mk) -SMB_BINARY_MK(regshell, lib/registry/config.mk) -SMB_BINARY_MK(regtree, lib/registry/config.mk) - if test x"$experimental" = x"yes"; then SMB_LIBRARY_ENABLE(libwinregistry, YES) fi - -SMB_LIBRARY_MK(libwinregistry, lib/registry/config.mk) diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index bebd8bf1d7..1a12b0ade6 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -4,6 +4,7 @@ # Start MODULE registry_nt4 [MODULE::registry_nt4] INIT_FUNCTION = registry_nt4_init +SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ lib/registry/reg_backend_nt4/reg_backend_nt4.o # End MODULE registry_nt4 @@ -13,6 +14,7 @@ INIT_OBJ_FILES = \ # Start MODULE registry_w95 [MODULE::registry_w95] INIT_FUNCTION = registry_w95_init +SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ lib/registry/reg_backend_w95/reg_backend_w95.o # End MODULE registry_w95 @@ -22,6 +24,7 @@ INIT_OBJ_FILES = \ # Start MODULE registry_dir [MODULE::registry_dir] INIT_FUNCTION = registry_dir_init +SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ lib/registry/reg_backend_dir/reg_backend_dir.o # End MODULE registry_dir @@ -31,6 +34,7 @@ INIT_OBJ_FILES = \ # Start MODULE registry_rpc [MODULE::registry_rpc] INIT_FUNCTION = registry_rpc_init +SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ lib/registry/reg_backend_rpc/reg_backend_rpc.o REQUIRED_SUBSYSTEMS = \ @@ -42,6 +46,7 @@ REQUIRED_SUBSYSTEMS = \ # Start MODULE registry_gconf [MODULE::registry_gconf] INIT_FUNCTION = registry_gconf_init +SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ lib/registry/reg_backend_gconf/reg_backend_gconf.o REQUIRED_SUBSYSTEMS = EXT_LIB_gconf @@ -52,6 +57,7 @@ REQUIRED_SUBSYSTEMS = EXT_LIB_gconf # Start MODULE registry_ldb [MODULE::registry_ldb] INIT_FUNCTION = registry_ldb_init +SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ lib/registry/reg_backend_ldb/reg_backend_ldb.o REQUIRED_SUBSYSTEMS = \ -- cgit From 836f6ea0bfea0721c55fc155f6f4b19a1316c1ef Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 14 Nov 2004 16:34:30 +0000 Subject: r3734: Fix some incorrect dependencies (This used to be commit 3add9e7de52496b135a230cccfd2d99a8b77ddd0) --- source4/lib/registry/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 1a12b0ade6..9c6ed24148 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -38,7 +38,7 @@ SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ lib/registry/reg_backend_rpc/reg_backend_rpc.o REQUIRED_SUBSYSTEMS = \ - LIBSMB + LIBRPC # End MODULE registry_rpc ################################################ -- cgit From 31ded4901b4529ad2e49871502cab5ecba71483a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 14 Nov 2004 22:23:23 +0000 Subject: r3737: - Get rid of the register_subsystem() and register_backend() functions. - Re-disable tdbtool (it was building fine on my Debian box but other machines were having problems) (This used to be commit 0d7bb2c40b7a9ed59df3f8944133ea562697e814) --- source4/lib/registry/common/reg_interface.c | 15 --------------- source4/lib/registry/config.mk | 1 - source4/lib/registry/reg_backend_dir/reg_backend_dir.c | 2 +- .../lib/registry/reg_backend_gconf/reg_backend_gconf.c | 2 +- source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c | 2 +- source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c | 2 +- source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c | 2 +- source4/lib/registry/reg_backend_w95/reg_backend_w95.c | 2 +- 8 files changed, 6 insertions(+), 22 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 0399fc26aa..77440cea0f 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -59,21 +59,6 @@ NTSTATUS registry_register(const void *_function) return NT_STATUS_OK; } -NTSTATUS registry_init(void) -{ - NTSTATUS status; - - status = register_subsystem("registry", registry_register); - if (NT_STATUS_IS_ERR(status)) { - DEBUG(0, ("Error registering registry subsystem: %s\n", nt_errstr(status))); - return status; - } - - registry_init_static_modules; - - return NT_STATUS_OK; -} - /* Find a backend in the list of available backends */ static struct reg_init_function_entry *reg_find_backend_entry(const char *name) { diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 9c6ed24148..ec9dbec7db 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -68,7 +68,6 @@ REQUIRED_SUBSYSTEMS = \ ################################################ # Start SUBSYSTEM REGISTRY [SUBSYSTEM::REGISTRY] -INIT_FUNCTION = registry_init INIT_OBJ_FILES = \ lib/registry/common/reg_interface.o ADD_OBJ_FILES = \ 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 247d723252..8712e7ce7c 100644 --- a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c @@ -144,5 +144,5 @@ static struct registry_operations reg_backend_dir = { NTSTATUS registry_dir_init(void) { - return register_backend("registry", ®_backend_dir); + return registry_register(®_backend_dir); } diff --git a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c index 382bc6dba5..fd258ca285 100644 --- a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c +++ b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c @@ -189,5 +189,5 @@ static struct registry_operations reg_backend_gconf = { NTSTATUS registry_gconf_init(void) { - return register_backend("registry", ®_backend_gconf); + return registry_register(®_backend_gconf); } diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index 22c81018c7..bdebe34ff4 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -214,5 +214,5 @@ static struct registry_operations reg_backend_ldb = { NTSTATUS registry_ldb_init(void) { - return register_backend("registry", ®_backend_ldb); + return registry_register(®_backend_ldb); } diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index c1b9b43445..aac6e548a8 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -1743,5 +1743,5 @@ static struct registry_operations reg_backend_nt4 = { NTSTATUS registry_nt4_init(void) { - return register_backend("registry", ®_backend_nt4); + return registry_register(®_backend_nt4); } 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 954e7684bb..47afc31d96 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -401,5 +401,5 @@ static struct registry_operations reg_backend_rpc = { NTSTATUS registry_rpc_init(void) { - return register_backend("registry", ®_backend_rpc); + return registry_register(®_backend_rpc); } diff --git a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c index 72ec882b8a..fb73e9052c 100644 --- a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c @@ -352,5 +352,5 @@ static struct registry_operations reg_backend_w95 = { NTSTATUS registry_w95_init(void) { - return register_backend("registry", ®_backend_w95); + return registry_register(®_backend_w95); } -- cgit From 8a18778286a16423d7d6e483fdb308a91e294efe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 16 Nov 2004 09:00:52 +0000 Subject: r3783: - don't use make proto for ldb anymore - split ldh.h out of samba's includes.h - make ldb_context and ldb_module private to the subsystem - use ltdb_ prefix for all ldb_tdb functions metze (This used to be commit f5ee40d6ce8224e280070975efc9911558fe675c) --- source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c index bdebe34ff4..380a8010f2 100644 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c @@ -20,6 +20,7 @@ #include "includes.h" #include "registry.h" +#include "lib/ldb/include/ldb.h" static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char *add) { -- cgit From d95a256d1b7f579666c852740d32ba0f446a4c66 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 19 Nov 2004 20:21:13 +0000 Subject: r3881: Split up the LIBNDR_GEN subsystem into NDR_* and RPC_NDR_* subsystems. This reduces the total size of the samba binaries from 119 Mb to 73 Mb. Next step will be to have the build system obtain some of this information by itself, so that we don't have to write ~10 lines per interface manually. (This used to be commit 16d905f6b0cbec591eebc44ee2ac9516a5730378) --- source4/lib/registry/config.mk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index ec9dbec7db..b91ec647a0 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -37,8 +37,7 @@ INIT_FUNCTION = registry_rpc_init SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ lib/registry/reg_backend_rpc/reg_backend_rpc.o -REQUIRED_SUBSYSTEMS = \ - LIBRPC +REQUIRED_SUBSYSTEMS = RPC_NDR_WINREG # End MODULE registry_rpc ################################################ -- cgit From cc8f4358cca2404895015e2351394f2f4a16e025 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 2 Dec 2004 04:37:36 +0000 Subject: r4035: more effort on consistent naming of the access mask bits. This removes the duplicate named SEC_RIGHTS_MAXIMUM_ALLOWED and SEC_RIGHTS_FULL_CONTROL, which are just other names for SEC_FLAG_MAXIMUM_ALLOWED and SEC_RIGHTS_FILE_ALL. The latter names match the new naming conventions in security.idl Also added names for the generic->specific mappings for files are directories (This used to be commit 17a4e0b3aca227b40957ed1e0c57e498debc6ddf) --- source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') 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 47afc31d96..1a7cb38af5 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -47,7 +47,7 @@ static void init_winreg_String(struct winreg_String *name, const char *s) unknown.unknown0 = 0x84e0; \ unknown.unknown1 = 0x0000; \ r.in.unknown = &unknown; \ - r.in.access_required = SEC_RIGHTS_MAXIMUM_ALLOWED; \ + r.in.access_required = SEC_FLAG_MAXIMUM_ALLOWED; \ r.out.handle = hnd;\ \ status = dcerpc_winreg_Open ## u(p, mem_ctx, &r); \ -- cgit From 4183b2ac3832cdc2055d7eb3ed7121a9ea91085c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 2 Dec 2004 04:51:56 +0000 Subject: r4037: fixed a bunch of "might be uninitialised" warnings after enabling -O1 in my compile (This used to be commit 0928b1f5b68c858922c3ea6c27ed03b5091c6221) --- source4/lib/registry/common/reg_interface.c | 2 +- source4/lib/registry/reg_backend_w95/reg_backend_w95.c | 2 +- source4/lib/registry/tools/regshell.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 77440cea0f..dea8861745 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -614,7 +614,7 @@ WERROR reg_key_get_parent(TALLOC_CTX *mem_ctx, struct registry_key *key, struct { char *parent_name; char *last; - struct registry_key *root; + struct registry_key *root = NULL; WERROR error; parent_name = strdup(key->path); diff --git a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c index fb73e9052c..445d13a99c 100644 --- a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c @@ -320,7 +320,7 @@ static WERROR w95_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, i DWORD i; DWORD offset = 0; RGDB_KEY *rgdb_key = LOCN_RGDB_KEY((CREG *)k->hive->backend_data, rgkn_key->id.rgdb, rgkn_key->id.id); - RGDB_VALUE *curval; + RGDB_VALUE *curval = NULL; if(!rgdb_key) return WERR_FOOBAR; diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 8d044f6fa2..3333299088 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -245,7 +245,7 @@ static char **reg_complete_command(const char *text, int end) { /* Complete command */ char **matches; - int i, len, samelen, count=1; + int i, len, samelen=0, count=1; matches = (char **)malloc(sizeof(matches[0])*MAX_COMPLETIONS); if (!matches) return NULL; -- cgit From 6e6374cb5bcffb4df8bdb0a83327fff92b61ac84 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 3 Dec 2004 07:20:30 +0000 Subject: r4055: fixed more places to use type safe allocation macros (This used to be commit eec698254f67365f27b4b7569fa982e22472aca1) --- source4/lib/registry/common/reg_interface.c | 4 ++-- source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c | 16 ++++++++-------- source4/lib/registry/tools/regshell.c | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index dea8861745..f7d3af0705 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -51,7 +51,7 @@ NTSTATUS registry_register(const void *_function) return NT_STATUS_OBJECT_NAME_COLLISION; } - entry = malloc(sizeof(struct reg_init_function_entry)); + entry = malloc_p(struct reg_init_function_entry); entry->functions = functions; DLIST_ADD(backends, entry); @@ -85,7 +85,7 @@ WERROR reg_create(struct registry_context **_ret) TALLOC_CTX *mem_ctx; struct registry_context *ret; mem_ctx = talloc_init("registry handle"); - ret = talloc(mem_ctx, sizeof(struct registry_context)); + ret = talloc_p(mem_ctx, struct registry_context); ret->mem_ctx = mem_ctx; ZERO_STRUCTP(ret); *_ret = ret; diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c index aac6e548a8..381f0c3bcf 100644 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c @@ -540,7 +540,7 @@ static SEC_DESC *nt_create_def_sec_desc(struct registry_hive *regf) { SEC_DESC *tmp; - tmp = (SEC_DESC *)malloc(sizeof(SEC_DESC)); + tmp = malloc_p(SEC_DESC); tmp->revision = 1; tmp->type = SEC_DESC_SELF_RELATIVE | SEC_DESC_DACL_PRESENT; @@ -577,7 +577,7 @@ static KEY_SEC_DESC *nt_create_init_sec(struct registry_hive *h) REGF *regf = h->backend_data; KEY_SEC_DESC *tsec = NULL; - tsec = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC)); + tsec = malloc_p(KEY_SEC_DESC); tsec->ref_cnt = 1; tsec->state = SEC_DESC_NBK; @@ -682,7 +682,7 @@ static SK_MAP *alloc_sk_map_entry(struct registry_hive *h, KEY_SEC_DESC *tmp, in { REGF *regf = h->backend_data; if (!regf->sk_map) { /* Allocate a block of 10 */ - regf->sk_map = (SK_MAP *)malloc(sizeof(SK_MAP) * 10); + regf->sk_map = malloc_array_p(SK_MAP, 10); regf->sk_map_size = 10; regf->sk_count = 1; (regf->sk_map)[0].sk_off = sk_off; @@ -742,7 +742,7 @@ static KEY_SEC_DESC *lookup_create_sec_key(struct registry_hive *h, SK_MAP *sk_m return tmp; } else { /* Allocate a new one */ - tmp = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC)); + tmp = malloc_p(KEY_SEC_DESC); memset(tmp, 0, sizeof(KEY_SEC_DESC)); /* Neatly sets offset to 0 */ tmp->state = SEC_DESC_RES; if (!alloc_sk_map_entry(h, tmp, sk_off)) { @@ -756,7 +756,7 @@ static SEC_DESC *process_sec_desc(struct registry_hive *regf, SEC_DESC *sec_desc { SEC_DESC *tmp = NULL; - tmp = (SEC_DESC *)malloc(sizeof(SEC_DESC)); + tmp = malloc_p(SEC_DESC); tmp->revision = SVAL(&sec_desc->revision,0); tmp->type = SVAL(&sec_desc->type,0); @@ -838,7 +838,7 @@ static KEY_SEC_DESC *process_sk(struct registry_hive *regf, SK_HDR *sk_hdr, int */ if (!tmp) { - tmp = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC)); + tmp = malloc_p(KEY_SEC_DESC); memset(tmp, 0, sizeof(KEY_SEC_DESC)); /* @@ -1154,7 +1154,7 @@ static HBIN_BLK *nt_create_hbin_blk(struct registry_hive *h, int size) size = (size + (REGF_HDR_BLKSIZ - 1)) & ~(REGF_HDR_BLKSIZ - 1); - tmp = (HBIN_BLK *)malloc(sizeof(HBIN_BLK)); + tmp = malloc_p(HBIN_BLK); memset(tmp, 0, sizeof(HBIN_BLK)); tmp->data = malloc(size); @@ -1553,7 +1553,7 @@ static REGF_HDR *nt_get_reg_header(struct registry_hive *h) { REGF *regf = h->backend_data; HBIN_BLK *tmp = NULL; - tmp = (HBIN_BLK *)malloc(sizeof(HBIN_BLK)); + tmp = malloc_p(HBIN_BLK); memset(tmp, 0, sizeof(HBIN_BLK)); tmp->type = REG_OUTBLK_HDR; diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 3333299088..f18b012720 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -247,7 +247,7 @@ static char **reg_complete_command(const char *text, int end) char **matches; int i, len, samelen=0, count=1; - matches = (char **)malloc(sizeof(matches[0])*MAX_COMPLETIONS); + matches = malloc_array_p(char *, MAX_COMPLETIONS); if (!matches) return NULL; matches[0] = NULL; @@ -301,7 +301,7 @@ static char **reg_complete_key(const char *text, int end) TALLOC_CTX *mem_ctx; /* Complete argument */ - matches = (char **)malloc(sizeof(matches[0])*MAX_COMPLETIONS); + matches = malloc_array_p(char *, MAX_COMPLETIONS); if (!matches) return NULL; matches[0] = NULL; -- cgit From 2f9e170f45e128eb6ab6bd97c9c8b40dcd9a97fa Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 4 Dec 2004 09:30:38 +0000 Subject: r4058: added a type safe version of smb_xmalloc() (This used to be commit 1235afa5fe3a396cd7a180cbc500834a30fbaa80) --- source4/lib/registry/tools/regpatch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index a8b2f83ee1..9b37b7952b 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -154,7 +154,7 @@ static void print_line(struct cmd_line *cl) */ static struct cmd_line *get_cmd_line(int fd) { - struct cmd_line *cl = (CMD_LINE *)smb_xmalloc(sizeof(CMD_LINE)); + struct cmd_line *cl = smb_xmalloc_p(CMD_LINE); int i = 0, rc; uint8_t ch; @@ -445,7 +445,7 @@ static CMD *regedit4_get_cmd(int fd) struct cmd_line *cl = NULL; struct val_spec_list *vl = NULL; - cmd = (struct command_s *)smb_xmalloc(sizeof(struct command_s)); + cmd = smb_xmalloc_p(struct command_s); cmd->cmd = CMD_NONE; cmd->key = NULL; @@ -488,7 +488,7 @@ static CMD *regedit4_get_cmd(int fd) * There could be a \ on the end which we need to * handle at some time */ - vl = (struct val_spec_list *)smb_xmalloc(sizeof(struct val_spec_list)); + vl = smb_xmalloc_p(struct val_spec_list); vl->next = NULL; vl->val = NULL; vl->name = parse_value(cl, &vl->type, &vl->val); @@ -607,7 +607,7 @@ static CMD_FILE *cmd_file_create(const char *file) return NULL; } - tmp = (CMD_FILE *)smb_xmalloc(sizeof(CMD_FILE)); + tmp = smb_xmalloc_p(CMD_FILE); /* * Let's fill in some of the fields; -- cgit From 9922c2d0357a89db4ee4abbb0beded6a0f24b010 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 4 Dec 2004 14:28:06 +0000 Subject: r4064: use the same name for type on both ends for long term we should remove all typedef's metze (This used to be commit 4b3f552cb373a0d91526412fc31699959c96a007) --- source4/lib/registry/tools/regpatch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 9b37b7952b..be60b96019 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -154,7 +154,7 @@ static void print_line(struct cmd_line *cl) */ static struct cmd_line *get_cmd_line(int fd) { - struct cmd_line *cl = smb_xmalloc_p(CMD_LINE); + CMD_LINE *cl = smb_xmalloc_p(CMD_LINE); int i = 0, rc; uint8_t ch; -- cgit From 4b533a90705115410575943ba0cf7630925f7421 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 8 Dec 2004 22:13:28 +0000 Subject: r4106: Add full name of two more hives (This used to be commit c1023db5e8336e495c06acae1773a28d7fc90658) --- source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/lib/registry') 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 1a7cb38af5..fae5d3f14e 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -64,6 +64,8 @@ openhive(HKCU) openhive(HKPD) openhive(HKU) openhive(HKCR) +openhive(HKDD) +openhive(HKCC) struct rpc_key_data { struct policy_handle pol; @@ -82,6 +84,8 @@ struct { { "HKEY_CLASSES_ROOT", open_HKCR }, { "HKEY_PERFORMANCE_DATA", open_HKPD }, { "HKEY_USERS", open_HKU }, +{ "HKEY_DYN_DATA", open_HKDD }, +{ "HKEY_CURRENT_CONFIG", open_HKCC }, { NULL, NULL } }; -- cgit From 2f1193715ff5815498f16cba4391d7ba5f212366 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 9 Dec 2004 12:42:29 +0000 Subject: r4116: fixed compilation of EnumValue code in winreg rpc backend thanks to volker for pointing this out (This used to be commit 2b67f18bdb58164697efd428391d4cbc46398464) --- .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 30 ++++++++++------------ 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'source4/lib/registry') 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 fae5d3f14e..3969a763e0 100644 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c @@ -226,9 +226,10 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *p struct rpc_key_data *mykeydata = parent->backend_data; WERROR error; struct winreg_EnumValue r; - uint32 type, len1, len2 = 0; - struct EnumValueIn buf_name, buf_val; + uint32 type, len1, zero = 0; NTSTATUS status; + uint8_t buf8; + uint16_t buf16; if(mykeydata->num_values == -1) { error = rpc_query_key(parent); @@ -239,19 +240,13 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *p r.in.handle = &mykeydata->pol; r.in.enum_index = n; - r.in.name_in.len = 0; - r.in.name_in.max_len = mykeydata->max_valnamelen * 2; - buf_name.max_len = mykeydata->max_valnamelen; - buf_name.offset = 0; - buf_name.len = 0; - r.in.name_in.buffer = &buf_name; + r.in.name_in.length = 0; + r.in.name_in.size = mykeydata->max_valnamelen * 2; + r.in.name_in.name = &buf16; r.in.type = &type; - buf_val.max_len = mykeydata->max_valdatalen; - buf_val.offset = 0; - buf_val.len = 0; - r.in.value_in = &buf_val; - r.in.value_len1 = &len1; - r.in.value_len2 = &len2; + r.in.value = &buf8; + r.in.length = &zero; + r.in.size = &len1; r.out.type = &type; @@ -261,13 +256,14 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *p return WERR_GENERAL_FAILURE; } - if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { + if(NT_STATUS_IS_OK(status) && + W_ERROR_IS_OK(r.out.result) && r.out.length) { *value = talloc_p(mem_ctx, struct registry_value); (*value)->parent = parent; (*value)->name = talloc_strdup(mem_ctx, r.out.name_out.name); (*value)->data_type = type; - (*value)->data_len = r.out.value_out->buffer.length; - (*value)->data_blk = talloc_memdup(mem_ctx, r.out.value_out->buffer.data, r.out.value_out->buffer.length); + (*value)->data_len = *r.out.length; + (*value)->data_blk = talloc_memdup(mem_ctx, r.out.value, *r.out.length); return WERR_OK; } -- cgit From 444a86792471c0bef33dde15c7a4a33e16a951b4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 10 Dec 2004 20:07:04 +0000 Subject: r4132: - Bunch of rather large fixes in the registry - Added some README files Not everything works yet, e.g. the EnumValue test appears to be broken. (This used to be commit c169e86c1f52763b83e77e509f89cb91f9b69071) --- source4/lib/registry/README | 30 + source4/lib/registry/common/reg_interface.c | 182 +- source4/lib/registry/config.mk | 17 +- source4/lib/registry/reg_backend_dir.c | 148 ++ .../lib/registry/reg_backend_dir/reg_backend_dir.c | 148 -- source4/lib/registry/reg_backend_gconf.c | 193 +++ .../registry/reg_backend_gconf/reg_backend_gconf.c | 193 --- source4/lib/registry/reg_backend_ldb.c | 219 +++ .../lib/registry/reg_backend_ldb/reg_backend_ldb.c | 219 --- source4/lib/registry/reg_backend_nt4.c | 1747 ++++++++++++++++++++ .../lib/registry/reg_backend_nt4/reg_backend_nt4.c | 1747 -------------------- source4/lib/registry/reg_backend_rpc.c | 398 +++++ .../lib/registry/reg_backend_rpc/reg_backend_rpc.c | 405 ----- source4/lib/registry/reg_backend_w95.c | 356 ++++ .../lib/registry/reg_backend_w95/reg_backend_w95.c | 356 ---- source4/lib/registry/reg_backend_wine.c | 48 + .../registry/reg_backend_wine/reg_backend_wine.c | 33 - source4/lib/registry/reg_samba.c | 62 + source4/lib/registry/tools/regdiff.c | 76 +- source4/lib/registry/tools/regpatch.c | 25 +- source4/lib/registry/tools/regshell.c | 87 +- source4/lib/registry/tools/regtree.c | 38 +- 22 files changed, 3418 insertions(+), 3309 deletions(-) create mode 100644 source4/lib/registry/README create mode 100644 source4/lib/registry/reg_backend_dir.c delete mode 100644 source4/lib/registry/reg_backend_dir/reg_backend_dir.c create mode 100644 source4/lib/registry/reg_backend_gconf.c delete mode 100644 source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c create mode 100644 source4/lib/registry/reg_backend_ldb.c delete mode 100644 source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c create mode 100644 source4/lib/registry/reg_backend_nt4.c delete mode 100644 source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c create mode 100644 source4/lib/registry/reg_backend_rpc.c delete mode 100644 source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c create mode 100644 source4/lib/registry/reg_backend_w95.c delete mode 100644 source4/lib/registry/reg_backend_w95/reg_backend_w95.c create mode 100644 source4/lib/registry/reg_backend_wine.c delete mode 100644 source4/lib/registry/reg_backend_wine/reg_backend_wine.c create mode 100644 source4/lib/registry/reg_samba.c (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/README b/source4/lib/registry/README new file mode 100644 index 0000000000..757029cdc2 --- /dev/null +++ b/source4/lib/registry/README @@ -0,0 +1,30 @@ +This is the registry library. The registry is basically a bunch of hives +(HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, etc) that can be loaded from +different places. + +The various registry backends provide support for loading/saving specific types +of hives: + - ldb + - w95 (USER.DAT-style files) + - nt4 (NTUSER.DAT-style files) + - gconf (GNOME configuration) + - rpc (Remote individual hives) + +Instead of opening individual hives, one can also open a 'complete' registry by +using one of these three functions: + + - reg_open_local() - load local registry, see below + - reg_open_remote() - connect to remote registry over RPC + - reg_open_wine() (not working yet) + +reg_open_local() loads a set of hives based on smb.conf settings. +Lines in smb.conf should have the following syntax: + +registry: = : + +So an example usage could be: + +registry:HKEY_CURRENT_USER = nt4:NTUSER.DAT +registry:HKEY_LOCAL_MACHINE = ldb:tdb://registry.tdb + +WERR_NOT_SUPPORTED will be returned for all hives that haven't been set. diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index f7d3af0705..740d849db1 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -30,32 +30,25 @@ static struct reg_init_function_entry *backends = NULL; static struct reg_init_function_entry *reg_find_backend_entry(const char *name); -#define reg_make_path(mem_ctx, parent, name) (((parent)->hive->root == (parent))?talloc_strdup(mem_ctx, name):talloc_asprintf(mem_ctx, "%s\\%s", parent->path, name)) - /* Register new backend */ -NTSTATUS registry_register(const void *_function) +NTSTATUS registry_register(const void *_hive_ops) { - const struct registry_operations *functions = _function; + const struct hive_operations *hive_ops = _hive_ops; struct reg_init_function_entry *entry = backends; - if (!functions || !functions->name) { - DEBUG(0, ("Invalid arguments while registering registry backend\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - DEBUG(5,("Attempting to register registry backend %s\n", functions->name)); + DEBUG(5,("Attempting to register registry backend %s\n", hive_ops->name)); /* Check for duplicates */ - if (reg_find_backend_entry(functions->name)) { - DEBUG(0,("There already is a registry backend registered with the name %s!\n", functions->name)); + if (reg_find_backend_entry(hive_ops->name)) { + DEBUG(0,("There already is a registry backend registered with the name %s!\n", hive_ops->name)); return NT_STATUS_OBJECT_NAME_COLLISION; } - entry = malloc_p(struct reg_init_function_entry); - entry->functions = functions; + entry = talloc_p(NULL, struct reg_init_function_entry); + entry->hive_functions = hive_ops; DLIST_ADD(backends, entry); - DEBUG(5,("Successfully added registry backend '%s'\n", functions->name)); + DEBUG(5,("Successfully added registry backend '%s'\n", hive_ops->name)); return NT_STATUS_OK; } @@ -67,7 +60,7 @@ static struct reg_init_function_entry *reg_find_backend_entry(const char *name) entry = backends; while(entry) { - if (strcmp(entry->functions->name, name) == 0) return entry; + if (strcmp(entry->hive_functions->name, name) == 0) return entry; entry = entry->next; } @@ -80,85 +73,83 @@ BOOL reg_has_backend(const char *backend) return reg_find_backend_entry(backend) != NULL?True:False; } -WERROR reg_create(struct registry_context **_ret) +static struct { + uint32 hkey; + const char *name; +} hkey_names[] = { - TALLOC_CTX *mem_ctx; - struct registry_context *ret; - mem_ctx = talloc_init("registry handle"); - ret = talloc_p(mem_ctx, struct registry_context); - ret->mem_ctx = mem_ctx; - ZERO_STRUCTP(ret); - *_ret = ret; - return WERR_OK; -} - -WERROR reg_list_available_hives(TALLOC_CTX *mem_ctx, const char *backend, const char *location, const char *credentials, char ***hives) + {HKEY_CLASSES_ROOT,"HKEY_CLASSES_ROOT" }, + {HKEY_CURRENT_USER,"HKEY_CURRENT_USER" }, + {HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" }, + {HKEY_PERFORMANCE_DATA, "HKEY_PERFORMANCE_DATA" }, + {HKEY_USERS, "HKEY_USERS" }, + {HKEY_CURRENT_CONFIG, "HKEY_CURRENT_CONFIG" }, + {HKEY_DYN_DATA, "HKEY_DYN_DATA" }, + {HKEY_PT, "HKEY_PT" }, + {HKEY_PN, "HKEY_PN" }, + { 0, NULL } +}; + +int reg_list_hives(TALLOC_CTX *mem_ctx, char ***hives, uint32_t **hkeys) { - struct reg_init_function_entry *entry; - - entry = reg_find_backend_entry(backend); - - if (!entry) { - DEBUG(0, ("No such registry backend '%s' loaded!\n", backend)); - return WERR_GENERAL_FAILURE; - } + int i; + *hives = talloc_array_p(mem_ctx, char *, ARRAY_SIZE(hkey_names)); + *hkeys = talloc_array_p(mem_ctx, uint32_t, ARRAY_SIZE(hkey_names)); - if(!entry->functions->list_available_hives) { - return WERR_NOT_SUPPORTED; + for (i = 0; hkey_names[i].name; i++) { + (*hives)[i] = talloc_strdup(mem_ctx, hkey_names[i].name); + (*hkeys)[i] = hkey_names[i].hkey; } - return entry->functions->list_available_hives(mem_ctx, location, credentials, hives); + return i; } -WERROR reg_open(struct registry_context **ret, const char *backend, const char *location, const char *credentials) +const char *reg_get_hkey_name(uint32_t hkey) { - WERROR error = reg_create(ret), reterror = WERR_NO_MORE_ITEMS; - char **hives; - int i, j; - TALLOC_CTX *mem_ctx = talloc_init("reg_open"); - - if(!W_ERROR_IS_OK(error)) return error; - - error = reg_list_available_hives(mem_ctx, backend, location, credentials, &hives); - - if(W_ERROR_EQUAL(error, WERR_NOT_SUPPORTED)) { - return reg_import_hive(*ret, backend, location, credentials, NULL); + int i; + for (i = 0; hkey_names[i].name; i++) { + if (hkey_names[i].hkey == hkey) return hkey_names[i].name; } - - if(!W_ERROR_IS_OK(error)) return error; - j = 0; - for(i = 0; hives[i]; i++) - { - error = reg_import_hive(*ret, backend, location, credentials, hives[i]); - if (W_ERROR_IS_OK(error)) { - reterror = WERR_OK; - (*ret)->hives[j]->name = talloc_strdup((*ret)->mem_ctx, hives[i]); - j++; - } else if (!W_ERROR_IS_OK(reterror)) reterror = error; + return NULL; +} + +WERROR reg_get_hive_by_name(struct registry_context *ctx, const char *name, struct registry_key **key) +{ + int i; + + for (i = 0; hkey_names[i].name; i++) { + if (!strcmp(hkey_names[i].name, name)) return reg_get_hive(ctx, hkey_names[i].hkey, key); } - return reterror; + DEBUG(1, ("No hive with name '%s'\n", name)); + + return WERR_BADFILE; } WERROR reg_close (struct registry_context *ctx) { - int i; - for (i = 0; i < ctx->num_hives; i++) { - if (ctx->hives[i]->functions->close_hive) { - ctx->hives[i]->functions->close_hive(ctx->hives[i]); - } - } talloc_destroy(ctx); return WERR_OK; } +WERROR reg_get_hive(struct registry_context *ctx, uint32_t hkey, struct registry_key **key) +{ + WERROR ret = ctx->get_hive(ctx, hkey, key); + + if (W_ERROR_IS_OK(ret)) { + (*key)->name = talloc_strdup(*key, reg_get_hkey_name(hkey)); + (*key)->path = ""; + } + + return ret; +} + /* Open a registry file/host/etc */ -WERROR reg_import_hive(struct registry_context *h, const char *backend, const char *location, const char *credentials, const char *hivename) +WERROR reg_open_hive(struct registry_context *parent_ctx, const char *backend, const char *location, const char *credentials, struct registry_key **root) { struct registry_hive *ret; - TALLOC_CTX *mem_ctx; struct reg_init_function_entry *entry; WERROR werr; @@ -169,24 +160,21 @@ WERROR reg_import_hive(struct registry_context *h, const char *backend, const ch return WERR_GENERAL_FAILURE; } - if(!entry->functions->open_hive) { + if(!entry->hive_functions || !entry->hive_functions->open_hive) { return WERR_NOT_SUPPORTED; } - - mem_ctx = h->mem_ctx; - ret = talloc_p(mem_ctx, struct registry_hive); - ret->location = location?talloc_strdup(mem_ctx, location):NULL; - ret->backend_hivename = hivename?talloc_strdup(mem_ctx, hivename):NULL; - ret->credentials = credentials?talloc_strdup(mem_ctx, credentials):NULL; - ret->functions = entry->functions; + ret = talloc_p(parent_ctx, struct registry_hive); + ret->location = location?talloc_strdup(ret, location):NULL; + ret->functions = entry->hive_functions; ret->backend_data = NULL; - ret->reg_ctx = h; - ret->name = NULL; + ret->reg_ctx = parent_ctx; - werr = entry->functions->open_hive(mem_ctx, ret, &ret->root); + werr = entry->hive_functions->open_hive(ret, &ret->root); - if(!W_ERROR_IS_OK(werr)) return werr; + if(!W_ERROR_IS_OK(werr)) { + return werr; + } if(!ret->root) { DEBUG(0, ("Backend %s didn't provide root key!\n", backend)); @@ -195,12 +183,9 @@ WERROR reg_import_hive(struct registry_context *h, const char *backend, const ch ret->root->hive = ret; ret->root->name = NULL; - ret->root->path = talloc_strdup(mem_ctx, ""); - - /* Add hive to context */ - h->num_hives++; - h->hives = talloc_realloc_p(h, h->hives, struct registry_hive *, h->num_hives); - h->hives[h->num_hives-1] = ret; + ret->root->path = talloc_strdup(ret, ""); + + *root = ret->root; return WERR_OK; } @@ -217,7 +202,7 @@ WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, co else hivelength = strlen(name); hivename = strndup(name, hivelength); - error = reg_get_hive(handle, hivename, &hive); + error = reg_get_hive_by_name(handle, hivename, &hive); SAFE_FREE(hivename); if(!W_ERROR_IS_OK(error)) { @@ -272,7 +257,8 @@ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char return WERR_NOT_SUPPORTED; } - fullname = reg_make_path(mem_ctx, parent, name); + + fullname = ((parent->hive->root == parent)?talloc_strdup(mem_ctx, name):talloc_asprintf(mem_ctx, "%s\\%s", parent->path, name)); error = parent->hive->functions->open_key(mem_ctx, parent->hive, fullname, result); @@ -499,7 +485,7 @@ WERROR reg_key_add_name_recursive_abs(struct registry_context *handle, const cha else hivelength = strlen(name); hivename = strndup(name, hivelength); - error = reg_get_hive(handle, hivename, &hive); + error = reg_get_hive_by_name(handle, hivename, &hive); SAFE_FREE(hivename); if(!W_ERROR_IS_OK(error)) return error; @@ -578,19 +564,7 @@ WERROR reg_val_set(struct registry_key *key, const char *value, int type, void * return WERR_NOT_SUPPORTED; } -WERROR reg_get_hive(struct registry_context *h, const char *name, struct registry_key **key) -{ - int i; - for(i = 0; i < h->num_hives; i++) - { - if(!strcmp(h->hives[i]->name, name)) { - *key = h->hives[i]->root; - return WERR_OK; - } - } - return WERR_NO_MORE_ITEMS; -} WERROR reg_del_value(struct registry_value *val) { diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index b91ec647a0..af9fb83bab 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -6,7 +6,7 @@ INIT_FUNCTION = registry_nt4_init SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ - lib/registry/reg_backend_nt4/reg_backend_nt4.o + lib/registry/reg_backend_nt4.o # End MODULE registry_nt4 ################################################ @@ -16,7 +16,7 @@ INIT_OBJ_FILES = \ INIT_FUNCTION = registry_w95_init SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ - lib/registry/reg_backend_w95/reg_backend_w95.o + lib/registry/reg_backend_w95.o # End MODULE registry_w95 ################################################ @@ -26,7 +26,7 @@ INIT_OBJ_FILES = \ INIT_FUNCTION = registry_dir_init SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ - lib/registry/reg_backend_dir/reg_backend_dir.o + lib/registry/reg_backend_dir.o # End MODULE registry_dir ################################################ @@ -36,18 +36,20 @@ INIT_OBJ_FILES = \ INIT_FUNCTION = registry_rpc_init SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ - lib/registry/reg_backend_rpc/reg_backend_rpc.o + lib/registry/reg_backend_rpc.o REQUIRED_SUBSYSTEMS = RPC_NDR_WINREG # End MODULE registry_rpc ################################################ + + ################################################ # Start MODULE registry_gconf [MODULE::registry_gconf] INIT_FUNCTION = registry_gconf_init SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ - lib/registry/reg_backend_gconf/reg_backend_gconf.o + lib/registry/reg_backend_gconf.o REQUIRED_SUBSYSTEMS = EXT_LIB_gconf # End MODULE registry_gconf ################################################ @@ -58,7 +60,7 @@ REQUIRED_SUBSYSTEMS = EXT_LIB_gconf INIT_FUNCTION = registry_ldb_init SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ - lib/registry/reg_backend_ldb/reg_backend_ldb.o + lib/registry/reg_backend_ldb.o REQUIRED_SUBSYSTEMS = \ LIBLDB # End MODULE registry_ldb @@ -70,7 +72,8 @@ REQUIRED_SUBSYSTEMS = \ INIT_OBJ_FILES = \ lib/registry/common/reg_interface.o ADD_OBJ_FILES = \ - lib/registry/common/reg_util.o + lib/registry/common/reg_util.o \ + lib/registry/reg_samba.o REQUIRED_SUBSYSTEMS = \ LIBBASIC # End MODULE registry_ldb diff --git a/source4/lib/registry/reg_backend_dir.c b/source4/lib/registry/reg_backend_dir.c new file mode 100644 index 0000000000..5c3ed3c44c --- /dev/null +++ b/source4/lib/registry/reg_backend_dir.c @@ -0,0 +1,148 @@ +/* + Unix SMB/CIFS implementation. + Registry interface + Copyright (C) Jelmer Vernooij 2004. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#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) +{ + char *path; + int ret; + asprintf(&path, "%s%s\\%s", parent->hive->location, parent->path, name); + path = reg_path_win2unix(path); + ret = mkdir(path, 0700); + SAFE_FREE(path); + if(ret == 0)return WERR_OK; /* FIXME */ + return WERR_INVALID_PARAM; +} + +static WERROR reg_dir_del_key(struct registry_key *k) +{ + return (rmdir((char *)k->backend_data) == 0)?WERR_OK:WERR_GENERAL_FAILURE; +} + +static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **subkey) +{ + DIR *d; + char *fullpath; + struct registry_key *ret; + + if(!name) { + DEBUG(0, ("NULL pointer passed as directory name!")); + return WERR_INVALID_PARAM; + } + + + fullpath = talloc_asprintf(mem_ctx, "%s%s", h->location, name); + fullpath = reg_path_win2unix(fullpath); + + d = opendir(fullpath); + if(!d) { + DEBUG(3,("Unable to open '%s': %s\n", fullpath, strerror(errno))); + return WERR_BADFILE; + } + closedir(d); + ret = talloc_p(mem_ctx, struct registry_key); + ret->hive = h; + ret->path = fullpath; + *subkey = ret; + return WERR_OK; +} + +static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_key **key) +{ + struct dirent *e; + char *fullpath = k->backend_data; + int i = 0; + DIR *d; + + d = opendir(fullpath); + + if(!d) return WERR_INVALID_PARAM; + + while((e = readdir(d))) { + if( strcmp(e->d_name, ".") && + strcmp(e->d_name, "..")) { + struct stat stbuf; + char *thispath; + + /* Check if file is a directory */ + asprintf(&thispath, "%s/%s", fullpath, e->d_name); + stat(thispath, &stbuf); + + if(S_ISDIR(stbuf.st_mode)) { + i++; + if(i == idx) { + (*key) = talloc_p(mem_ctx, struct registry_key); + (*key)->name = e->d_name; + (*key)->path = NULL; + (*key)->backend_data = talloc_strdup(mem_ctx, thispath); + SAFE_FREE(thispath); + closedir(d); + return WERR_OK; + } + } + + SAFE_FREE(thispath); + } + } + + closedir(d); + + return WERR_NO_MORE_ITEMS; +} + +static WERROR reg_dir_open(struct registry_hive *h, struct registry_key **key) +{ + if(!h->location) return WERR_INVALID_PARAM; + + *key = talloc_p(h, struct registry_key); + (*key)->backend_data = talloc_strdup(*key, h->location); + return WERR_OK; +} + +static WERROR reg_dir_set_value(struct registry_key *p, const char *name, int type, void *data, int len) +{ + /* FIXME */ + return WERR_NOT_SUPPORTED; +} + +static WERROR reg_dir_del_value(struct registry_value *v) +{ + /* FIXME*/ + return WERR_NOT_SUPPORTED; +} + +static struct hive_operations reg_backend_dir = { + .name = "dir", + .open_hive = reg_dir_open, + .open_key = reg_dir_open_key, + .add_key = reg_dir_add_key, + .del_key = reg_dir_del_key, + .get_subkey_by_index = reg_dir_key_by_index, + .set_value = reg_dir_set_value, + .del_value = reg_dir_del_value, +}; + +NTSTATUS registry_dir_init(void) +{ + return registry_register(®_backend_dir); +} diff --git a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c deleted file mode 100644 index 8712e7ce7c..0000000000 --- a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Registry interface - Copyright (C) Jelmer Vernooij 2004. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" -#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) -{ - char *path; - int ret; - asprintf(&path, "%s%s\\%s", parent->hive->location, parent->path, name); - path = reg_path_win2unix(path); - ret = mkdir(path, 0700); - SAFE_FREE(path); - if(ret == 0)return WERR_OK; /* FIXME */ - return WERR_INVALID_PARAM; -} - -static WERROR reg_dir_del_key(struct registry_key *k) -{ - return (rmdir((char *)k->backend_data) == 0)?WERR_OK:WERR_GENERAL_FAILURE; -} - -static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **subkey) -{ - DIR *d; - char *fullpath; - struct registry_key *ret; - - if(!name) { - DEBUG(0, ("NULL pointer passed as directory name!")); - return WERR_INVALID_PARAM; - } - - - fullpath = talloc_asprintf(mem_ctx, "%s%s", h->location, name); - fullpath = reg_path_win2unix(fullpath); - - d = opendir(fullpath); - if(!d) { - DEBUG(3,("Unable to open '%s': %s\n", fullpath, strerror(errno))); - return WERR_BADFILE; - } - closedir(d); - ret = talloc_p(mem_ctx, struct registry_key); - ret->hive = h; - ret->path = fullpath; - *subkey = ret; - return WERR_OK; -} - -static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_key **key) -{ - struct dirent *e; - char *fullpath = k->backend_data; - int i = 0; - DIR *d; - - d = opendir(fullpath); - - if(!d) return WERR_INVALID_PARAM; - - while((e = readdir(d))) { - if( strcmp(e->d_name, ".") && - strcmp(e->d_name, "..")) { - struct stat stbuf; - char *thispath; - - /* Check if file is a directory */ - asprintf(&thispath, "%s/%s", fullpath, e->d_name); - stat(thispath, &stbuf); - - if(S_ISDIR(stbuf.st_mode)) { - i++; - if(i == idx) { - (*key) = talloc_p(mem_ctx, struct registry_key); - (*key)->name = e->d_name; - (*key)->path = NULL; - (*key)->backend_data = talloc_strdup(mem_ctx, thispath); - SAFE_FREE(thispath); - closedir(d); - return WERR_OK; - } - } - - SAFE_FREE(thispath); - } - } - - closedir(d); - - return WERR_NO_MORE_ITEMS; -} - -static WERROR reg_dir_open(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **key) -{ - if(!h->location) return WERR_INVALID_PARAM; - - *key = talloc_p(mem_ctx, struct registry_key); - (*key)->backend_data = talloc_strdup(mem_ctx, h->location); - return WERR_OK; -} - -static WERROR reg_dir_set_value(struct registry_key *p, const char *name, int type, void *data, int len) -{ - /* FIXME */ - return WERR_NOT_SUPPORTED; -} - -static WERROR reg_dir_del_value(struct registry_value *v) -{ - /* FIXME*/ - return WERR_NOT_SUPPORTED; -} - -static struct registry_operations reg_backend_dir = { - .name = "dir", - .open_hive = reg_dir_open, - .open_key = reg_dir_open_key, - .add_key = reg_dir_add_key, - .del_key = reg_dir_del_key, - .get_subkey_by_index = reg_dir_key_by_index, - .set_value = reg_dir_set_value, - .del_value = reg_dir_del_value, -}; - -NTSTATUS registry_dir_init(void) -{ - return registry_register(®_backend_dir); -} diff --git a/source4/lib/registry/reg_backend_gconf.c b/source4/lib/registry/reg_backend_gconf.c new file mode 100644 index 0000000000..2fed2417b7 --- /dev/null +++ b/source4/lib/registry/reg_backend_gconf.c @@ -0,0 +1,193 @@ +/* + Unix SMB/CIFS implementation. + Registry interface + Copyright (C) Jelmer Vernooij 2004. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "registry.h" +#include + +static WERROR gerror_to_werror(GError *error) +{ + if(error == NULL) return WERR_OK; + /* FIXME */ + return WERR_FOOBAR; +} + +static WERROR reg_open_gconf_hive(struct registry_hive *h, struct registry_key **k) +{ + g_type_init(); + h->backend_data = (void *)gconf_client_get_default(); + if(!h->backend_data) return WERR_FOOBAR; + + *k = talloc_p(h, struct registry_key); + (*k)->name = talloc_strdup(*k, ""); + (*k)->path = talloc_strdup(*k, ""); + (*k)->backend_data = talloc_strdup(*k, "/"); + return WERR_OK; +} + +static WERROR gconf_open_key (TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **key) +{ + struct registry_key *ret; + char *fullpath; + + fullpath = talloc_asprintf(mem_ctx, "/%s", reg_path_win2unix(talloc_strdup(mem_ctx, name))); + + /* Check if key exists */ + if(!gconf_client_dir_exists((GConfClient *)h->backend_data, fullpath, NULL)) { + return WERR_DEST_NOT_FOUND; + } + + ret = talloc_p(mem_ctx, struct registry_key); + ret->backend_data = fullpath; + + *key = ret; + return WERR_OK; +} + +static WERROR gconf_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *p, int idx, struct registry_value **val) +{ + GSList *entries; + GSList *cur; + GConfEntry *entry; + GConfValue *value; + struct registry_value *newval; + char *fullpath = p->backend_data; + int i; + cur = entries = gconf_client_all_entries((GConfClient*)p->hive->backend_data, fullpath, NULL); + + for(i = 0; i < idx && cur; i++) cur = cur->next; + + if(!cur) return WERR_NO_MORE_ITEMS; + + entry = cur->data; + value = gconf_entry_get_value(entry); + + newval = talloc_p(mem_ctx, struct registry_value); + newval->name = talloc_strdup(mem_ctx, strrchr(gconf_entry_get_key(entry), '/')+1); + if(value) { + switch(value->type) { + case GCONF_VALUE_INVALID: + newval->data_type = REG_NONE; + break; + + case GCONF_VALUE_STRING: + newval->data_type = REG_SZ; + newval->data_blk = talloc_strdup(mem_ctx, gconf_value_get_string(value)); + newval->data_len = strlen(newval->data_blk); + break; + + case GCONF_VALUE_INT: + newval->data_type = REG_DWORD; + newval->data_blk = talloc_p(mem_ctx, long); + *((long *)newval->data_blk) = gconf_value_get_int(value); + newval->data_len = sizeof(long); + break; + + case GCONF_VALUE_FLOAT: + newval->data_blk = talloc_p(mem_ctx, double); + newval->data_type = REG_BINARY; + *((double *)newval->data_blk) = gconf_value_get_float(value); + newval->data_len = sizeof(double); + break; + + case GCONF_VALUE_BOOL: + newval->data_blk = talloc_p(mem_ctx, BOOL); + newval->data_type = REG_BINARY; + *((BOOL *)newval->data_blk) = gconf_value_get_bool(value); + newval->data_len = sizeof(BOOL); + break; + + default: + newval->data_type = REG_NONE; + DEBUG(0, ("Not implemented..\n")); + break; + } + } else newval->data_type = REG_NONE; + + g_slist_free(entries); + *val = newval; + return WERR_OK; +} + +static WERROR gconf_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *p, int idx, struct registry_key **sub) +{ + GSList *dirs; + GSList *cur; + int i; + char *fullpath = p->backend_data; + cur = dirs = gconf_client_all_dirs((GConfClient*)p->hive->backend_data, fullpath,NULL); + + for(i = 0; i < idx && cur; i++) cur = cur->next; + + if(!cur) return WERR_NO_MORE_ITEMS; + + *sub = talloc_p(mem_ctx, struct registry_key); + (*sub)->name = talloc_strdup(mem_ctx, strrchr((char *)cur->data, '/')+1); + (*sub)->backend_data = talloc_strdup(mem_ctx, cur->data); + + g_slist_free(dirs); + return WERR_OK; +} + +static WERROR gconf_set_value(struct registry_key *key, const char *valname, int type, void *data, int len) +{ + GError *error = NULL; + char *valpath; + asprintf(&valpath, "%s/%s", key->path, valname); + + switch(type) { + case REG_SZ: + case REG_EXPAND_SZ: + gconf_client_set_string((GConfClient *)key->hive->backend_data, valpath, data, &error); + SAFE_FREE(valpath); + return gerror_to_werror(error); + + case REG_DWORD: + gconf_client_set_int((GConfClient *)key->hive->backend_data, valpath, + *((int *)data), &error); + SAFE_FREE(valpath); + return gerror_to_werror(error); + default: + DEBUG(0, ("Unsupported type: %d\n", type)); + SAFE_FREE(valpath); + return WERR_NOT_SUPPORTED; + } + + return WERR_NOT_SUPPORTED; +} + +static struct hive_operations reg_backend_gconf = { + .name = "gconf", + .open_hive = reg_open_gconf_hive, + .open_key = gconf_open_key, + .get_subkey_by_index = gconf_get_subkey_by_id, + .get_value_by_index = gconf_get_value_by_id, + .set_value = gconf_set_value, + + /* Note: + * since GConf uses schemas for what keys and values are allowed, there + * is no way of 'emulating' add_key and del_key here. + */ +}; + +NTSTATUS registry_gconf_init(void) +{ + return registry_register(®_backend_gconf); +} diff --git a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c deleted file mode 100644 index fd258ca285..0000000000 --- a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Registry interface - Copyright (C) Jelmer Vernooij 2004. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" -#include "registry.h" -#include - -static WERROR gerror_to_werror(GError *error) -{ - if(error == NULL) return WERR_OK; - /* FIXME */ - return WERR_FOOBAR; -} - -static WERROR reg_open_gconf_hive(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **k) -{ - g_type_init(); - h->backend_data = (void *)gconf_client_get_default(); - if(!h->backend_data) return WERR_FOOBAR; - - *k = talloc_p(mem_ctx, struct registry_key); - (*k)->name = talloc_strdup(mem_ctx, ""); - (*k)->path = talloc_strdup(mem_ctx, ""); - (*k)->backend_data = talloc_strdup(mem_ctx, "/"); - return WERR_OK; -} - -static WERROR gconf_open_key (TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **key) -{ - struct registry_key *ret; - char *fullpath; - - fullpath = talloc_asprintf(mem_ctx, "/%s", reg_path_win2unix(talloc_strdup(mem_ctx, name))); - - /* Check if key exists */ - if(!gconf_client_dir_exists((GConfClient *)h->backend_data, fullpath, NULL)) { - return WERR_DEST_NOT_FOUND; - } - - ret = talloc_p(mem_ctx, struct registry_key); - ret->backend_data = fullpath; - - *key = ret; - return WERR_OK; -} - -static WERROR gconf_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *p, int idx, struct registry_value **val) -{ - GSList *entries; - GSList *cur; - GConfEntry *entry; - GConfValue *value; - struct registry_value *newval; - char *fullpath = p->backend_data; - int i; - cur = entries = gconf_client_all_entries((GConfClient*)p->hive->backend_data, fullpath, NULL); - - for(i = 0; i < idx && cur; i++) cur = cur->next; - - if(!cur) return WERR_NO_MORE_ITEMS; - - entry = cur->data; - value = gconf_entry_get_value(entry); - - newval = talloc_p(mem_ctx, struct registry_value); - newval->name = talloc_strdup(mem_ctx, strrchr(gconf_entry_get_key(entry), '/')+1); - if(value) { - switch(value->type) { - case GCONF_VALUE_INVALID: - newval->data_type = REG_NONE; - break; - - case GCONF_VALUE_STRING: - newval->data_type = REG_SZ; - newval->data_blk = talloc_strdup(mem_ctx, gconf_value_get_string(value)); - newval->data_len = strlen(newval->data_blk); - break; - - case GCONF_VALUE_INT: - newval->data_type = REG_DWORD; - newval->data_blk = talloc_p(mem_ctx, long); - *((long *)newval->data_blk) = gconf_value_get_int(value); - newval->data_len = sizeof(long); - break; - - case GCONF_VALUE_FLOAT: - newval->data_blk = talloc_p(mem_ctx, double); - newval->data_type = REG_BINARY; - *((double *)newval->data_blk) = gconf_value_get_float(value); - newval->data_len = sizeof(double); - break; - - case GCONF_VALUE_BOOL: - newval->data_blk = talloc_p(mem_ctx, BOOL); - newval->data_type = REG_BINARY; - *((BOOL *)newval->data_blk) = gconf_value_get_bool(value); - newval->data_len = sizeof(BOOL); - break; - - default: - newval->data_type = REG_NONE; - DEBUG(0, ("Not implemented..\n")); - break; - } - } else newval->data_type = REG_NONE; - - g_slist_free(entries); - *val = newval; - return WERR_OK; -} - -static WERROR gconf_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *p, int idx, struct registry_key **sub) -{ - GSList *dirs; - GSList *cur; - int i; - char *fullpath = p->backend_data; - cur = dirs = gconf_client_all_dirs((GConfClient*)p->hive->backend_data, fullpath,NULL); - - for(i = 0; i < idx && cur; i++) cur = cur->next; - - if(!cur) return WERR_NO_MORE_ITEMS; - - *sub = talloc_p(mem_ctx, struct registry_key); - (*sub)->name = talloc_strdup(mem_ctx, strrchr((char *)cur->data, '/')+1); - (*sub)->backend_data = talloc_strdup(mem_ctx, cur->data); - - g_slist_free(dirs); - return WERR_OK; -} - -static WERROR gconf_set_value(struct registry_key *key, const char *valname, int type, void *data, int len) -{ - GError *error = NULL; - char *valpath; - asprintf(&valpath, "%s/%s", key->path, valname); - - switch(type) { - case REG_SZ: - case REG_EXPAND_SZ: - gconf_client_set_string((GConfClient *)key->hive->backend_data, valpath, data, &error); - SAFE_FREE(valpath); - return gerror_to_werror(error); - - case REG_DWORD: - gconf_client_set_int((GConfClient *)key->hive->backend_data, valpath, - *((int *)data), &error); - SAFE_FREE(valpath); - return gerror_to_werror(error); - default: - DEBUG(0, ("Unsupported type: %d\n", type)); - SAFE_FREE(valpath); - return WERR_NOT_SUPPORTED; - } - - return WERR_NOT_SUPPORTED; -} - -static struct registry_operations reg_backend_gconf = { - .name = "gconf", - .open_hive = reg_open_gconf_hive, - .open_key = gconf_open_key, - .get_subkey_by_index = gconf_get_subkey_by_id, - .get_value_by_index = gconf_get_value_by_id, - .set_value = gconf_set_value, - - /* Note: - * since GConf uses schemas for what keys and values are allowed, there - * is no way of 'emulating' add_key and del_key here. - */ -}; - -NTSTATUS registry_gconf_init(void) -{ - return registry_register(®_backend_gconf); -} diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c new file mode 100644 index 0000000000..7eaf6194a5 --- /dev/null +++ b/source4/lib/registry/reg_backend_ldb.c @@ -0,0 +1,219 @@ +/* + Unix SMB/CIFS implementation. + Registry interface + Copyright (C) Jelmer Vernooij 2004. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "registry.h" +#include "lib/ldb/include/ldb.h" + +static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char *add) +{ + char *ret = talloc_strdup(mem_ctx, ""); + char *mypath = strdup(path); + char *end = mypath, *begin; + + if(add) + ret = talloc_asprintf_append(ret, "%s", add); + + while(end) { + char *keyname; + begin = strrchr(end, '\\'); + + if(begin) keyname = begin + 1; + else keyname = mypath; + + if(strlen(keyname)) + ret = talloc_asprintf_append(ret, "key=%s,", keyname); + + if(begin) { + *begin = '\0'; + end = begin-1; + } else { + end = NULL; + } + } + + SAFE_FREE(mypath); + + ret[strlen(ret)-1] = '\0'; + + if(strlen(ret) == 0) return NULL; + + return ret; +} + + +static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_key **subkey) +{ + struct ldb_context *c = k->hive->backend_data; + int ret; + struct ldb_message **msg; + struct ldb_message_element *el; + + ret = ldb_search(c, (char *)k->backend_data, LDB_SCOPE_ONELEVEL, "(key=*)", NULL,&msg); + + if(ret < 0) { + DEBUG(0, ("Error getting subkeys for '%s': %s\n", (char *)k->backend_data, ldb_errstring(c))); + return WERR_FOOBAR; + } + + if(idx >= ret) return WERR_NO_MORE_ITEMS; + + el = ldb_msg_find_element(msg[idx], "key"); + + *subkey = talloc_p(mem_ctx, struct registry_key); + (*subkey)->name = talloc_strdup(mem_ctx, el->values[0].data); + (*subkey)->backend_data = talloc_strdup(mem_ctx, msg[idx]->dn); + + ldb_search_free(c, msg); + return WERR_OK; +} + +static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_value **value) +{ + struct ldb_context *c = k->hive->backend_data; + int ret; + struct ldb_message **msg; + struct ldb_message_element *el; + + ret = ldb_search(c, (char *)k->backend_data, LDB_SCOPE_ONELEVEL, "(value=*)", NULL,&msg); + + if(ret < 0) { + DEBUG(0, ("Error getting values for '%s': %s\n", (char *)k->backend_data, ldb_errstring(c))); + return WERR_FOOBAR; + } + + if(idx >= ret) return WERR_NO_MORE_ITEMS; + + el = ldb_msg_find_element(msg[idx], "value"); + + *value = talloc_p(mem_ctx, struct registry_value); + (*value)->name = talloc_strdup(mem_ctx, el->values[0].data); + (*value)->backend_data = talloc_strdup(mem_ctx, msg[idx]->dn); + + ldb_search_free(c, msg); + return WERR_OK; +} + +static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **key) +{ + struct ldb_context *c = h->backend_data; + struct ldb_message **msg; + char *ldap_path; + int ret; + ldap_path = reg_path_to_ldb(mem_ctx, name, NULL); + + ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL,&msg); + + if(ret == 0) { + return WERR_NO_MORE_ITEMS; + } else if(ret < 0) { + DEBUG(0, ("Error opening key '%s': %s\n", ldap_path, ldb_errstring(c))); + return WERR_FOOBAR; + } + + *key = talloc_p(mem_ctx, struct registry_key); + (*key)->name = talloc_strdup(mem_ctx, strrchr(name, '\\')); + (*key)->backend_data = talloc_strdup(mem_ctx, msg[0]->dn); + + ldb_search_free(c, msg); + + return WERR_OK; +} + +static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) +{ + struct ldb_context *c; + + if (!hive->location) return WERR_INVALID_PARAM; + c = ldb_connect(hive->location, 0, NULL); + + if(!c) { + DEBUG(1, ("ldb_open_hive: %s\n", ldb_errstring(hive->backend_data))); + return WERR_FOOBAR; + } + ldb_set_debug_stderr(c); + hive->backend_data = c; + + hive->root = talloc_zero_p(hive, struct registry_key); + hive->root->name = talloc_strdup(hive->root, ""); + + 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) +{ + struct ldb_context *ctx = parent->hive->backend_data; + struct ldb_message msg; + int ret; + + ZERO_STRUCT(msg); + + msg.dn = reg_path_to_ldb(mem_ctx, parent->path, talloc_asprintf(mem_ctx, "key=%s,", name)); + + ldb_msg_add_string(ctx, &msg, "key", talloc_strdup(mem_ctx, name)); + + ret = ldb_add(ctx, &msg); + if (ret < 0) { + DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parent->hive->backend_data))); + return WERR_FOOBAR; + } + + *newkey = talloc_zero_p(mem_ctx, struct registry_key); + (*newkey)->backend_data = msg.dn; + (*newkey)->name = talloc_strdup(mem_ctx, name); + + return WERR_OK; +} + +static WERROR ldb_del_key (struct registry_key *key) +{ + int ret; + + ret = ldb_delete(key->hive->backend_data, key->backend_data); + + if (ret < 0) { + DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(key->hive->backend_data))); + return WERR_FOOBAR; + } + + return WERR_OK; +} + +static WERROR ldb_close_hive (struct registry_hive *hive) +{ + ldb_close (hive->backend_data); + return WERR_OK; +} + +static struct hive_operations reg_backend_ldb = { + .name = "ldb", + .add_key = ldb_add_key, + .del_key = ldb_del_key, + .open_hive = ldb_open_hive, + .close_hive = ldb_close_hive, + .open_key = ldb_open_key, + .get_value_by_index = ldb_get_value_by_id, + .get_subkey_by_index = ldb_get_subkey_by_id, +}; + +NTSTATUS registry_ldb_init(void) +{ + return registry_register(®_backend_ldb); +} diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c deleted file mode 100644 index 380a8010f2..0000000000 --- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Registry interface - Copyright (C) Jelmer Vernooij 2004. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" -#include "registry.h" -#include "lib/ldb/include/ldb.h" - -static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char *add) -{ - char *ret = talloc_strdup(mem_ctx, ""); - char *mypath = strdup(path); - char *end = mypath, *begin; - - if(add) - ret = talloc_asprintf_append(ret, "%s", add); - - while(end) { - char *keyname; - begin = strrchr(end, '\\'); - - if(begin) keyname = begin + 1; - else keyname = mypath; - - if(strlen(keyname)) - ret = talloc_asprintf_append(ret, "key=%s,", keyname); - - if(begin) { - *begin = '\0'; - end = begin-1; - } else { - end = NULL; - } - } - - SAFE_FREE(mypath); - - ret[strlen(ret)-1] = '\0'; - - if(strlen(ret) == 0) return NULL; - - return ret; -} - - -static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_key **subkey) -{ - struct ldb_context *c = k->hive->backend_data; - int ret; - struct ldb_message **msg; - struct ldb_message_element *el; - - ret = ldb_search(c, (char *)k->backend_data, LDB_SCOPE_ONELEVEL, "(key=*)", NULL,&msg); - - if(ret < 0) { - DEBUG(0, ("Error getting subkeys for '%s': %s\n", (char *)k->backend_data, ldb_errstring(c))); - return WERR_FOOBAR; - } - - if(idx >= ret) return WERR_NO_MORE_ITEMS; - - el = ldb_msg_find_element(msg[idx], "key"); - - *subkey = talloc_p(mem_ctx, struct registry_key); - (*subkey)->name = talloc_strdup(mem_ctx, el->values[0].data); - (*subkey)->backend_data = talloc_strdup(mem_ctx, msg[idx]->dn); - - ldb_search_free(c, msg); - return WERR_OK; -} - -static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_value **value) -{ - struct ldb_context *c = k->hive->backend_data; - int ret; - struct ldb_message **msg; - struct ldb_message_element *el; - - ret = ldb_search(c, (char *)k->backend_data, LDB_SCOPE_ONELEVEL, "(value=*)", NULL,&msg); - - if(ret < 0) { - DEBUG(0, ("Error getting values for '%s': %s\n", (char *)k->backend_data, ldb_errstring(c))); - return WERR_FOOBAR; - } - - if(idx >= ret) return WERR_NO_MORE_ITEMS; - - el = ldb_msg_find_element(msg[idx], "value"); - - *value = talloc_p(mem_ctx, struct registry_value); - (*value)->name = talloc_strdup(mem_ctx, el->values[0].data); - (*value)->backend_data = talloc_strdup(mem_ctx, msg[idx]->dn); - - ldb_search_free(c, msg); - return WERR_OK; -} - -static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **key) -{ - struct ldb_context *c = h->backend_data; - struct ldb_message **msg; - char *ldap_path; - int ret; - ldap_path = reg_path_to_ldb(mem_ctx, name, NULL); - - ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL,&msg); - - if(ret == 0) { - return WERR_NO_MORE_ITEMS; - } else if(ret < 0) { - DEBUG(0, ("Error opening key '%s': %s\n", ldap_path, ldb_errstring(c))); - return WERR_FOOBAR; - } - - *key = talloc_p(mem_ctx, struct registry_key); - (*key)->name = talloc_strdup(mem_ctx, strrchr(name, '\\')); - (*key)->backend_data = talloc_strdup(mem_ctx, msg[0]->dn); - - ldb_search_free(c, msg); - - return WERR_OK; -} - -static WERROR ldb_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *hive, struct registry_key **k) -{ - struct ldb_context *c; - - if (!hive->location) return WERR_INVALID_PARAM; - c = ldb_connect(hive->location, 0, NULL); - - if(!c) { - DEBUG(1, ("ldb_open_hive: %s\n", ldb_errstring(hive->backend_data))); - return WERR_FOOBAR; - } - ldb_set_debug_stderr(c); - hive->backend_data = c; - - hive->root = talloc_zero_p(mem_ctx, struct registry_key); - hive->root->name = talloc_strdup(mem_ctx, ""); - - 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) -{ - struct ldb_context *ctx = parent->hive->backend_data; - struct ldb_message msg; - int ret; - - ZERO_STRUCT(msg); - - msg.dn = reg_path_to_ldb(mem_ctx, parent->path, talloc_asprintf(mem_ctx, "key=%s,", name)); - - ldb_msg_add_string(ctx, &msg, "key", talloc_strdup(mem_ctx, name)); - - ret = ldb_add(ctx, &msg); - if (ret < 0) { - DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parent->hive->backend_data))); - return WERR_FOOBAR; - } - - *newkey = talloc_zero_p(mem_ctx, struct registry_key); - (*newkey)->backend_data = msg.dn; - (*newkey)->name = talloc_strdup(mem_ctx, name); - - return WERR_OK; -} - -static WERROR ldb_del_key (struct registry_key *key) -{ - int ret; - - ret = ldb_delete(key->hive->backend_data, key->backend_data); - - if (ret < 0) { - DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(key->hive->backend_data))); - return WERR_FOOBAR; - } - - return WERR_OK; -} - -static WERROR ldb_close_hive (struct registry_hive *hive) -{ - ldb_close (hive->backend_data); - return WERR_OK; -} - -static struct registry_operations reg_backend_ldb = { - .name = "ldb", - .add_key = ldb_add_key, - .del_key = ldb_del_key, - .open_hive = ldb_open_hive, - .close_hive = ldb_close_hive, - .open_key = ldb_open_key, - .get_value_by_index = ldb_get_value_by_id, - .get_subkey_by_index = ldb_get_subkey_by_id, -}; - -NTSTATUS registry_ldb_init(void) -{ - return registry_register(®_backend_ldb); -} diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c new file mode 100644 index 0000000000..117d8d1b81 --- /dev/null +++ b/source4/lib/registry/reg_backend_nt4.c @@ -0,0 +1,1747 @@ +/* + Samba Unix/Linux SMB client utility libeditreg.c + Copyright (C) 2002 Richard Sharpe, rsharpe@richardsharpe.com + Copyright (C) 2003-2004 Jelmer Vernooij, jelmer@samba.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/************************************************************************* + + A utility to edit a Windows NT/2K etc registry file. + + Many of the ideas in here come from other people and software. + I first looked in Wine in misc/registry.c and was also influenced by + http://www.wednesday.demon.co.uk/dosreg.html + + Which seems to contain comments from someone else. I reproduce them here + incase the site above disappears. It actually comes from + http://home.eunet.no/~pnordahl/ntpasswd/WinReg.txt. + + The goal here is to read the registry into memory, manipulate it, and then + write it out if it was changed by any actions of the user. + +The windows NT registry has 2 different blocks, where one can occur many +times... + +the "regf"-Block +================ + +"regf" is obviously the abbreviation for "Registry file". "regf" is the +signature of the header-block which is always 4kb in size, although only +the first 64 bytes seem to be used and a checksum is calculated over +the first 0x200 bytes only! + +Offset Size Contents +0x00000000 D-Word ID: ASCII-"regf" = 0x66676572 +0x00000004 D-Word ???? //see struct REG_HANDLE +0x00000008 D-Word ???? Always the same value as at 0x00000004 +0x0000000C Q-Word last modify date in WinNT date-format +0x00000014 D-Word 1 +0x00000018 D-Word 3 +0x0000001C D-Word 0 +0x00000020 D-Word 1 +0x00000024 D-Word Offset of 1st key record +0x00000028 D-Word Size of the data-blocks (Filesize-4kb) +0x0000002C D-Word 1 +0x000001FC D-Word Sum of all D-Words from 0x00000000 to +0x000001FB //XOR of all words. Nigel + +I have analyzed more registry files (from multiple machines running +NT 4.0 german version) and could not find an explanation for the values +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 +of 4kb in size. + +Inside these hbin-blocks the different records are placed. The memory- +management looks like a C-compiler heap management to me... + +hbin-Header +=========== +Offset Size Contents +0x0000 D-Word ID: ASCII-"hbin" = 0x6E696268 +0x0004 D-Word Offset from the 1st hbin-Block +0x0008 D-Word Offset to the next hbin-Block +0x001C D-Word Block-size + +The values in 0x0008 and 0x001C should be the same, so I don't know +if they are correct or swapped... + +From offset 0x0020 inside a hbin-block data is stored with the following +format: + +Offset Size Contents +0x0000 D-Word Data-block size //this size must be a +multiple of 8. Nigel +0x0004 ???? Data + +If the size field is negative (bit 31 set), the corresponding block +is free and has a size of -blocksize! + +That does not seem to be true. All block lengths seem to be negative! +(Richard Sharpe) + +The data is stored as one record per block. Block size is a multiple +of 4 and the last block reaches the next hbin-block, leaving no room. + +(That also seems incorrect, in that the block size if a multiple of 8. +That is, the block, including the 4 byte header, is always a multiple of +8 bytes. Richard Sharpe.) + +Records in the hbin-blocks +========================== + +nk-Record + + The nk-record can be treated as a combination of tree-record and + key-record of the win 95 registry. + +lf-Record + + The lf-record is the counterpart to the RGKN-record (the + hash-function) + +vk-Record + + The vk-record consists information to a single value (value key). + +sk-Record + + sk (? Security Key ?) is the ACL of the registry. + +Value-Lists + + The value-lists contain information about which values are inside a + sub-key and don't have a header. + +Datas + + The datas of the registry are (like the value-list) stored without a + header. + +All offset-values are relative to the first hbin-block and point to the +block-size field of the record-entry. to get the file offset, you have to add +the header size (4kb) and the size field (4 bytes)... + +the nk-Record +============= +Offset Size Contents +0x0000 Word ID: ASCII-"nk" = 0x6B6E +0x0002 Word for the root-key: 0x2C, otherwise 0x20 //key symbolic links 0x10. Nigel +0x0004 Q-Word write-date/time in windows nt notation +0x0010 D-Word Offset of Owner/Parent key +0x0014 D-Word number of sub-Keys +0x001C D-Word Offset of the sub-key lf-Records +0x0024 D-Word number of values +0x0028 D-Word Offset of the Value-List +0x002C D-Word Offset of the sk-Record + +0x0030 D-Word Offset of the Class-Name //see NK structure for the use of these fields. Nigel +0x0044 D-Word Unused (data-trash) //some kind of run time index. Does not appear to be important. Nigel +0x0048 Word name-length +0x004A Word class-name length +0x004C ???? key-name + +the Value-List +============== +Offset Size Contents +0x0000 D-Word Offset 1st Value +0x0004 D-Word Offset 2nd Value +0x???? D-Word Offset nth Value + +To determine the number of values, you have to look at the owner-nk-record! + +The vk-Record +============= +Offset Size Contents +0x0000 Word ID: ASCII-"vk" = 0x6B76 +0x0002 Word name length +0x0004 D-Word length of the data //if top bit is set when offset contains data. Nigel +0x0008 D-Word Offset of Data +0x000C D-Word Type of value +0x0010 Word Flag +0x0012 Word Unused (data-trash) +0x0014 ???? Name + +If bit 0 of the flag-word is set, a name is present, otherwise the value has no name (=default) + +If the data-size is lower 5, the data-offset value is used to store the data itself! + +The data-types +============== +Wert Beteutung +0x0001 RegSZ: character string (in UNICODE!) +0x0002 ExpandSZ: string with "%var%" expanding (UNICODE!) +0x0003 RegBin: raw-binary value +0x0004 RegDWord: Dword +0x0007 RegMultiSZ: multiple strings, seperated with 0 + (UNICODE!) + +The "lf"-record +=============== +Offset Size Contents +0x0000 Word ID: ASCII-"lf" = 0x666C +0x0002 Word number of keys +0x0004 ???? Hash-Records + +Hash-Record +=========== +Offset Size Contents +0x0000 D-Word Offset of corresponding "nk"-Record +0x0004 D-Word ASCII: the first 4 characters of the key-name, padded with 0's. Case sensitiv! + +Keep in mind, that the value at 0x0004 is used for checking the data-consistency! If you change the +key-name you have to change the hash-value too! + +//These hashrecords must be sorted low to high within the lf record. Nigel. + +The "sk"-block +============== +(due to the complexity of the SAM-info, not clear jet) +(This is just a self-relative security descriptor in the data. R Sharpe.) + + +Offset Size Contents +0x0000 Word ID: ASCII-"sk" = 0x6B73 +0x0002 Word Unused +0x0004 D-Word Offset of previous "sk"-Record +0x0008 D-Word Offset of next "sk"-Record +0x000C D-Word usage-counter +0x0010 D-Word Size of "sk"-record in bytes +???? //standard self +relative security desciptor. Nigel +???? ???? Security and auditing settings... +???? + +The usage counter counts the number of references to this +"sk"-record. You can use one "sk"-record for the entire registry! + +Windows nt date/time format +=========================== +The time-format is a 64-bit integer which is incremented every +0,0000001 seconds by 1 (I don't know how accurate it realy is!) +It starts with 0 at the 1st of january 1601 0:00! All values are +stored in GMT time! The time-zone is important to get the real +time! + +Common values for win95 and win-nt +================================== +Offset values marking an "end of list", are either 0 or -1 (0xFFFFFFFF). +If a value has no name (length=0, flag(bit 0)=0), it is treated as the +"Default" entry... +If a value has no data (length=0), it is displayed as empty. + +simplyfied win-3.?? registry: +============================= + ++-----------+ +| next rec. |---+ +----->+------------+ +| first sub | | | | Usage cnt. | +| name | | +-->+------------+ | | length | +| value | | | | next rec. | | | text |------->+-------+ ++-----------+ | | | name rec. |--+ +------------+ | xxxxx | + +------------+ | | value rec. |-------->+------------+ +-------+ + v | +------------+ | Usage cnt. | ++-----------+ | | length | +| next rec. | | | text |------->+-------+ +| first sub |------+ +------------+ | xxxxx | +| name | +-------+ +| value | ++-----------+ + +Greatly simplyfied structure of the nt-registry: +================================================ + ++---------------------------------------------------------------+ +| | +v | ++---------+ +---------->+-----------+ +----->+---------+ | +| "nk" | | | lf-rec. | | | nk-rec. | | +| ID | | | # of keys | | | parent |---+ +| Date | | | 1st key |--+ | .... | +| parent | | +-----------+ +---------+ +| suk-keys|-----+ +| values |--------------------->+----------+ +| SK-rec. |---------------+ | 1. value |--> +----------+ +| class |--+ | +----------+ | vk-rec. | ++---------+ | | | .... | + v | | data |--> +-------+ + +------------+ | +----------+ | xxxxx | + | Class name | | +-------+ + +------------+ | + v + +---------+ +---------+ + +----->| next sk |--->| Next sk |--+ + | +---| prev sk |<---| prev sk | | + | | | .... | | ... | | + | | +---------+ +---------+ | + | | ^ | + | | | | + | +--------------------+ | + +----------------------------------+ + +--------------------------------------------------------------------------- + +Hope this helps.... (Although it was "fun" for me to uncover this things, + it took me several sleepless nights ;) + + B.D. + +*************************************************************************/ + +#include "includes.h" +#include "registry.h" +#include "system/shmem.h" + +#define REG_KEY_LIST_SIZE 10 +#define FLAG_HAS_NAME 0x01 +/*FIXME*/ + +/* + * Structures for dealing with the on-disk format of the registry + */ + +const char *def_owner_sid_str = NULL; + +/* + * These definitions are for the in-memory registry structure. + * It is a tree structure that mimics what you see with tools like regedit + */ + + +/* + * Definition of a Key. It has a name, classname, date/time last modified, + * sub-keys, values, and a security descriptor + */ + +#define REG_ROOT_KEY 1 +#define REG_SUB_KEY 2 +#define REG_SYM_LINK 3 + +/* + * All of the structures below actually have a four-byte length before them + * which always seems to be negative. The following macro retrieves that + * size as an integer + */ + +#define BLK_SIZE(b) ((int)*(int *)(((int *)b)-1)) + +typedef uint_t DWORD; +typedef unsigned short WORD; + +typedef struct sk_struct SK_HDR; +/* + * This structure keeps track of the output format of the registry + */ +#define REG_OUTBLK_HDR 1 +#define REG_OUTBLK_HBIN 2 + +typedef struct regf_block { + DWORD REGF_ID; /* regf */ + DWORD uk1; + DWORD uk2; + DWORD tim1, tim2; + DWORD uk3; /* 1 */ + DWORD uk4; /* 3 */ + DWORD uk5; /* 0 */ + DWORD uk6; /* 1 */ + DWORD first_key; /* offset */ + uint_t dblk_size; + DWORD uk7[116]; /* 1 */ + DWORD chksum; +} REGF_HDR; + +typedef struct hbin_sub_struct { + DWORD dblocksize; + char data[1]; +} HBIN_SUB_HDR; + +typedef struct hbin_struct { + DWORD HBIN_ID; /* hbin */ + DWORD off_from_first; + DWORD off_to_next; + DWORD uk1; + DWORD uk2; + DWORD uk3; + DWORD uk4; + DWORD blk_size; + HBIN_SUB_HDR hbin_sub_hdr; +} HBIN_HDR; + +typedef struct nk_struct { + WORD NK_ID; + WORD type; + DWORD t1, t2; + DWORD uk1; + DWORD own_off; + DWORD subk_num; + DWORD uk2; + DWORD lf_off; + DWORD uk3; + DWORD val_cnt; + DWORD val_off; + DWORD sk_off; + DWORD clsnam_off; + DWORD unk4[4]; + DWORD unk5; + WORD nam_len; + WORD clsnam_len; + char key_nam[1]; /* Actual length determined by nam_len */ +} NK_HDR; + +struct sk_struct { + WORD SK_ID; + WORD uk1; + DWORD prev_off; + DWORD next_off; + DWORD ref_cnt; + DWORD rec_size; + char sec_desc[1]; +}; + +typedef struct key_sec_desc_s { + struct key_sec_desc_s *prev, *next; + int ref_cnt; + int state; + int offset; + SK_HDR *sk_hdr; /* This means we must keep the registry in memory */ + SEC_DESC *sec_desc; +} KEY_SEC_DESC; + +/* A map of sk offsets in the regf to KEY_SEC_DESCs for quick lookup etc */ +typedef struct sk_map_s { + int sk_off; + KEY_SEC_DESC *key_sec_desc; +} SK_MAP; + +typedef struct vk_struct { + WORD VK_ID; + WORD nam_len; + DWORD dat_len; /* If top-bit set, offset contains the data */ + DWORD dat_off; + DWORD dat_type; + WORD flag; /* =1, has name, else no name (=Default). */ + WORD unk1; + char dat_name[1]; /* Name starts here ... */ +} VK_HDR; + +typedef DWORD VL_TYPE[1]; /* Value list is an array of vk rec offsets */ + +typedef struct hash_struct { + DWORD nk_off; + char hash[4]; +} HASH_REC; + + +typedef struct lf_struct { + WORD LF_ID; + WORD key_count; + struct hash_struct hr[1]; /* Array of hash records, depending on key_count */} LF_HDR; + + + +/* + * This structure keeps track of the output format of the registry + */ +#define REG_OUTBLK_HDR 1 +#define REG_OUTBLK_HBIN 2 + +typedef struct hbin_blk_s { + int type, size; + struct hbin_blk_s *next; + char *data; /* The data block */ + uint_t file_offset; /* Offset in file */ + uint_t free_space; /* Amount of free space in block */ + uint_t fsp_off; /* Start of free space in block */ + int complete, stored; +} HBIN_BLK; + +typedef struct regf_struct_s { + int reg_type; + int fd; + struct stat sbuf; + char *base; + BOOL modified; + NTTIME last_mod_time; + NK_HDR *first_key; + int sk_count, sk_map_size; + SK_MAP *sk_map; + const char *owner_sid_str; + SEC_DESC *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 + */ + HBIN_BLK *blk_head, *blk_tail, *free_space; +} REGF; + +static DWORD str_to_dword(const char *a) { + int i; + unsigned long ret = 0; + for(i = strlen(a)-1; i >= 0; i--) { + ret = ret * 0x100 + a[i]; + } + return ret; +} + +#if 0 + +/* + * Create an ACE + */ +static BOOL nt_create_ace(SEC_ACE *ace, int type, int flags, uint32_t perms, const char *sid) +{ + DOM_SID s; + SEC_ACCESS access; + access.mask = perms; + if(!string_to_sid(&s, sid))return False; + init_sec_ace(ace, &s, type, access, flags); + return True; +} + +/* + * Create a default ACL + */ +static SEC_ACL *nt_create_default_acl(struct registry_hive *regf) +{ + SEC_ACE aces[8]; + + if(!nt_create_ace(&aces[0], 0x00, 0x0, 0xF003F, regf->owner_sid_str)) return NULL; + if(!nt_create_ace(&aces[1], 0x00, 0x0, 0xF003F, "S-1-5-18")) return NULL; + if(!nt_create_ace(&aces[2], 0x00, 0x0, 0xF003F, "S-1-5-32-544")) return NULL; + if(!nt_create_ace(&aces[3], 0x00, 0x0, 0x20019, "S-1-5-12")) return NULL; + if(!nt_create_ace(&aces[4], 0x00, 0x0B, GENERIC_RIGHT_ALL_ACCESS, regf->owner_sid_str)) return NULL; + if(!nt_create_ace(&aces[5], 0x00, 0x0B, 0x10000000, "S-1-5-18")) return NULL; + if(!nt_create_ace(&aces[6], 0x00, 0x0B, 0x10000000, "S-1-5-32-544")) return NULL; + if(!nt_create_ace(&aces[7], 0x00, 0x0B, 0x80000000, "S-1-5-12")) return NULL; + + return make_sec_acl(regf->mem_ctx, 2, 8, aces); +} + +/* + * Create a default security descriptor. We pull in things from env + * if need be + */ +static SEC_DESC *nt_create_def_sec_desc(struct registry_hive *regf) +{ + SEC_DESC *tmp; + + tmp = malloc_p(SEC_DESC); + + tmp->revision = 1; + tmp->type = SEC_DESC_SELF_RELATIVE | SEC_DESC_DACL_PRESENT; + if (!string_to_sid(tmp->owner_sid, "S-1-5-32-544")) goto error; + if (!string_to_sid(tmp->grp_sid, "S-1-5-18")) goto error; + tmp->sacl = NULL; + tmp->dacl = nt_create_default_acl(regf); + + return tmp; + + error: + if (tmp) nt_delete_sec_desc(tmp); + return NULL; +} + +/* + * We will implement inheritence that is based on what the parent's SEC_DESC + * says, but the Owner and Group SIDs can be overwridden from the command line + * and additional ACEs can be applied from the command line etc. + */ +static KEY_SEC_DESC *nt_inherit_security(struct registry_key *key) +{ + + if (!key) return NULL; + return key->security; +} + +/* + * Create an initial security descriptor and init other structures, if needed + * We assume that the initial security stuff is empty ... + */ +static KEY_SEC_DESC *nt_create_init_sec(struct registry_hive *h) +{ + REGF *regf = h->backend_data; + KEY_SEC_DESC *tsec = NULL; + + tsec = malloc_p(KEY_SEC_DESC); + + tsec->ref_cnt = 1; + tsec->state = SEC_DESC_NBK; + tsec->offset = 0; + + tsec->sec_desc = regf->def_sec_desc; + + return tsec; +} +#endif + +/* + * Get the starting record for NT Registry file + */ + +/* + * Where we keep all the regf stuff for one registry. + * This is the structure that we use to tie the in memory tree etc + * together. By keeping separate structs, we can operate on different + * registries at the same time. + * Currently, the SK_MAP is an array of mapping structure. + * Since we only need this on input and output, we fill in the structure + * as we go on input. On output, we know how many SK items we have, so + * we can allocate the structure as we need to. + * If you add stuff here that is dynamically allocated, add the + * appropriate free statements below. + */ + +#define REG_HANDLE_REGTYPE_NONE 0 +#define REG_HANDLE_REGTYPE_NT 1 +#define REG_HANDLE_REGTYPE_W9X 2 + +#define TTTONTTIME(r, t1, t2) (r)->last_mod_time = (t1) | (((uint64_t)(t2)) << 32) + +#define REGF_HDR_BLKSIZ 0x1000 + +#define OFF(f) ((f) + REGF_HDR_BLKSIZ + 4) +#define LOCN(base, f) ((base) + OFF(f)) + +/* Get the header of the registry. Return a pointer to the structure + * If the mmap'd area has not been allocated, then mmap the input file + */ +static REGF_HDR *nt_get_regf_hdr(struct registry_hive *h) +{ + REGF *regf = h->backend_data; + SMB_REG_ASSERT(regf); + + if (!regf->base) { /* Try to mmap etc the file */ + + if ((regf->fd = open(h->location, O_RDONLY, 0000)) <0) { + return NULL; /* What about errors? */ + } + + if (fstat(regf->fd, ®f->sbuf) < 0) { + return NULL; + } + + regf->base = mmap(0, regf->sbuf.st_size, PROT_READ, MAP_SHARED, regf->fd, 0); + + if ((int)regf->base == 1) { + DEBUG(0,("Could not mmap file: %s, %s\n", h->location, + strerror(errno))); + return NULL; + } + } + + /* + * At this point, regf->base != NULL, and we should be able to read the + * header + */ + + SMB_REG_ASSERT(regf->base != NULL); + + return (REGF_HDR *)regf->base; +} + +/* + * Validate a regf header + * For now, do nothing, but we should check the checksum + */ +static int valid_regf_hdr(REGF_HDR *regf_hdr) +{ + if (!regf_hdr) return 0; + + return 1; +} + +#if 0 + +/* + * Process an SK header ... + * Every time we see a new one, add it to the map. Otherwise, just look it up. + * We will do a simple linear search for the moment, since many KEYs have the + * same security descriptor. + * We allocate the map in increments of 10 entries. + */ + +/* + * Create a new entry in the map, and increase the size of the map if needed + */ +static SK_MAP *alloc_sk_map_entry(struct registry_hive *h, KEY_SEC_DESC *tmp, int sk_off) +{ + REGF *regf = h->backend_data; + if (!regf->sk_map) { /* Allocate a block of 10 */ + regf->sk_map = malloc_array_p(SK_MAP, 10); + regf->sk_map_size = 10; + regf->sk_count = 1; + (regf->sk_map)[0].sk_off = sk_off; + (regf->sk_map)[0].key_sec_desc = tmp; + } + else { /* Simply allocate a new slot, unless we have to expand the list */ + int ndx = regf->sk_count; + if (regf->sk_count >= regf->sk_map_size) { + regf->sk_map = (SK_MAP *)realloc(regf->sk_map, + (regf->sk_map_size + 10)*sizeof(SK_MAP)); + if (!regf->sk_map) { + free(tmp); + return NULL; + } + /* + * ndx already points at the first entry of the new block + */ + regf->sk_map_size += 10; + } + (regf->sk_map)[ndx].sk_off = sk_off; + (regf->sk_map)[ndx].key_sec_desc = tmp; + regf->sk_count++; + } + return regf->sk_map; +} + +/* + * Search for a KEY_SEC_DESC in the sk_map, but don't create one if not + * found + */ +KEY_SEC_DESC *lookup_sec_key(SK_MAP *sk_map, int count, int sk_off) +{ + int i; + + if (!sk_map) return NULL; + + for (i = 0; i < count; i++) { + + if (sk_map[i].sk_off == sk_off) + return sk_map[i].key_sec_desc; + + } + + return NULL; + +} + +/* + * Allocate a KEY_SEC_DESC if we can't find one in the map + */ +static KEY_SEC_DESC *lookup_create_sec_key(struct registry_hive *h, SK_MAP *sk_map, int sk_off) +{ + REGF *regf = h->backend_data; + KEY_SEC_DESC *tmp = lookup_sec_key(regf->sk_map, regf->sk_count, sk_off); + + if (tmp) { + return tmp; + } + else { /* Allocate a new one */ + tmp = malloc_p(KEY_SEC_DESC); + memset(tmp, 0, sizeof(KEY_SEC_DESC)); /* Neatly sets offset to 0 */ + tmp->state = SEC_DESC_RES; + if (!alloc_sk_map_entry(h, tmp, sk_off)) { + return NULL; + } + return tmp; + } +} + +static SEC_DESC *process_sec_desc(struct registry_hive *regf, SEC_DESC *sec_desc) +{ + SEC_DESC *tmp = NULL; + + tmp = malloc_p(SEC_DESC); + + tmp->revision = SVAL(&sec_desc->revision,0); + tmp->type = SVAL(&sec_desc->type,0); + DEBUG(2, ("SEC_DESC Rev: %0X, Type: %0X\n", tmp->revision, tmp->type)); + DEBUGADD(2, ("SEC_DESC Owner Off: %0X\n", IVAL(&sec_desc->off_owner_sid,0))); + DEBUGADD(2, ("SEC_DESC Group Off: %0X\n", IVAL(&sec_desc->off_grp_sid,0))); + DEBUGADD(2, ("SEC_DESC DACL Off: %0X\n", IVAL(&sec_desc->off_dacl,0))); + tmp->owner_sid = sid_dup_talloc(regf->mem_ctx, (DOM_SID *)((char *)sec_desc + IVAL(&sec_desc->off_owner_sid,0))); + if (!tmp->owner_sid) { + free(tmp); + return NULL; + } + tmp->grp_sid = sid_dup_talloc(regf->mem_ctx, (DOM_SID *)((char *)sec_desc + IVAL(&sec_desc->off_grp_sid,0))); + if (!tmp->grp_sid) { + free(tmp); + return NULL; + } + + /* Now pick up the SACL and DACL */ + + DEBUG(0, ("%d, %d\n", IVAL(&sec_desc->off_sacl,0), IVAL(&sec_desc->off_dacl,0))); + + if (sec_desc->off_sacl) + tmp->sacl = dup_sec_acl(regf->mem_ctx, (SEC_ACL *)((char *)sec_desc + IVAL(&sec_desc->off_sacl,0))); + else + tmp->sacl = NULL; + + if (sec_desc->off_dacl) + tmp->dacl = dup_sec_acl(regf->mem_ctx, (SEC_ACL *)((char *)sec_desc + IVAL(&sec_desc->off_dacl,0))); + else + tmp->dacl = NULL; + + return tmp; +} + +static KEY_SEC_DESC *process_sk(struct registry_hive *regf, SK_HDR *sk_hdr, int sk_off, int size) +{ + KEY_SEC_DESC *tmp = NULL; + int sk_next_off, sk_prev_off, sk_size; + SEC_DESC *sec_desc; + + if (!sk_hdr) return NULL; + + if (SVAL(&sk_hdr->SK_ID,0) != str_to_dword("sk")) { + DEBUG(0, ("Unrecognized SK Header ID: %08X, %s\n", (int)sk_hdr, + regf->regfile_name)); + return NULL; + } + + if (-size < (sk_size = IVAL(&sk_hdr->rec_size,0))) { + DEBUG(0, ("Incorrect SK record size: %d vs %d. %s\n", + -size, sk_size, regf->regfile_name)); + return NULL; + } + + /* + * Now, we need to look up the SK Record in the map, and return it + * Since the map contains the SK_OFF mapped to KEY_SEC_DESC, we can + * use that + */ + + if (regf->sk_map && + ((tmp = lookup_sec_key(regf->sk_map, regf->sk_count, sk_off)) != NULL) + && (tmp->state == SEC_DESC_OCU)) { + tmp->ref_cnt++; + return tmp; + } + + /* Here, we have an item in the map that has been reserved, or tmp==NULL. */ + + SMB_REG_ASSERT(tmp == NULL || (tmp && tmp->state != SEC_DESC_NON)); + + /* + * Now, allocate a KEY_SEC_DESC, and parse the structure here, and add the + * new KEY_SEC_DESC to the mapping structure, since the offset supplied is + * the actual offset of structure. The same offset will be used by + * all future references to this structure + * We could put all this unpleasantness in a function. + */ + + if (!tmp) { + tmp = malloc_p(KEY_SEC_DESC); + memset(tmp, 0, sizeof(KEY_SEC_DESC)); + + /* + * Allocate an entry in the SK_MAP ... + * We don't need to free tmp, because that is done for us if the + * sm_map entry can't be expanded when we need more space in the map. + */ + + if (!alloc_sk_map_entry(regf, tmp, sk_off)) { + return NULL; + } + } + + tmp->ref_cnt++; + tmp->state = SEC_DESC_OCU; + + /* + * Now, process the actual sec desc and plug the values in + */ + + sec_desc = (SEC_DESC *)&sk_hdr->sec_desc[0]; + tmp->sec_desc = process_sec_desc(regf, sec_desc); + + /* + * Now forward and back links. Here we allocate an entry in the sk_map + * if it does not exist, and mark it reserved + */ + + sk_prev_off = IVAL(&sk_hdr->prev_off,0); + tmp->prev = lookup_create_sec_key(regf, regf->sk_map, sk_prev_off); + SMB_REG_ASSERT(tmp->prev != NULL); + sk_next_off = IVAL(&sk_hdr->next_off,0); + tmp->next = lookup_create_sec_key(regf, regf->sk_map, sk_next_off); + SMB_REG_ASSERT(tmp->next != NULL); + + return tmp; +} +#endif + +/* + * Process a VK header and return a value + */ +static WERROR vk_to_val(TALLOC_CTX *mem_ctx, struct registry_key *parent, VK_HDR *vk_hdr, int size, struct registry_value **value) +{ + REGF *regf = parent->hive->backend_data; + int nam_len, dat_len, flag, dat_type, dat_off, vk_id; + struct registry_value *tmp = NULL; + + if (!vk_hdr) return WERR_INVALID_PARAM; + + if ((vk_id = SVAL(&vk_hdr->VK_ID,0)) != str_to_dword("vk")) { + DEBUG(0, ("Unrecognized VK header ID: %0X, block: %0X, %s\n", + vk_id, (int)vk_hdr, parent->hive->location)); + return WERR_GENERAL_FAILURE; + } + + nam_len = SVAL(&vk_hdr->nam_len,0); + flag = SVAL(&vk_hdr->flag,0); + dat_type = IVAL(&vk_hdr->dat_type,0); + dat_len = IVAL(&vk_hdr->dat_len,0); /* If top bit, offset contains data */ + dat_off = IVAL(&vk_hdr->dat_off,0); + + tmp = talloc_p(mem_ctx, struct registry_value); + tmp->data_type = dat_type; + + if (flag & FLAG_HAS_NAME) { + tmp->name = talloc_strndup(mem_ctx, vk_hdr->dat_name, nam_len); + } else { + tmp->name = NULL; + } + + /* + * Allocate space and copy the data as a BLOB + */ + + if (dat_len&0x7FFFFFFF) { + + char *dtmp = (char *)talloc(mem_ctx, dat_len&0x7FFFFFFF); + + if ((dat_len&0x80000000) == 0) { /* The data is pointed to by the offset */ + char *dat_ptr = LOCN(regf->base, dat_off); + memcpy(dtmp, dat_ptr, dat_len); + } + else { /* The data is in the offset or type */ + /* + * FIXME. + * Some registry files seem to have weird fields. If top bit is set, + * but len is 0, the type seems to be the value ... + * Not sure how to handle this last type for the moment ... + */ + dat_len = dat_len & 0x7FFFFFFF; + memcpy(dtmp, &dat_off, dat_len); + } + + + if(tmp->data_type == REG_SZ) { + char *ret; + dat_len = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, dtmp, dat_len, (void **)&ret); + dtmp = ret; + } + + + tmp->data_blk = dtmp; + tmp->data_len = dat_len; + } + + *value = tmp; + return WERR_OK; +} + +#if 0 /* unused */ + +static BOOL vl_verify(VL_TYPE vl, int count, int size) +{ + if(!vl) return False; + if (-size < (count+1)*sizeof(int)){ + DEBUG(0, ("Error in VL header format. Size less than space required. %d\n", -size)); + return False; + } + return True; +} + +#endif + +static WERROR lf_verify(struct registry_hive *h, LF_HDR *lf_hdr, int size) +{ + int lf_id; + if ((lf_id = SVAL(&lf_hdr->LF_ID,0)) != str_to_dword("lf")) { + DEBUG(0, ("Unrecognized LF Header format: %0X, Block: %0X, %s.\n", + lf_id, (int)lf_hdr, h->location)); + return WERR_INVALID_PARAM; + } + return WERR_OK; +} + +static WERROR lf_num_entries(struct registry_hive *h, LF_HDR *lf_hdr, int size, int *count) +{ + WERROR error; + + error = lf_verify(h, lf_hdr, size); + if(!W_ERROR_IS_OK(error)) return error; + + SMB_REG_ASSERT(size < 0); + + *count = SVAL(&lf_hdr->key_count,0); + DEBUG(2, ("Key Count: %u\n", *count)); + if (*count <= 0) return WERR_INVALID_PARAM; + + return WERR_OK; +} + + +static WERROR nk_to_key(TALLOC_CTX *, struct registry_hive *regf, NK_HDR *nk_hdr, int size, struct registry_key *parent, struct registry_key **); + + + +/* + * Process an LF Header and return a list of sub-keys + */ +static WERROR lf_get_entry(TALLOC_CTX *mem_ctx, struct registry_key *parent, LF_HDR *lf_hdr, int size, int n, struct registry_key **key) +{ + REGF *regf = parent->hive->backend_data; + int count, nk_off; + NK_HDR *nk_hdr; + WERROR error; + + if (!lf_hdr) return WERR_INVALID_PARAM; + + error = lf_verify(parent->hive, lf_hdr, size); + if(!W_ERROR_IS_OK(error)) return error; + + SMB_REG_ASSERT(size < 0); + + count = SVAL(&lf_hdr->key_count,0); + DEBUG(2, ("Key Count: %u\n", count)); + if (count <= 0) return WERR_GENERAL_FAILURE; + if (n >= count) return WERR_NO_MORE_ITEMS; + + nk_off = IVAL(&lf_hdr->hr[n].nk_off,0); + DEBUG(2, ("NK Offset: %0X\n", nk_off)); + nk_hdr = (NK_HDR *)LOCN(regf->base, nk_off); + return nk_to_key(mem_ctx, parent->hive, nk_hdr, BLK_SIZE(nk_hdr), parent, key); +} + +static WERROR nk_to_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, NK_HDR *nk_hdr, int size, struct registry_key *parent, struct registry_key **key) +{ + REGF *regf = h->backend_data; + struct registry_key *tmp = NULL, *own; + int namlen, clsname_len, sk_off, own_off; + uint_t nk_id; + SK_HDR *sk_hdr; + int type; + char key_name[1024]; + + if (!nk_hdr) return WERR_INVALID_PARAM; + + if ((nk_id = SVAL(&nk_hdr->NK_ID,0)) != str_to_dword("nk")) { + DEBUG(0, ("Unrecognized NK Header format: %08X, Block: %0X. %s\n", + nk_id, (int)nk_hdr, parent->hive->location)); + return WERR_INVALID_PARAM; + } + + SMB_REG_ASSERT(size < 0); + + namlen = SVAL(&nk_hdr->nam_len,0); + clsname_len = SVAL(&nk_hdr->clsnam_len,0); + + /* + * The value of -size should be ge + * (sizeof(NK_HDR) - 1 + namlen) + * The -1 accounts for the fact that we included the first byte of + * the name in the structure. clsname_len is the length of the thing + * pointed to by clsnam_off + */ + + if (-size < (sizeof(NK_HDR) - 1 + namlen)) { + DEBUG(0, ("Incorrect NK_HDR size: %d, %0X\n", -size, (int)nk_hdr)); + DEBUG(0, ("Sizeof NK_HDR: %d, name_len %d, clsname_len %d\n", + sizeof(NK_HDR), namlen, clsname_len)); + return WERR_GENERAL_FAILURE; + } + + DEBUG(2, ("NK HDR: Name len: %d, class name len: %d\n", namlen, clsname_len)); + + /* Fish out the key name and process the LF list */ + + SMB_REG_ASSERT(namlen < sizeof(key_name)); + + strncpy(key_name, nk_hdr->key_nam, namlen); + key_name[namlen] = '\0'; + + type = (SVAL(&nk_hdr->type,0)==0x2C?REG_ROOT_KEY:REG_SUB_KEY); + if(type == REG_ROOT_KEY && parent) { + DEBUG(0,("Root key encountered below root level!\n")); + return WERR_GENERAL_FAILURE; + } + + tmp = talloc_p(mem_ctx, struct registry_key); + tmp->name = talloc_strdup(mem_ctx, key_name); + tmp->backend_data = nk_hdr; + + DEBUG(2, ("Key name: %s\n", key_name)); + + /* + * Fish out the class name, it is in UNICODE, while the key name is + * ASCII :-) + */ + + if (clsname_len) { /* Just print in Ascii for now */ + void *clsnamep; + int clsnam_off; + + clsnam_off = IVAL(&nk_hdr->clsnam_off,0); + clsnamep = LOCN(regf->base, clsnam_off); + DEBUG(2, ("Class Name Offset: %0X\n", clsnam_off)); + + pull_ucs2_talloc(mem_ctx, &tmp->class_name, clsnamep); + + DEBUGADD(2,(" Class Name: %s\n", tmp->class_name)); + + } + + /* + * Process the owner offset ... + */ + + own_off = IVAL(&nk_hdr->own_off,0); + own = (struct registry_key *)LOCN(regf->base, own_off); + DEBUG(2, ("Owner Offset: %0X\n", own_off)); + + DEBUGADD(2, (" Owner locn: %0X, Our locn: %0X\n", + (uint_t)own, (uint_t)nk_hdr)); + + /* + * We should verify that the owner field is correct ... + * for now, we don't worry ... + */ + + /* + * Also handle the SK header ... + */ + + sk_off = IVAL(&nk_hdr->sk_off,0); + sk_hdr = (SK_HDR *)LOCN(regf->base, sk_off); + DEBUG(2, ("SK Offset: %0X\n", sk_off)); + + if (sk_off != -1) { + +#if 0 + tmp->security = process_sk(regf, sk_hdr, sk_off, BLK_SIZE(sk_hdr)); +#endif + + } + + *key = tmp; + return WERR_OK; +} + +#if 0 /* unused */ + +/* + * Allocate a new hbin block, set up the header for the block etc + */ +static HBIN_BLK *nt_create_hbin_blk(struct registry_hive *h, int size) +{ + REGF *regf = h->backend_data; + HBIN_BLK *tmp; + HBIN_HDR *hdr; + + if (!regf || !size) return NULL; + + /* Round size up to multiple of REGF_HDR_BLKSIZ */ + + size = (size + (REGF_HDR_BLKSIZ - 1)) & ~(REGF_HDR_BLKSIZ - 1); + + tmp = malloc_p(HBIN_BLK); + memset(tmp, 0, sizeof(HBIN_BLK)); + + tmp->data = malloc(size); + + memset(tmp->data, 0, size); /* Make it pristine */ + + tmp->size = size; + /*FIXMEtmp->file_offset = regf->blk_tail->file_offset + regf->blk_tail->size;*/ + + tmp->free_space = size - (sizeof(HBIN_HDR) - sizeof(HBIN_SUB_HDR)); + tmp->fsp_off = size - tmp->free_space; + + /* + * Now, build the header in the data block + */ + hdr = (HBIN_HDR *)tmp->data; + hdr->HBIN_ID = str_to_dword("hbin"); + hdr->off_from_first = tmp->file_offset - REGF_HDR_BLKSIZ; + hdr->off_to_next = tmp->size; + hdr->blk_size = tmp->size; + + /* + * Now link it in + */ + + regf->blk_tail->next = tmp; + regf->blk_tail = tmp; + if (!regf->free_space) regf->free_space = tmp; + + return tmp; +} + +/* + * Allocate a unit of space ... and return a pointer as function param + * and the block's offset as a side effect + */ +static void *nt_alloc_regf_space(struct registry_hive *h, int size, uint_t *off) +{ + REGF *regf = h->backend_data; + int tmp = 0; + void *ret = NULL; + HBIN_BLK *blk; + + if (!regf || !size || !off) return NULL; + + SMB_REG_ASSERT(regf->blk_head != NULL); + + /* + * round up size to include header and then to 8-byte boundary + */ + size = (size + 4 + 7) & ~7; + + /* + * Check if there is space, if none, grab a block + */ + if (!regf->free_space) { + if (!nt_create_hbin_blk(h, REGF_HDR_BLKSIZ)) + return NULL; + } + + /* + * Now, chain down the list of blocks looking for free space + */ + + for (blk = regf->free_space; blk != NULL; blk = blk->next) { + if (blk->free_space <= size) { + tmp = blk->file_offset + blk->fsp_off - REGF_HDR_BLKSIZ; + ret = blk->data + blk->fsp_off; + blk->free_space -= size; + blk->fsp_off += size; + + /* Insert the header */ + ((HBIN_SUB_HDR *)ret)->dblocksize = -size; + + /* + * Fix up the free space ptr + * If it is NULL, we fix it up next time + */ + + if (!blk->free_space) + regf->free_space = blk->next; + + *off = tmp; + return (((char *)ret)+4);/* The pointer needs to be to the data struct */ + } + } + + /* + * If we got here, we need to add another block, which might be + * larger than one block -- deal with that later + */ + if (nt_create_hbin_blk(h, REGF_HDR_BLKSIZ)) { + blk = regf->free_space; + tmp = blk->file_offset + blk->fsp_off - REGF_HDR_BLKSIZ; + ret = blk->data + blk->fsp_off; + blk->free_space -= size; + blk->fsp_off += size; + + /* Insert the header */ + ((HBIN_SUB_HDR *)ret)->dblocksize = -size; + + /* + * Fix up the free space ptr + * If it is NULL, we fix it up next time + */ + + if (!blk->free_space) + regf->free_space = blk->next; + + *off = tmp; + return (((char *)ret) + 4);/* The pointer needs to be to the data struct */ + } + + return NULL; +} + +/* + * Store a SID at the location provided + */ +static int nt_store_SID(struct registry_hive *regf, DOM_SID *sid, uint8_t *locn) +{ + int i; + uint8_t *p = locn; + + if (!regf || !sid || !locn) return 0; + + *p = sid->sid_rev_num; p++; + *p = sid->num_auths; p++; + + for (i=0; i < 6; i++) { + *p = sid->id_auth[i]; p++; + } + + for (i=0; i < sid->num_auths; i++) { + SIVAL(p, 0, sid->sub_auths[i]); p+=4; + } + + return p - locn; + +} + +static int nt_store_ace(struct registry_hive *regf, SEC_ACE *ace, uint8_t *locn) +{ + int size = 0; + SEC_ACE *reg_ace = (SEC_ACE *)locn; + uint8_t *p; + + if (!regf || !ace || !locn) return 0; + + reg_ace->type = ace->type; + reg_ace->flags = ace->flags; + + /* Deal with the length when we have stored the SID */ + + p = (uint8_t *)®_ace->info.mask; + + SIVAL(p, 0, ace->info.mask); p += 4; + + size = nt_store_SID(regf, &ace->trustee, p); + + size += 8; /* Size of the fixed header */ + + p = (uint8_t *)®_ace->size; + + SSVAL(p, 0, size); + + return size; +} + +/* + * Store an ACL at the location provided + */ +static int nt_store_acl(struct registry_hive *regf, SEC_ACL *acl, uint8_t *locn) { + int size = 0, i; + uint8_t *p = locn, *s; + + if (!regf || !acl || !locn) return 0; + + /* + * Now store the header and then the ACEs ... + */ + + SSVAL(p, 0, acl->revision); + + p += 2; s = p; /* Save this for the size field */ + + p += 2; + + SIVAL(p, 0, acl->num_aces); + + p += 4; + + for (i = 0; i < acl->num_aces; i++) { + size = nt_store_ace(regf, &acl->ace[i], p); + p += size; + } + + size = s - locn; + SSVAL(s, 0, size); + return size; +} + +/* + * Flatten and store the Sec Desc + * Windows lays out the DACL first, but since there is no SACL, it might be + * that first, then the owner, then the group SID. So, we do it that way + * too. + */ +static uint_t nt_store_sec_desc(struct registry_hive *regf, SEC_DESC *sd, char *locn) +{ + SEC_DESC *rsd = (SEC_DESC *)locn; + uint_t size = 0, off = 0; + + if (!regf || !sd || !locn) return 0; + + /* + * Now, fill in the first two fields, then lay out the various fields + * as needed + */ + + rsd->revision = SEC_DESC_REVISION; + rsd->type = SEC_DESC_DACL_PRESENT | SEC_DESC_SELF_RELATIVE; + + off = 4 * sizeof(DWORD) + 4; + + if (sd->sacl){ + size = nt_store_acl(regf, sd->sacl, (char *)(locn + off)); + rsd->off_sacl = off; + } + else + rsd->off_sacl = 0; + + off += size; + + if (sd->dacl) { + rsd->off_dacl = off; + size = nt_store_acl(regf, sd->dacl, (char *)(locn + off)); + } + else { + rsd->off_dacl = 0; + } + + off += size; + + /* Now the owner and group SIDs */ + + if (sd->owner_sid) { + rsd->off_owner_sid = off; + size = nt_store_SID(regf, sd->owner_sid, (char *)(locn + off)); + } + else { + rsd->off_owner_sid = 0; + } + + off += size; + + if (sd->grp_sid) { + rsd->off_grp_sid = off; + size = nt_store_SID(regf, sd->grp_sid, (char *)(locn + off)); + } + else { + rsd->off_grp_sid = 0; + } + + off += size; + + return size; +} + +/* + * Store the security information + * + * If it has already been stored, just get its offset from record + * otherwise, store it and record its offset + */ +static uint_t nt_store_security(struct registry_hive *regf, KEY_SEC_DESC *sec) +{ + int size = 0; + uint_t sk_off; + SK_HDR *sk_hdr; + + if (sec->offset) return sec->offset; + + /* + * OK, we don't have this one in the file yet. We must compute the + * size taken by the security descriptor as a self-relative SD, which + * means making one pass over each structure and figuring it out + */ + +/* FIXME size = sec_desc_size(sec->sec_desc); */ + + /* Allocate that much space */ + + sk_hdr = nt_alloc_regf_space(regf, size, &sk_off); + sec->sk_hdr = sk_hdr; + + if (!sk_hdr) return 0; + + /* Now, lay out the sec_desc in the space provided */ + + sk_hdr->SK_ID = str_to_dword("sk"); + + /* + * We can't deal with the next and prev offset in the SK_HDRs until the + * whole tree has been stored, then we can go and deal with them + */ + + sk_hdr->ref_cnt = sec->ref_cnt; + sk_hdr->rec_size = size; /* Is this correct */ + + /* Now, lay out the sec_desc */ + + if (!nt_store_sec_desc(regf, sec->sec_desc, (char *)&sk_hdr->sec_desc)) + return 0; + + return sk_off; + +} + +/* + * Store a KEY in the file ... + * + * We store this depth first, and defer storing the lf struct until + * all the sub-keys have been stored. + * + * We store the NK hdr, any SK header, class name, and VK structure, then + * recurse down the LF structures ... + * + * We return the offset of the NK struct + * FIXME, FIXME, FIXME: Convert to using SIVAL and SSVAL ... + */ +static int nt_store_reg_key(struct registry_hive *regf, struct registry_key *key) +{ + NK_HDR *nk_hdr; + uint_t nk_off, sk_off, size; + + if (!regf || !key) return 0; + + size = sizeof(NK_HDR) + strlen(key->name) - 1; + nk_hdr = nt_alloc_regf_space(regf, size, &nk_off); + if (!nk_hdr) goto error; + + key->offset = nk_off; /* We will need this later */ + + /* + * Now fill in each field etc ... + */ + + nk_hdr->NK_ID = str_to_dword("nk"); + if (key->type == REG_ROOT_KEY) + nk_hdr->type = 0x2C; + else + nk_hdr->type = 0x20; + + /* FIXME: Fill in the time of last update */ + + if (key->type != REG_ROOT_KEY) + nk_hdr->own_off = key->owner->offset; + + if (key->sub_keys) + nk_hdr->subk_num = key->sub_keys->key_count; + + /* + * Now, process the Sec Desc and then store its offset + */ + + sk_off = nt_store_security(regf, key->security); + nk_hdr->sk_off = sk_off; + + /* + * Then, store the val list and store its offset + */ + if (key->values) { + nk_hdr->val_cnt = key->values->val_count; + nk_hdr->val_off = nt_store_val_list(regf, key->values); + } + else { + nk_hdr->val_off = -1; + nk_hdr->val_cnt = 0; + } + + /* + * Finally, store the subkeys, and their offsets + */ + +error: + return 0; +} + +/* + * Store the registry header ... + * We actually create the registry header block and link it to the chain + * of output blocks. + */ +static REGF_HDR *nt_get_reg_header(struct registry_hive *h) { + REGF *regf = h->backend_data; + HBIN_BLK *tmp = NULL; + + tmp = malloc_p(HBIN_BLK); + + memset(tmp, 0, sizeof(HBIN_BLK)); + tmp->type = REG_OUTBLK_HDR; + tmp->size = REGF_HDR_BLKSIZ; + tmp->data = malloc(REGF_HDR_BLKSIZ); + if (!tmp->data) goto error; + + memset(tmp->data, 0, REGF_HDR_BLKSIZ); /* Make it pristine, unlike Windows */ + regf->blk_head = regf->blk_tail = tmp; + + return (REGF_HDR *)tmp->data; + +error: + if (tmp) free(tmp); + return NULL; +} + +#endif + +static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) +{ + REGF *regf; + REGF_HDR *regf_hdr; + uint_t regf_id, hbin_id; + HBIN_HDR *hbin_hdr; + + regf = (REGF *)talloc_p(h, REGF); + memset(regf, 0, sizeof(REGF)); + regf->owner_sid_str = NULL; /* FIXME: Fill in */ + h->backend_data = regf; + + DEBUG(5, ("Attempting to load registry file\n")); + + /* Get the header */ + + if ((regf_hdr = nt_get_regf_hdr(h)) == NULL) { + DEBUG(0, ("Unable to get header\n")); + return WERR_GENERAL_FAILURE; + } + + /* Now process that header and start to read the rest in */ + + if ((regf_id = IVAL(®f_hdr->REGF_ID,0)) != str_to_dword("regf")) { + DEBUG(0, ("Unrecognized NT registry header id: %0X, %s\n", + regf_id, h->location)); + return WERR_GENERAL_FAILURE; + } + + /* + * Validate the header ... + */ + if (!valid_regf_hdr(regf_hdr)) { + DEBUG(0, ("Registry file header does not validate: %s\n", + h->location)); + return WERR_GENERAL_FAILURE; + } + + /* Update the last mod date, and then go get the first NK record and on */ + + TTTONTTIME(regf, IVAL(®f_hdr->tim1,0), IVAL(®f_hdr->tim2,0)); + + /* + * The hbin hdr seems to be just uninteresting garbage. Check that + * it is there, but that is all. + */ + + hbin_hdr = (HBIN_HDR *)(regf->base + REGF_HDR_BLKSIZ); + + if ((hbin_id = IVAL(&hbin_hdr->HBIN_ID,0)) != str_to_dword("hbin")) { + DEBUG(0, ("Unrecognized registry hbin hdr ID: %0X, %s\n", + hbin_id, h->location)); + return WERR_GENERAL_FAILURE; + } + + /* + * Get a pointer to the first key from the hreg_hdr + */ + + DEBUG(2, ("First Key: %0X\n", + IVAL(®f_hdr->first_key, 0))); + + regf->first_key = (NK_HDR *)LOCN(regf->base, IVAL(®f_hdr->first_key,0)); + DEBUGADD(2, ("First Key Offset: %0X\n", + IVAL(®f_hdr->first_key, 0))); + + DEBUGADD(2, ("Data Block Size: %d\n", + IVAL(®f_hdr->dblk_size, 0))); + + DEBUGADD(2, ("Offset to next hbin block: %0X\n", + IVAL(&hbin_hdr->off_to_next, 0))); + + DEBUGADD(2, ("HBIN block size: %0X\n", + IVAL(&hbin_hdr->blk_size, 0))); + + /* + * Unmap the registry file, as we might want to read in another + * tree etc. + */ + + h->backend_data = regf; + + return nk_to_key(h, h, ((REGF *)h->backend_data)->first_key, BLK_SIZE(((REGF *)h->backend_data)->first_key), NULL, key); +} + + +static WERROR nt_num_subkeys(struct registry_key *k, int *num) +{ + REGF *regf = k->hive->backend_data; + LF_HDR *lf_hdr; + int lf_off; + NK_HDR *nk_hdr = k->backend_data; + lf_off = IVAL(&nk_hdr->lf_off,0); + DEBUG(2, ("SubKey list offset: %0X\n", lf_off)); + if(lf_off == -1) { + *num = 0; + return WERR_OK; + } + lf_hdr = (LF_HDR *)LOCN(regf->base, lf_off); + + return lf_num_entries(k->hive, lf_hdr, BLK_SIZE(lf_hdr), num); +} + +static WERROR nt_num_values(struct registry_key *k, int *count) +{ + NK_HDR *nk_hdr = k->backend_data; + *count = IVAL(&nk_hdr->val_cnt,0); + return WERR_OK; +} + +static WERROR nt_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *k, int n, struct registry_value **value) +{ + VL_TYPE *vl; + int val_off, vk_off; + int val_count; + VK_HDR *vk_hdr; + REGF *regf = k->hive->backend_data; + NK_HDR *nk_hdr = k->backend_data; + val_count = IVAL(&nk_hdr->val_cnt,0); + val_off = IVAL(&nk_hdr->val_off,0); + vl = (VL_TYPE *)LOCN(regf->base, val_off); + DEBUG(2, ("Val List Offset: %0X\n", val_off)); + if(n < 0) return WERR_INVALID_PARAM; + if(n >= val_count) return WERR_NO_MORE_ITEMS; + + vk_off = IVAL(&vl[n],0); + vk_hdr = (VK_HDR *)LOCN(regf->base, vk_off); + return vk_to_val(mem_ctx, k, vk_hdr, BLK_SIZE(vk_hdr), value); +} + +static WERROR nt_key_by_index(TALLOC_CTX *mem_ctx, struct registry_key *k, int n, struct registry_key **subkey) +{ + REGF *regf = k->hive->backend_data; + int lf_off; + NK_HDR *nk_hdr = k->backend_data; + LF_HDR *lf_hdr; + lf_off = IVAL(&nk_hdr->lf_off,0); + DEBUG(2, ("SubKey list offset: %0X\n", lf_off)); + + /* + * No more subkeys if lf_off == -1 + */ + + if (lf_off != -1) { + lf_hdr = (LF_HDR *)LOCN(regf->base, lf_off); + return lf_get_entry(mem_ctx, k, lf_hdr, BLK_SIZE(lf_hdr), n, subkey); + } + + return WERR_NO_MORE_ITEMS; +} + +static struct hive_operations reg_backend_nt4 = { + .name = "nt4", + .open_hive = nt_open_hive, + .num_subkeys = nt_num_subkeys, + .num_values = nt_num_values, + .get_subkey_by_index = nt_key_by_index, + .get_value_by_index = nt_value_by_index, + + /* TODO: + .add_key + .add_value + .del_key + .del_value + .update_value + */ +}; + +NTSTATUS registry_nt4_init(void) +{ + return registry_register(®_backend_nt4); +} diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c deleted file mode 100644 index 381f0c3bcf..0000000000 --- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c +++ /dev/null @@ -1,1747 +0,0 @@ -/* - Samba Unix/Linux SMB client utility libeditreg.c - Copyright (C) 2002 Richard Sharpe, rsharpe@richardsharpe.com - Copyright (C) 2003-2004 Jelmer Vernooij, jelmer@samba.org - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/************************************************************************* - - A utility to edit a Windows NT/2K etc registry file. - - Many of the ideas in here come from other people and software. - I first looked in Wine in misc/registry.c and was also influenced by - http://www.wednesday.demon.co.uk/dosreg.html - - Which seems to contain comments from someone else. I reproduce them here - incase the site above disappears. It actually comes from - http://home.eunet.no/~pnordahl/ntpasswd/WinReg.txt. - - The goal here is to read the registry into memory, manipulate it, and then - write it out if it was changed by any actions of the user. - -The windows NT registry has 2 different blocks, where one can occur many -times... - -the "regf"-Block -================ - -"regf" is obviously the abbreviation for "Registry file". "regf" is the -signature of the header-block which is always 4kb in size, although only -the first 64 bytes seem to be used and a checksum is calculated over -the first 0x200 bytes only! - -Offset Size Contents -0x00000000 D-Word ID: ASCII-"regf" = 0x66676572 -0x00000004 D-Word ???? //see struct REG_HANDLE -0x00000008 D-Word ???? Always the same value as at 0x00000004 -0x0000000C Q-Word last modify date in WinNT date-format -0x00000014 D-Word 1 -0x00000018 D-Word 3 -0x0000001C D-Word 0 -0x00000020 D-Word 1 -0x00000024 D-Word Offset of 1st key record -0x00000028 D-Word Size of the data-blocks (Filesize-4kb) -0x0000002C D-Word 1 -0x000001FC D-Word Sum of all D-Words from 0x00000000 to -0x000001FB //XOR of all words. Nigel - -I have analyzed more registry files (from multiple machines running -NT 4.0 german version) and could not find an explanation for the values -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 -of 4kb in size. - -Inside these hbin-blocks the different records are placed. The memory- -management looks like a C-compiler heap management to me... - -hbin-Header -=========== -Offset Size Contents -0x0000 D-Word ID: ASCII-"hbin" = 0x6E696268 -0x0004 D-Word Offset from the 1st hbin-Block -0x0008 D-Word Offset to the next hbin-Block -0x001C D-Word Block-size - -The values in 0x0008 and 0x001C should be the same, so I don't know -if they are correct or swapped... - -From offset 0x0020 inside a hbin-block data is stored with the following -format: - -Offset Size Contents -0x0000 D-Word Data-block size //this size must be a -multiple of 8. Nigel -0x0004 ???? Data - -If the size field is negative (bit 31 set), the corresponding block -is free and has a size of -blocksize! - -That does not seem to be true. All block lengths seem to be negative! -(Richard Sharpe) - -The data is stored as one record per block. Block size is a multiple -of 4 and the last block reaches the next hbin-block, leaving no room. - -(That also seems incorrect, in that the block size if a multiple of 8. -That is, the block, including the 4 byte header, is always a multiple of -8 bytes. Richard Sharpe.) - -Records in the hbin-blocks -========================== - -nk-Record - - The nk-record can be treated as a combination of tree-record and - key-record of the win 95 registry. - -lf-Record - - The lf-record is the counterpart to the RGKN-record (the - hash-function) - -vk-Record - - The vk-record consists information to a single value (value key). - -sk-Record - - sk (? Security Key ?) is the ACL of the registry. - -Value-Lists - - The value-lists contain information about which values are inside a - sub-key and don't have a header. - -Datas - - The datas of the registry are (like the value-list) stored without a - header. - -All offset-values are relative to the first hbin-block and point to the -block-size field of the record-entry. to get the file offset, you have to add -the header size (4kb) and the size field (4 bytes)... - -the nk-Record -============= -Offset Size Contents -0x0000 Word ID: ASCII-"nk" = 0x6B6E -0x0002 Word for the root-key: 0x2C, otherwise 0x20 //key symbolic links 0x10. Nigel -0x0004 Q-Word write-date/time in windows nt notation -0x0010 D-Word Offset of Owner/Parent key -0x0014 D-Word number of sub-Keys -0x001C D-Word Offset of the sub-key lf-Records -0x0024 D-Word number of values -0x0028 D-Word Offset of the Value-List -0x002C D-Word Offset of the sk-Record - -0x0030 D-Word Offset of the Class-Name //see NK structure for the use of these fields. Nigel -0x0044 D-Word Unused (data-trash) //some kind of run time index. Does not appear to be important. Nigel -0x0048 Word name-length -0x004A Word class-name length -0x004C ???? key-name - -the Value-List -============== -Offset Size Contents -0x0000 D-Word Offset 1st Value -0x0004 D-Word Offset 2nd Value -0x???? D-Word Offset nth Value - -To determine the number of values, you have to look at the owner-nk-record! - -The vk-Record -============= -Offset Size Contents -0x0000 Word ID: ASCII-"vk" = 0x6B76 -0x0002 Word name length -0x0004 D-Word length of the data //if top bit is set when offset contains data. Nigel -0x0008 D-Word Offset of Data -0x000C D-Word Type of value -0x0010 Word Flag -0x0012 Word Unused (data-trash) -0x0014 ???? Name - -If bit 0 of the flag-word is set, a name is present, otherwise the value has no name (=default) - -If the data-size is lower 5, the data-offset value is used to store the data itself! - -The data-types -============== -Wert Beteutung -0x0001 RegSZ: character string (in UNICODE!) -0x0002 ExpandSZ: string with "%var%" expanding (UNICODE!) -0x0003 RegBin: raw-binary value -0x0004 RegDWord: Dword -0x0007 RegMultiSZ: multiple strings, seperated with 0 - (UNICODE!) - -The "lf"-record -=============== -Offset Size Contents -0x0000 Word ID: ASCII-"lf" = 0x666C -0x0002 Word number of keys -0x0004 ???? Hash-Records - -Hash-Record -=========== -Offset Size Contents -0x0000 D-Word Offset of corresponding "nk"-Record -0x0004 D-Word ASCII: the first 4 characters of the key-name, padded with 0's. Case sensitiv! - -Keep in mind, that the value at 0x0004 is used for checking the data-consistency! If you change the -key-name you have to change the hash-value too! - -//These hashrecords must be sorted low to high within the lf record. Nigel. - -The "sk"-block -============== -(due to the complexity of the SAM-info, not clear jet) -(This is just a self-relative security descriptor in the data. R Sharpe.) - - -Offset Size Contents -0x0000 Word ID: ASCII-"sk" = 0x6B73 -0x0002 Word Unused -0x0004 D-Word Offset of previous "sk"-Record -0x0008 D-Word Offset of next "sk"-Record -0x000C D-Word usage-counter -0x0010 D-Word Size of "sk"-record in bytes -???? //standard self -relative security desciptor. Nigel -???? ???? Security and auditing settings... -???? - -The usage counter counts the number of references to this -"sk"-record. You can use one "sk"-record for the entire registry! - -Windows nt date/time format -=========================== -The time-format is a 64-bit integer which is incremented every -0,0000001 seconds by 1 (I don't know how accurate it realy is!) -It starts with 0 at the 1st of january 1601 0:00! All values are -stored in GMT time! The time-zone is important to get the real -time! - -Common values for win95 and win-nt -================================== -Offset values marking an "end of list", are either 0 or -1 (0xFFFFFFFF). -If a value has no name (length=0, flag(bit 0)=0), it is treated as the -"Default" entry... -If a value has no data (length=0), it is displayed as empty. - -simplyfied win-3.?? registry: -============================= - -+-----------+ -| next rec. |---+ +----->+------------+ -| first sub | | | | Usage cnt. | -| name | | +-->+------------+ | | length | -| value | | | | next rec. | | | text |------->+-------+ -+-----------+ | | | name rec. |--+ +------------+ | xxxxx | - +------------+ | | value rec. |-------->+------------+ +-------+ - v | +------------+ | Usage cnt. | -+-----------+ | | length | -| next rec. | | | text |------->+-------+ -| first sub |------+ +------------+ | xxxxx | -| name | +-------+ -| value | -+-----------+ - -Greatly simplyfied structure of the nt-registry: -================================================ - -+---------------------------------------------------------------+ -| | -v | -+---------+ +---------->+-----------+ +----->+---------+ | -| "nk" | | | lf-rec. | | | nk-rec. | | -| ID | | | # of keys | | | parent |---+ -| Date | | | 1st key |--+ | .... | -| parent | | +-----------+ +---------+ -| suk-keys|-----+ -| values |--------------------->+----------+ -| SK-rec. |---------------+ | 1. value |--> +----------+ -| class |--+ | +----------+ | vk-rec. | -+---------+ | | | .... | - v | | data |--> +-------+ - +------------+ | +----------+ | xxxxx | - | Class name | | +-------+ - +------------+ | - v - +---------+ +---------+ - +----->| next sk |--->| Next sk |--+ - | +---| prev sk |<---| prev sk | | - | | | .... | | ... | | - | | +---------+ +---------+ | - | | ^ | - | | | | - | +--------------------+ | - +----------------------------------+ - ---------------------------------------------------------------------------- - -Hope this helps.... (Although it was "fun" for me to uncover this things, - it took me several sleepless nights ;) - - B.D. - -*************************************************************************/ - -#include "includes.h" -#include "registry.h" -#include "system/shmem.h" - -#define REG_KEY_LIST_SIZE 10 -#define FLAG_HAS_NAME 0x01 -/*FIXME*/ - -/* - * Structures for dealing with the on-disk format of the registry - */ - -const char *def_owner_sid_str = NULL; - -/* - * These definitions are for the in-memory registry structure. - * It is a tree structure that mimics what you see with tools like regedit - */ - - -/* - * Definition of a Key. It has a name, classname, date/time last modified, - * sub-keys, values, and a security descriptor - */ - -#define REG_ROOT_KEY 1 -#define REG_SUB_KEY 2 -#define REG_SYM_LINK 3 - -/* - * All of the structures below actually have a four-byte length before them - * which always seems to be negative. The following macro retrieves that - * size as an integer - */ - -#define BLK_SIZE(b) ((int)*(int *)(((int *)b)-1)) - -typedef uint_t DWORD; -typedef unsigned short WORD; - -typedef struct sk_struct SK_HDR; -/* - * This structure keeps track of the output format of the registry - */ -#define REG_OUTBLK_HDR 1 -#define REG_OUTBLK_HBIN 2 - -typedef struct regf_block { - DWORD REGF_ID; /* regf */ - DWORD uk1; - DWORD uk2; - DWORD tim1, tim2; - DWORD uk3; /* 1 */ - DWORD uk4; /* 3 */ - DWORD uk5; /* 0 */ - DWORD uk6; /* 1 */ - DWORD first_key; /* offset */ - uint_t dblk_size; - DWORD uk7[116]; /* 1 */ - DWORD chksum; -} REGF_HDR; - -typedef struct hbin_sub_struct { - DWORD dblocksize; - char data[1]; -} HBIN_SUB_HDR; - -typedef struct hbin_struct { - DWORD HBIN_ID; /* hbin */ - DWORD off_from_first; - DWORD off_to_next; - DWORD uk1; - DWORD uk2; - DWORD uk3; - DWORD uk4; - DWORD blk_size; - HBIN_SUB_HDR hbin_sub_hdr; -} HBIN_HDR; - -typedef struct nk_struct { - WORD NK_ID; - WORD type; - DWORD t1, t2; - DWORD uk1; - DWORD own_off; - DWORD subk_num; - DWORD uk2; - DWORD lf_off; - DWORD uk3; - DWORD val_cnt; - DWORD val_off; - DWORD sk_off; - DWORD clsnam_off; - DWORD unk4[4]; - DWORD unk5; - WORD nam_len; - WORD clsnam_len; - char key_nam[1]; /* Actual length determined by nam_len */ -} NK_HDR; - -struct sk_struct { - WORD SK_ID; - WORD uk1; - DWORD prev_off; - DWORD next_off; - DWORD ref_cnt; - DWORD rec_size; - char sec_desc[1]; -}; - -typedef struct key_sec_desc_s { - struct key_sec_desc_s *prev, *next; - int ref_cnt; - int state; - int offset; - SK_HDR *sk_hdr; /* This means we must keep the registry in memory */ - SEC_DESC *sec_desc; -} KEY_SEC_DESC; - -/* A map of sk offsets in the regf to KEY_SEC_DESCs for quick lookup etc */ -typedef struct sk_map_s { - int sk_off; - KEY_SEC_DESC *key_sec_desc; -} SK_MAP; - -typedef struct vk_struct { - WORD VK_ID; - WORD nam_len; - DWORD dat_len; /* If top-bit set, offset contains the data */ - DWORD dat_off; - DWORD dat_type; - WORD flag; /* =1, has name, else no name (=Default). */ - WORD unk1; - char dat_name[1]; /* Name starts here ... */ -} VK_HDR; - -typedef DWORD VL_TYPE[1]; /* Value list is an array of vk rec offsets */ - -typedef struct hash_struct { - DWORD nk_off; - char hash[4]; -} HASH_REC; - - -typedef struct lf_struct { - WORD LF_ID; - WORD key_count; - struct hash_struct hr[1]; /* Array of hash records, depending on key_count */} LF_HDR; - - - -/* - * This structure keeps track of the output format of the registry - */ -#define REG_OUTBLK_HDR 1 -#define REG_OUTBLK_HBIN 2 - -typedef struct hbin_blk_s { - int type, size; - struct hbin_blk_s *next; - char *data; /* The data block */ - uint_t file_offset; /* Offset in file */ - uint_t free_space; /* Amount of free space in block */ - uint_t fsp_off; /* Start of free space in block */ - int complete, stored; -} HBIN_BLK; - -typedef struct regf_struct_s { - int reg_type; - int fd; - struct stat sbuf; - char *base; - BOOL modified; - NTTIME last_mod_time; - NK_HDR *first_key; - int sk_count, sk_map_size; - SK_MAP *sk_map; - const char *owner_sid_str; - SEC_DESC *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 - */ - HBIN_BLK *blk_head, *blk_tail, *free_space; -} REGF; - -static DWORD str_to_dword(const char *a) { - int i; - unsigned long ret = 0; - for(i = strlen(a)-1; i >= 0; i--) { - ret = ret * 0x100 + a[i]; - } - return ret; -} - -#if 0 - -/* - * Create an ACE - */ -static BOOL nt_create_ace(SEC_ACE *ace, int type, int flags, uint32_t perms, const char *sid) -{ - DOM_SID s; - SEC_ACCESS access; - access.mask = perms; - if(!string_to_sid(&s, sid))return False; - init_sec_ace(ace, &s, type, access, flags); - return True; -} - -/* - * Create a default ACL - */ -static SEC_ACL *nt_create_default_acl(struct registry_hive *regf) -{ - SEC_ACE aces[8]; - - if(!nt_create_ace(&aces[0], 0x00, 0x0, 0xF003F, regf->owner_sid_str)) return NULL; - if(!nt_create_ace(&aces[1], 0x00, 0x0, 0xF003F, "S-1-5-18")) return NULL; - if(!nt_create_ace(&aces[2], 0x00, 0x0, 0xF003F, "S-1-5-32-544")) return NULL; - if(!nt_create_ace(&aces[3], 0x00, 0x0, 0x20019, "S-1-5-12")) return NULL; - if(!nt_create_ace(&aces[4], 0x00, 0x0B, GENERIC_RIGHT_ALL_ACCESS, regf->owner_sid_str)) return NULL; - if(!nt_create_ace(&aces[5], 0x00, 0x0B, 0x10000000, "S-1-5-18")) return NULL; - if(!nt_create_ace(&aces[6], 0x00, 0x0B, 0x10000000, "S-1-5-32-544")) return NULL; - if(!nt_create_ace(&aces[7], 0x00, 0x0B, 0x80000000, "S-1-5-12")) return NULL; - - return make_sec_acl(regf->mem_ctx, 2, 8, aces); -} - -/* - * Create a default security descriptor. We pull in things from env - * if need be - */ -static SEC_DESC *nt_create_def_sec_desc(struct registry_hive *regf) -{ - SEC_DESC *tmp; - - tmp = malloc_p(SEC_DESC); - - tmp->revision = 1; - tmp->type = SEC_DESC_SELF_RELATIVE | SEC_DESC_DACL_PRESENT; - if (!string_to_sid(tmp->owner_sid, "S-1-5-32-544")) goto error; - if (!string_to_sid(tmp->grp_sid, "S-1-5-18")) goto error; - tmp->sacl = NULL; - tmp->dacl = nt_create_default_acl(regf); - - return tmp; - - error: - if (tmp) nt_delete_sec_desc(tmp); - return NULL; -} - -/* - * We will implement inheritence that is based on what the parent's SEC_DESC - * says, but the Owner and Group SIDs can be overwridden from the command line - * and additional ACEs can be applied from the command line etc. - */ -static KEY_SEC_DESC *nt_inherit_security(struct registry_key *key) -{ - - if (!key) return NULL; - return key->security; -} - -/* - * Create an initial security descriptor and init other structures, if needed - * We assume that the initial security stuff is empty ... - */ -static KEY_SEC_DESC *nt_create_init_sec(struct registry_hive *h) -{ - REGF *regf = h->backend_data; - KEY_SEC_DESC *tsec = NULL; - - tsec = malloc_p(KEY_SEC_DESC); - - tsec->ref_cnt = 1; - tsec->state = SEC_DESC_NBK; - tsec->offset = 0; - - tsec->sec_desc = regf->def_sec_desc; - - return tsec; -} -#endif - -/* - * Get the starting record for NT Registry file - */ - -/* - * Where we keep all the regf stuff for one registry. - * This is the structure that we use to tie the in memory tree etc - * together. By keeping separate structs, we can operate on different - * registries at the same time. - * Currently, the SK_MAP is an array of mapping structure. - * Since we only need this on input and output, we fill in the structure - * as we go on input. On output, we know how many SK items we have, so - * we can allocate the structure as we need to. - * If you add stuff here that is dynamically allocated, add the - * appropriate free statements below. - */ - -#define REG_HANDLE_REGTYPE_NONE 0 -#define REG_HANDLE_REGTYPE_NT 1 -#define REG_HANDLE_REGTYPE_W9X 2 - -#define TTTONTTIME(r, t1, t2) (r)->last_mod_time = (t1) | (((uint64_t)(t2)) << 32) - -#define REGF_HDR_BLKSIZ 0x1000 - -#define OFF(f) ((f) + REGF_HDR_BLKSIZ + 4) -#define LOCN(base, f) ((base) + OFF(f)) - -/* Get the header of the registry. Return a pointer to the structure - * If the mmap'd area has not been allocated, then mmap the input file - */ -static REGF_HDR *nt_get_regf_hdr(struct registry_hive *h) -{ - REGF *regf = h->backend_data; - SMB_REG_ASSERT(regf); - - if (!regf->base) { /* Try to mmap etc the file */ - - if ((regf->fd = open(h->location, O_RDONLY, 0000)) <0) { - return NULL; /* What about errors? */ - } - - if (fstat(regf->fd, ®f->sbuf) < 0) { - return NULL; - } - - regf->base = mmap(0, regf->sbuf.st_size, PROT_READ, MAP_SHARED, regf->fd, 0); - - if ((int)regf->base == 1) { - DEBUG(0,("Could not mmap file: %s, %s\n", h->location, - strerror(errno))); - return NULL; - } - } - - /* - * At this point, regf->base != NULL, and we should be able to read the - * header - */ - - SMB_REG_ASSERT(regf->base != NULL); - - return (REGF_HDR *)regf->base; -} - -/* - * Validate a regf header - * For now, do nothing, but we should check the checksum - */ -static int valid_regf_hdr(REGF_HDR *regf_hdr) -{ - if (!regf_hdr) return 0; - - return 1; -} - -#if 0 - -/* - * Process an SK header ... - * Every time we see a new one, add it to the map. Otherwise, just look it up. - * We will do a simple linear search for the moment, since many KEYs have the - * same security descriptor. - * We allocate the map in increments of 10 entries. - */ - -/* - * Create a new entry in the map, and increase the size of the map if needed - */ -static SK_MAP *alloc_sk_map_entry(struct registry_hive *h, KEY_SEC_DESC *tmp, int sk_off) -{ - REGF *regf = h->backend_data; - if (!regf->sk_map) { /* Allocate a block of 10 */ - regf->sk_map = malloc_array_p(SK_MAP, 10); - regf->sk_map_size = 10; - regf->sk_count = 1; - (regf->sk_map)[0].sk_off = sk_off; - (regf->sk_map)[0].key_sec_desc = tmp; - } - else { /* Simply allocate a new slot, unless we have to expand the list */ - int ndx = regf->sk_count; - if (regf->sk_count >= regf->sk_map_size) { - regf->sk_map = (SK_MAP *)realloc(regf->sk_map, - (regf->sk_map_size + 10)*sizeof(SK_MAP)); - if (!regf->sk_map) { - free(tmp); - return NULL; - } - /* - * ndx already points at the first entry of the new block - */ - regf->sk_map_size += 10; - } - (regf->sk_map)[ndx].sk_off = sk_off; - (regf->sk_map)[ndx].key_sec_desc = tmp; - regf->sk_count++; - } - return regf->sk_map; -} - -/* - * Search for a KEY_SEC_DESC in the sk_map, but don't create one if not - * found - */ -KEY_SEC_DESC *lookup_sec_key(SK_MAP *sk_map, int count, int sk_off) -{ - int i; - - if (!sk_map) return NULL; - - for (i = 0; i < count; i++) { - - if (sk_map[i].sk_off == sk_off) - return sk_map[i].key_sec_desc; - - } - - return NULL; - -} - -/* - * Allocate a KEY_SEC_DESC if we can't find one in the map - */ -static KEY_SEC_DESC *lookup_create_sec_key(struct registry_hive *h, SK_MAP *sk_map, int sk_off) -{ - REGF *regf = h->backend_data; - KEY_SEC_DESC *tmp = lookup_sec_key(regf->sk_map, regf->sk_count, sk_off); - - if (tmp) { - return tmp; - } - else { /* Allocate a new one */ - tmp = malloc_p(KEY_SEC_DESC); - memset(tmp, 0, sizeof(KEY_SEC_DESC)); /* Neatly sets offset to 0 */ - tmp->state = SEC_DESC_RES; - if (!alloc_sk_map_entry(h, tmp, sk_off)) { - return NULL; - } - return tmp; - } -} - -static SEC_DESC *process_sec_desc(struct registry_hive *regf, SEC_DESC *sec_desc) -{ - SEC_DESC *tmp = NULL; - - tmp = malloc_p(SEC_DESC); - - tmp->revision = SVAL(&sec_desc->revision,0); - tmp->type = SVAL(&sec_desc->type,0); - DEBUG(2, ("SEC_DESC Rev: %0X, Type: %0X\n", tmp->revision, tmp->type)); - DEBUGADD(2, ("SEC_DESC Owner Off: %0X\n", IVAL(&sec_desc->off_owner_sid,0))); - DEBUGADD(2, ("SEC_DESC Group Off: %0X\n", IVAL(&sec_desc->off_grp_sid,0))); - DEBUGADD(2, ("SEC_DESC DACL Off: %0X\n", IVAL(&sec_desc->off_dacl,0))); - tmp->owner_sid = sid_dup_talloc(regf->mem_ctx, (DOM_SID *)((char *)sec_desc + IVAL(&sec_desc->off_owner_sid,0))); - if (!tmp->owner_sid) { - free(tmp); - return NULL; - } - tmp->grp_sid = sid_dup_talloc(regf->mem_ctx, (DOM_SID *)((char *)sec_desc + IVAL(&sec_desc->off_grp_sid,0))); - if (!tmp->grp_sid) { - free(tmp); - return NULL; - } - - /* Now pick up the SACL and DACL */ - - DEBUG(0, ("%d, %d\n", IVAL(&sec_desc->off_sacl,0), IVAL(&sec_desc->off_dacl,0))); - - if (sec_desc->off_sacl) - tmp->sacl = dup_sec_acl(regf->mem_ctx, (SEC_ACL *)((char *)sec_desc + IVAL(&sec_desc->off_sacl,0))); - else - tmp->sacl = NULL; - - if (sec_desc->off_dacl) - tmp->dacl = dup_sec_acl(regf->mem_ctx, (SEC_ACL *)((char *)sec_desc + IVAL(&sec_desc->off_dacl,0))); - else - tmp->dacl = NULL; - - return tmp; -} - -static KEY_SEC_DESC *process_sk(struct registry_hive *regf, SK_HDR *sk_hdr, int sk_off, int size) -{ - KEY_SEC_DESC *tmp = NULL; - int sk_next_off, sk_prev_off, sk_size; - SEC_DESC *sec_desc; - - if (!sk_hdr) return NULL; - - if (SVAL(&sk_hdr->SK_ID,0) != str_to_dword("sk")) { - DEBUG(0, ("Unrecognized SK Header ID: %08X, %s\n", (int)sk_hdr, - regf->regfile_name)); - return NULL; - } - - if (-size < (sk_size = IVAL(&sk_hdr->rec_size,0))) { - DEBUG(0, ("Incorrect SK record size: %d vs %d. %s\n", - -size, sk_size, regf->regfile_name)); - return NULL; - } - - /* - * Now, we need to look up the SK Record in the map, and return it - * Since the map contains the SK_OFF mapped to KEY_SEC_DESC, we can - * use that - */ - - if (regf->sk_map && - ((tmp = lookup_sec_key(regf->sk_map, regf->sk_count, sk_off)) != NULL) - && (tmp->state == SEC_DESC_OCU)) { - tmp->ref_cnt++; - return tmp; - } - - /* Here, we have an item in the map that has been reserved, or tmp==NULL. */ - - SMB_REG_ASSERT(tmp == NULL || (tmp && tmp->state != SEC_DESC_NON)); - - /* - * Now, allocate a KEY_SEC_DESC, and parse the structure here, and add the - * new KEY_SEC_DESC to the mapping structure, since the offset supplied is - * the actual offset of structure. The same offset will be used by - * all future references to this structure - * We could put all this unpleasantness in a function. - */ - - if (!tmp) { - tmp = malloc_p(KEY_SEC_DESC); - memset(tmp, 0, sizeof(KEY_SEC_DESC)); - - /* - * Allocate an entry in the SK_MAP ... - * We don't need to free tmp, because that is done for us if the - * sm_map entry can't be expanded when we need more space in the map. - */ - - if (!alloc_sk_map_entry(regf, tmp, sk_off)) { - return NULL; - } - } - - tmp->ref_cnt++; - tmp->state = SEC_DESC_OCU; - - /* - * Now, process the actual sec desc and plug the values in - */ - - sec_desc = (SEC_DESC *)&sk_hdr->sec_desc[0]; - tmp->sec_desc = process_sec_desc(regf, sec_desc); - - /* - * Now forward and back links. Here we allocate an entry in the sk_map - * if it does not exist, and mark it reserved - */ - - sk_prev_off = IVAL(&sk_hdr->prev_off,0); - tmp->prev = lookup_create_sec_key(regf, regf->sk_map, sk_prev_off); - SMB_REG_ASSERT(tmp->prev != NULL); - sk_next_off = IVAL(&sk_hdr->next_off,0); - tmp->next = lookup_create_sec_key(regf, regf->sk_map, sk_next_off); - SMB_REG_ASSERT(tmp->next != NULL); - - return tmp; -} -#endif - -/* - * Process a VK header and return a value - */ -static WERROR vk_to_val(TALLOC_CTX *mem_ctx, struct registry_key *parent, VK_HDR *vk_hdr, int size, struct registry_value **value) -{ - REGF *regf = parent->hive->backend_data; - int nam_len, dat_len, flag, dat_type, dat_off, vk_id; - struct registry_value *tmp = NULL; - - if (!vk_hdr) return WERR_INVALID_PARAM; - - if ((vk_id = SVAL(&vk_hdr->VK_ID,0)) != str_to_dword("vk")) { - DEBUG(0, ("Unrecognized VK header ID: %0X, block: %0X, %s\n", - vk_id, (int)vk_hdr, parent->hive->location)); - return WERR_GENERAL_FAILURE; - } - - nam_len = SVAL(&vk_hdr->nam_len,0); - flag = SVAL(&vk_hdr->flag,0); - dat_type = IVAL(&vk_hdr->dat_type,0); - dat_len = IVAL(&vk_hdr->dat_len,0); /* If top bit, offset contains data */ - dat_off = IVAL(&vk_hdr->dat_off,0); - - tmp = talloc_p(mem_ctx, struct registry_value); - tmp->data_type = dat_type; - - if (flag & FLAG_HAS_NAME) { - tmp->name = talloc_strndup(mem_ctx, vk_hdr->dat_name, nam_len); - } else { - tmp->name = NULL; - } - - /* - * Allocate space and copy the data as a BLOB - */ - - if (dat_len&0x7FFFFFFF) { - - char *dtmp = (char *)talloc(mem_ctx, dat_len&0x7FFFFFFF); - - if ((dat_len&0x80000000) == 0) { /* The data is pointed to by the offset */ - char *dat_ptr = LOCN(regf->base, dat_off); - memcpy(dtmp, dat_ptr, dat_len); - } - else { /* The data is in the offset or type */ - /* - * FIXME. - * Some registry files seem to have weird fields. If top bit is set, - * but len is 0, the type seems to be the value ... - * Not sure how to handle this last type for the moment ... - */ - dat_len = dat_len & 0x7FFFFFFF; - memcpy(dtmp, &dat_off, dat_len); - } - - - if(tmp->data_type == REG_SZ) { - char *ret; - dat_len = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, dtmp, dat_len, (void **)&ret); - dtmp = ret; - } - - - tmp->data_blk = dtmp; - tmp->data_len = dat_len; - } - - *value = tmp; - return WERR_OK; -} - -#if 0 /* unused */ - -static BOOL vl_verify(VL_TYPE vl, int count, int size) -{ - if(!vl) return False; - if (-size < (count+1)*sizeof(int)){ - DEBUG(0, ("Error in VL header format. Size less than space required. %d\n", -size)); - return False; - } - return True; -} - -#endif - -static WERROR lf_verify(struct registry_hive *h, LF_HDR *lf_hdr, int size) -{ - int lf_id; - if ((lf_id = SVAL(&lf_hdr->LF_ID,0)) != str_to_dword("lf")) { - DEBUG(0, ("Unrecognized LF Header format: %0X, Block: %0X, %s.\n", - lf_id, (int)lf_hdr, h->location)); - return WERR_INVALID_PARAM; - } - return WERR_OK; -} - -static WERROR lf_num_entries(struct registry_hive *h, LF_HDR *lf_hdr, int size, int *count) -{ - WERROR error; - - error = lf_verify(h, lf_hdr, size); - if(!W_ERROR_IS_OK(error)) return error; - - SMB_REG_ASSERT(size < 0); - - *count = SVAL(&lf_hdr->key_count,0); - DEBUG(2, ("Key Count: %u\n", *count)); - if (*count <= 0) return WERR_INVALID_PARAM; - - return WERR_OK; -} - - -static WERROR nk_to_key(TALLOC_CTX *, struct registry_hive *regf, NK_HDR *nk_hdr, int size, struct registry_key *parent, struct registry_key **); - - - -/* - * Process an LF Header and return a list of sub-keys - */ -static WERROR lf_get_entry(TALLOC_CTX *mem_ctx, struct registry_key *parent, LF_HDR *lf_hdr, int size, int n, struct registry_key **key) -{ - REGF *regf = parent->hive->backend_data; - int count, nk_off; - NK_HDR *nk_hdr; - WERROR error; - - if (!lf_hdr) return WERR_INVALID_PARAM; - - error = lf_verify(parent->hive, lf_hdr, size); - if(!W_ERROR_IS_OK(error)) return error; - - SMB_REG_ASSERT(size < 0); - - count = SVAL(&lf_hdr->key_count,0); - DEBUG(2, ("Key Count: %u\n", count)); - if (count <= 0) return WERR_GENERAL_FAILURE; - if (n >= count) return WERR_NO_MORE_ITEMS; - - nk_off = IVAL(&lf_hdr->hr[n].nk_off,0); - DEBUG(2, ("NK Offset: %0X\n", nk_off)); - nk_hdr = (NK_HDR *)LOCN(regf->base, nk_off); - return nk_to_key(mem_ctx, parent->hive, nk_hdr, BLK_SIZE(nk_hdr), parent, key); -} - -static WERROR nk_to_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, NK_HDR *nk_hdr, int size, struct registry_key *parent, struct registry_key **key) -{ - REGF *regf = h->backend_data; - struct registry_key *tmp = NULL, *own; - int namlen, clsname_len, sk_off, own_off; - uint_t nk_id; - SK_HDR *sk_hdr; - int type; - char key_name[1024]; - - if (!nk_hdr) return WERR_INVALID_PARAM; - - if ((nk_id = SVAL(&nk_hdr->NK_ID,0)) != str_to_dword("nk")) { - DEBUG(0, ("Unrecognized NK Header format: %08X, Block: %0X. %s\n", - nk_id, (int)nk_hdr, parent->hive->location)); - return WERR_INVALID_PARAM; - } - - SMB_REG_ASSERT(size < 0); - - namlen = SVAL(&nk_hdr->nam_len,0); - clsname_len = SVAL(&nk_hdr->clsnam_len,0); - - /* - * The value of -size should be ge - * (sizeof(NK_HDR) - 1 + namlen) - * The -1 accounts for the fact that we included the first byte of - * the name in the structure. clsname_len is the length of the thing - * pointed to by clsnam_off - */ - - if (-size < (sizeof(NK_HDR) - 1 + namlen)) { - DEBUG(0, ("Incorrect NK_HDR size: %d, %0X\n", -size, (int)nk_hdr)); - DEBUG(0, ("Sizeof NK_HDR: %d, name_len %d, clsname_len %d\n", - sizeof(NK_HDR), namlen, clsname_len)); - return WERR_GENERAL_FAILURE; - } - - DEBUG(2, ("NK HDR: Name len: %d, class name len: %d\n", namlen, clsname_len)); - - /* Fish out the key name and process the LF list */ - - SMB_REG_ASSERT(namlen < sizeof(key_name)); - - strncpy(key_name, nk_hdr->key_nam, namlen); - key_name[namlen] = '\0'; - - type = (SVAL(&nk_hdr->type,0)==0x2C?REG_ROOT_KEY:REG_SUB_KEY); - if(type == REG_ROOT_KEY && parent) { - DEBUG(0,("Root key encountered below root level!\n")); - return WERR_GENERAL_FAILURE; - } - - tmp = talloc_p(mem_ctx, struct registry_key); - tmp->name = talloc_strdup(mem_ctx, key_name); - tmp->backend_data = nk_hdr; - - DEBUG(2, ("Key name: %s\n", key_name)); - - /* - * Fish out the class name, it is in UNICODE, while the key name is - * ASCII :-) - */ - - if (clsname_len) { /* Just print in Ascii for now */ - void *clsnamep; - int clsnam_off; - - clsnam_off = IVAL(&nk_hdr->clsnam_off,0); - clsnamep = LOCN(regf->base, clsnam_off); - DEBUG(2, ("Class Name Offset: %0X\n", clsnam_off)); - - pull_ucs2_talloc(mem_ctx, &tmp->class_name, clsnamep); - - DEBUGADD(2,(" Class Name: %s\n", tmp->class_name)); - - } - - /* - * Process the owner offset ... - */ - - own_off = IVAL(&nk_hdr->own_off,0); - own = (struct registry_key *)LOCN(regf->base, own_off); - DEBUG(2, ("Owner Offset: %0X\n", own_off)); - - DEBUGADD(2, (" Owner locn: %0X, Our locn: %0X\n", - (uint_t)own, (uint_t)nk_hdr)); - - /* - * We should verify that the owner field is correct ... - * for now, we don't worry ... - */ - - /* - * Also handle the SK header ... - */ - - sk_off = IVAL(&nk_hdr->sk_off,0); - sk_hdr = (SK_HDR *)LOCN(regf->base, sk_off); - DEBUG(2, ("SK Offset: %0X\n", sk_off)); - - if (sk_off != -1) { - -#if 0 - tmp->security = process_sk(regf, sk_hdr, sk_off, BLK_SIZE(sk_hdr)); -#endif - - } - - *key = tmp; - return WERR_OK; -} - -#if 0 /* unused */ - -/* - * Allocate a new hbin block, set up the header for the block etc - */ -static HBIN_BLK *nt_create_hbin_blk(struct registry_hive *h, int size) -{ - REGF *regf = h->backend_data; - HBIN_BLK *tmp; - HBIN_HDR *hdr; - - if (!regf || !size) return NULL; - - /* Round size up to multiple of REGF_HDR_BLKSIZ */ - - size = (size + (REGF_HDR_BLKSIZ - 1)) & ~(REGF_HDR_BLKSIZ - 1); - - tmp = malloc_p(HBIN_BLK); - memset(tmp, 0, sizeof(HBIN_BLK)); - - tmp->data = malloc(size); - - memset(tmp->data, 0, size); /* Make it pristine */ - - tmp->size = size; - /*FIXMEtmp->file_offset = regf->blk_tail->file_offset + regf->blk_tail->size;*/ - - tmp->free_space = size - (sizeof(HBIN_HDR) - sizeof(HBIN_SUB_HDR)); - tmp->fsp_off = size - tmp->free_space; - - /* - * Now, build the header in the data block - */ - hdr = (HBIN_HDR *)tmp->data; - hdr->HBIN_ID = str_to_dword("hbin"); - hdr->off_from_first = tmp->file_offset - REGF_HDR_BLKSIZ; - hdr->off_to_next = tmp->size; - hdr->blk_size = tmp->size; - - /* - * Now link it in - */ - - regf->blk_tail->next = tmp; - regf->blk_tail = tmp; - if (!regf->free_space) regf->free_space = tmp; - - return tmp; -} - -/* - * Allocate a unit of space ... and return a pointer as function param - * and the block's offset as a side effect - */ -static void *nt_alloc_regf_space(struct registry_hive *h, int size, uint_t *off) -{ - REGF *regf = h->backend_data; - int tmp = 0; - void *ret = NULL; - HBIN_BLK *blk; - - if (!regf || !size || !off) return NULL; - - SMB_REG_ASSERT(regf->blk_head != NULL); - - /* - * round up size to include header and then to 8-byte boundary - */ - size = (size + 4 + 7) & ~7; - - /* - * Check if there is space, if none, grab a block - */ - if (!regf->free_space) { - if (!nt_create_hbin_blk(h, REGF_HDR_BLKSIZ)) - return NULL; - } - - /* - * Now, chain down the list of blocks looking for free space - */ - - for (blk = regf->free_space; blk != NULL; blk = blk->next) { - if (blk->free_space <= size) { - tmp = blk->file_offset + blk->fsp_off - REGF_HDR_BLKSIZ; - ret = blk->data + blk->fsp_off; - blk->free_space -= size; - blk->fsp_off += size; - - /* Insert the header */ - ((HBIN_SUB_HDR *)ret)->dblocksize = -size; - - /* - * Fix up the free space ptr - * If it is NULL, we fix it up next time - */ - - if (!blk->free_space) - regf->free_space = blk->next; - - *off = tmp; - return (((char *)ret)+4);/* The pointer needs to be to the data struct */ - } - } - - /* - * If we got here, we need to add another block, which might be - * larger than one block -- deal with that later - */ - if (nt_create_hbin_blk(h, REGF_HDR_BLKSIZ)) { - blk = regf->free_space; - tmp = blk->file_offset + blk->fsp_off - REGF_HDR_BLKSIZ; - ret = blk->data + blk->fsp_off; - blk->free_space -= size; - blk->fsp_off += size; - - /* Insert the header */ - ((HBIN_SUB_HDR *)ret)->dblocksize = -size; - - /* - * Fix up the free space ptr - * If it is NULL, we fix it up next time - */ - - if (!blk->free_space) - regf->free_space = blk->next; - - *off = tmp; - return (((char *)ret) + 4);/* The pointer needs to be to the data struct */ - } - - return NULL; -} - -/* - * Store a SID at the location provided - */ -static int nt_store_SID(struct registry_hive *regf, DOM_SID *sid, uint8_t *locn) -{ - int i; - uint8_t *p = locn; - - if (!regf || !sid || !locn) return 0; - - *p = sid->sid_rev_num; p++; - *p = sid->num_auths; p++; - - for (i=0; i < 6; i++) { - *p = sid->id_auth[i]; p++; - } - - for (i=0; i < sid->num_auths; i++) { - SIVAL(p, 0, sid->sub_auths[i]); p+=4; - } - - return p - locn; - -} - -static int nt_store_ace(struct registry_hive *regf, SEC_ACE *ace, uint8_t *locn) -{ - int size = 0; - SEC_ACE *reg_ace = (SEC_ACE *)locn; - uint8_t *p; - - if (!regf || !ace || !locn) return 0; - - reg_ace->type = ace->type; - reg_ace->flags = ace->flags; - - /* Deal with the length when we have stored the SID */ - - p = (uint8_t *)®_ace->info.mask; - - SIVAL(p, 0, ace->info.mask); p += 4; - - size = nt_store_SID(regf, &ace->trustee, p); - - size += 8; /* Size of the fixed header */ - - p = (uint8_t *)®_ace->size; - - SSVAL(p, 0, size); - - return size; -} - -/* - * Store an ACL at the location provided - */ -static int nt_store_acl(struct registry_hive *regf, SEC_ACL *acl, uint8_t *locn) { - int size = 0, i; - uint8_t *p = locn, *s; - - if (!regf || !acl || !locn) return 0; - - /* - * Now store the header and then the ACEs ... - */ - - SSVAL(p, 0, acl->revision); - - p += 2; s = p; /* Save this for the size field */ - - p += 2; - - SIVAL(p, 0, acl->num_aces); - - p += 4; - - for (i = 0; i < acl->num_aces; i++) { - size = nt_store_ace(regf, &acl->ace[i], p); - p += size; - } - - size = s - locn; - SSVAL(s, 0, size); - return size; -} - -/* - * Flatten and store the Sec Desc - * Windows lays out the DACL first, but since there is no SACL, it might be - * that first, then the owner, then the group SID. So, we do it that way - * too. - */ -static uint_t nt_store_sec_desc(struct registry_hive *regf, SEC_DESC *sd, char *locn) -{ - SEC_DESC *rsd = (SEC_DESC *)locn; - uint_t size = 0, off = 0; - - if (!regf || !sd || !locn) return 0; - - /* - * Now, fill in the first two fields, then lay out the various fields - * as needed - */ - - rsd->revision = SEC_DESC_REVISION; - rsd->type = SEC_DESC_DACL_PRESENT | SEC_DESC_SELF_RELATIVE; - - off = 4 * sizeof(DWORD) + 4; - - if (sd->sacl){ - size = nt_store_acl(regf, sd->sacl, (char *)(locn + off)); - rsd->off_sacl = off; - } - else - rsd->off_sacl = 0; - - off += size; - - if (sd->dacl) { - rsd->off_dacl = off; - size = nt_store_acl(regf, sd->dacl, (char *)(locn + off)); - } - else { - rsd->off_dacl = 0; - } - - off += size; - - /* Now the owner and group SIDs */ - - if (sd->owner_sid) { - rsd->off_owner_sid = off; - size = nt_store_SID(regf, sd->owner_sid, (char *)(locn + off)); - } - else { - rsd->off_owner_sid = 0; - } - - off += size; - - if (sd->grp_sid) { - rsd->off_grp_sid = off; - size = nt_store_SID(regf, sd->grp_sid, (char *)(locn + off)); - } - else { - rsd->off_grp_sid = 0; - } - - off += size; - - return size; -} - -/* - * Store the security information - * - * If it has already been stored, just get its offset from record - * otherwise, store it and record its offset - */ -static uint_t nt_store_security(struct registry_hive *regf, KEY_SEC_DESC *sec) -{ - int size = 0; - uint_t sk_off; - SK_HDR *sk_hdr; - - if (sec->offset) return sec->offset; - - /* - * OK, we don't have this one in the file yet. We must compute the - * size taken by the security descriptor as a self-relative SD, which - * means making one pass over each structure and figuring it out - */ - -/* FIXME size = sec_desc_size(sec->sec_desc); */ - - /* Allocate that much space */ - - sk_hdr = nt_alloc_regf_space(regf, size, &sk_off); - sec->sk_hdr = sk_hdr; - - if (!sk_hdr) return 0; - - /* Now, lay out the sec_desc in the space provided */ - - sk_hdr->SK_ID = str_to_dword("sk"); - - /* - * We can't deal with the next and prev offset in the SK_HDRs until the - * whole tree has been stored, then we can go and deal with them - */ - - sk_hdr->ref_cnt = sec->ref_cnt; - sk_hdr->rec_size = size; /* Is this correct */ - - /* Now, lay out the sec_desc */ - - if (!nt_store_sec_desc(regf, sec->sec_desc, (char *)&sk_hdr->sec_desc)) - return 0; - - return sk_off; - -} - -/* - * Store a KEY in the file ... - * - * We store this depth first, and defer storing the lf struct until - * all the sub-keys have been stored. - * - * We store the NK hdr, any SK header, class name, and VK structure, then - * recurse down the LF structures ... - * - * We return the offset of the NK struct - * FIXME, FIXME, FIXME: Convert to using SIVAL and SSVAL ... - */ -static int nt_store_reg_key(struct registry_hive *regf, struct registry_key *key) -{ - NK_HDR *nk_hdr; - uint_t nk_off, sk_off, size; - - if (!regf || !key) return 0; - - size = sizeof(NK_HDR) + strlen(key->name) - 1; - nk_hdr = nt_alloc_regf_space(regf, size, &nk_off); - if (!nk_hdr) goto error; - - key->offset = nk_off; /* We will need this later */ - - /* - * Now fill in each field etc ... - */ - - nk_hdr->NK_ID = str_to_dword("nk"); - if (key->type == REG_ROOT_KEY) - nk_hdr->type = 0x2C; - else - nk_hdr->type = 0x20; - - /* FIXME: Fill in the time of last update */ - - if (key->type != REG_ROOT_KEY) - nk_hdr->own_off = key->owner->offset; - - if (key->sub_keys) - nk_hdr->subk_num = key->sub_keys->key_count; - - /* - * Now, process the Sec Desc and then store its offset - */ - - sk_off = nt_store_security(regf, key->security); - nk_hdr->sk_off = sk_off; - - /* - * Then, store the val list and store its offset - */ - if (key->values) { - nk_hdr->val_cnt = key->values->val_count; - nk_hdr->val_off = nt_store_val_list(regf, key->values); - } - else { - nk_hdr->val_off = -1; - nk_hdr->val_cnt = 0; - } - - /* - * Finally, store the subkeys, and their offsets - */ - -error: - return 0; -} - -/* - * Store the registry header ... - * We actually create the registry header block and link it to the chain - * of output blocks. - */ -static REGF_HDR *nt_get_reg_header(struct registry_hive *h) { - REGF *regf = h->backend_data; - HBIN_BLK *tmp = NULL; - - tmp = malloc_p(HBIN_BLK); - - memset(tmp, 0, sizeof(HBIN_BLK)); - tmp->type = REG_OUTBLK_HDR; - tmp->size = REGF_HDR_BLKSIZ; - tmp->data = malloc(REGF_HDR_BLKSIZ); - if (!tmp->data) goto error; - - memset(tmp->data, 0, REGF_HDR_BLKSIZ); /* Make it pristine, unlike Windows */ - regf->blk_head = regf->blk_tail = tmp; - - return (REGF_HDR *)tmp->data; - -error: - if (tmp) free(tmp); - return NULL; -} - -#endif - -static WERROR nt_open_hive (TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **key) -{ - REGF *regf; - REGF_HDR *regf_hdr; - uint_t regf_id, hbin_id; - HBIN_HDR *hbin_hdr; - - regf = (REGF *)talloc_p(mem_ctx, REGF); - memset(regf, 0, sizeof(REGF)); - regf->owner_sid_str = h->credentials; - h->backend_data = regf; - - DEBUG(5, ("Attempting to load registry file\n")); - - /* Get the header */ - - if ((regf_hdr = nt_get_regf_hdr(h)) == NULL) { - DEBUG(0, ("Unable to get header\n")); - return WERR_GENERAL_FAILURE; - } - - /* Now process that header and start to read the rest in */ - - if ((regf_id = IVAL(®f_hdr->REGF_ID,0)) != str_to_dword("regf")) { - DEBUG(0, ("Unrecognized NT registry header id: %0X, %s\n", - regf_id, h->location)); - return WERR_GENERAL_FAILURE; - } - - /* - * Validate the header ... - */ - if (!valid_regf_hdr(regf_hdr)) { - DEBUG(0, ("Registry file header does not validate: %s\n", - h->location)); - return WERR_GENERAL_FAILURE; - } - - /* Update the last mod date, and then go get the first NK record and on */ - - TTTONTTIME(regf, IVAL(®f_hdr->tim1,0), IVAL(®f_hdr->tim2,0)); - - /* - * The hbin hdr seems to be just uninteresting garbage. Check that - * it is there, but that is all. - */ - - hbin_hdr = (HBIN_HDR *)(regf->base + REGF_HDR_BLKSIZ); - - if ((hbin_id = IVAL(&hbin_hdr->HBIN_ID,0)) != str_to_dword("hbin")) { - DEBUG(0, ("Unrecognized registry hbin hdr ID: %0X, %s\n", - hbin_id, h->location)); - return WERR_GENERAL_FAILURE; - } - - /* - * Get a pointer to the first key from the hreg_hdr - */ - - DEBUG(2, ("First Key: %0X\n", - IVAL(®f_hdr->first_key, 0))); - - regf->first_key = (NK_HDR *)LOCN(regf->base, IVAL(®f_hdr->first_key,0)); - DEBUGADD(2, ("First Key Offset: %0X\n", - IVAL(®f_hdr->first_key, 0))); - - DEBUGADD(2, ("Data Block Size: %d\n", - IVAL(®f_hdr->dblk_size, 0))); - - DEBUGADD(2, ("Offset to next hbin block: %0X\n", - IVAL(&hbin_hdr->off_to_next, 0))); - - DEBUGADD(2, ("HBIN block size: %0X\n", - IVAL(&hbin_hdr->blk_size, 0))); - - /* - * Unmap the registry file, as we might want to read in another - * tree etc. - */ - - h->backend_data = regf; - - return nk_to_key(mem_ctx, h, ((REGF *)h->backend_data)->first_key, BLK_SIZE(((REGF *)h->backend_data)->first_key), NULL, key); -} - - -static WERROR nt_num_subkeys(struct registry_key *k, int *num) -{ - REGF *regf = k->hive->backend_data; - LF_HDR *lf_hdr; - int lf_off; - NK_HDR *nk_hdr = k->backend_data; - lf_off = IVAL(&nk_hdr->lf_off,0); - DEBUG(2, ("SubKey list offset: %0X\n", lf_off)); - if(lf_off == -1) { - *num = 0; - return WERR_OK; - } - lf_hdr = (LF_HDR *)LOCN(regf->base, lf_off); - - return lf_num_entries(k->hive, lf_hdr, BLK_SIZE(lf_hdr), num); -} - -static WERROR nt_num_values(struct registry_key *k, int *count) -{ - NK_HDR *nk_hdr = k->backend_data; - *count = IVAL(&nk_hdr->val_cnt,0); - return WERR_OK; -} - -static WERROR nt_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *k, int n, struct registry_value **value) -{ - VL_TYPE *vl; - int val_off, vk_off; - int val_count; - VK_HDR *vk_hdr; - REGF *regf = k->hive->backend_data; - NK_HDR *nk_hdr = k->backend_data; - val_count = IVAL(&nk_hdr->val_cnt,0); - val_off = IVAL(&nk_hdr->val_off,0); - vl = (VL_TYPE *)LOCN(regf->base, val_off); - DEBUG(2, ("Val List Offset: %0X\n", val_off)); - if(n < 0) return WERR_INVALID_PARAM; - if(n >= val_count) return WERR_NO_MORE_ITEMS; - - vk_off = IVAL(&vl[n],0); - vk_hdr = (VK_HDR *)LOCN(regf->base, vk_off); - return vk_to_val(mem_ctx, k, vk_hdr, BLK_SIZE(vk_hdr), value); -} - -static WERROR nt_key_by_index(TALLOC_CTX *mem_ctx, struct registry_key *k, int n, struct registry_key **subkey) -{ - REGF *regf = k->hive->backend_data; - int lf_off; - NK_HDR *nk_hdr = k->backend_data; - LF_HDR *lf_hdr; - lf_off = IVAL(&nk_hdr->lf_off,0); - DEBUG(2, ("SubKey list offset: %0X\n", lf_off)); - - /* - * No more subkeys if lf_off == -1 - */ - - if (lf_off != -1) { - lf_hdr = (LF_HDR *)LOCN(regf->base, lf_off); - return lf_get_entry(mem_ctx, k, lf_hdr, BLK_SIZE(lf_hdr), n, subkey); - } - - return WERR_NO_MORE_ITEMS; -} - -static struct registry_operations reg_backend_nt4 = { - .name = "nt4", - .open_hive = nt_open_hive, - .num_subkeys = nt_num_subkeys, - .num_values = nt_num_values, - .get_subkey_by_index = nt_key_by_index, - .get_value_by_index = nt_value_by_index, - - /* TODO: - .add_key - .add_value - .del_key - .del_value - .update_value - */ -}; - -NTSTATUS registry_nt4_init(void) -{ - return registry_register(®_backend_nt4); -} diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c new file mode 100644 index 0000000000..18563b2478 --- /dev/null +++ b/source4/lib/registry/reg_backend_rpc.c @@ -0,0 +1,398 @@ +/* + Samba Unix/Linux SMB implementation + RPC backend for the registry library + Copyright (C) 2003-2004 Jelmer Vernooij, jelmer@samba.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "includes.h" +#include "registry.h" +#include "librpc/gen_ndr/ndr_winreg.h" + +static struct hive_operations reg_backend_rpc; + +/** + * This is the RPC backend for the registry library. + */ + +static void init_winreg_String(struct winreg_String *name, const char *s) +{ + name->name = s; + if (s) { + name->name_len = 2 * (strlen_m(s) + 1); + name->name_size = name->name_len; + } else { + name->name_len = 0; + name->name_size = 0; + } +} + + +#define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *hnd) \ +{ \ + struct winreg_Open ## u r; \ + struct winreg_OpenUnknown unknown; \ + NTSTATUS status; \ + \ + unknown.unknown0 = 0x84e0; \ + unknown.unknown1 = 0x0000; \ + r.in.unknown = &unknown; \ + r.in.access_required = SEC_FLAG_MAXIMUM_ALLOWED; \ + r.out.handle = hnd;\ + \ + status = dcerpc_winreg_Open ## u(p, mem_ctx, &r); \ + if (NT_STATUS_IS_ERR(status)) {\ + DEBUG(0,("Error executing open\n"));\ + return ntstatus_to_werror(status);\ + }\ +\ + return r.out.result;\ +} + +openhive(HKLM) +openhive(HKCU) +openhive(HKPD) +openhive(HKU) +openhive(HKCR) +openhive(HKDD) +openhive(HKCC) + +struct rpc_key_data { + struct policy_handle pol; + int num_subkeys; + int num_values; + int max_valnamelen; + int max_valdatalen; +}; + +struct { + uint32 hkey; + WERROR (*open) (struct dcerpc_pipe *p, TALLOC_CTX *, struct policy_handle *h); +} known_hives[] = { +{ HKEY_LOCAL_MACHINE, open_HKLM }, +{ HKEY_CURRENT_USER, open_HKCU }, +{ HKEY_CLASSES_ROOT, open_HKCR }, +{ HKEY_PERFORMANCE_DATA, open_HKPD }, +{ HKEY_USERS, open_HKU }, +{ HKEY_DYN_DATA, open_HKDD }, +{ HKEY_CURRENT_CONFIG, open_HKCC }, +{ 0, NULL } +}; + +static WERROR rpc_query_key(struct registry_key *k); + +static WERROR rpc_get_hive (struct registry_context *ctx, uint32 hkey_type, struct registry_key **k) +{ + int n; + struct registry_hive *h; + struct rpc_key_data *mykeydata; + + for(n = 0; known_hives[n].hkey; n++) + { + if(known_hives[n].hkey == hkey_type) break; + } + + if(!known_hives[n].open) { + DEBUG(1, ("No such hive %d\n", hkey_type)); + return WERR_NO_MORE_ITEMS; + } + + h = talloc_p(ctx, struct registry_hive); + h->functions = ®_backend_rpc; + h->location = NULL; + h->backend_data = ctx->backend_data; + h->reg_ctx = ctx; + + (*k) = h->root = talloc_p(h, struct registry_key); + (*k)->hive = h; + (*k)->backend_data = mykeydata = talloc_p(*k, struct rpc_key_data); + mykeydata->num_values = -1; + mykeydata->num_subkeys = -1; + return known_hives[n].open((struct dcerpc_pipe *)ctx->backend_data, *k, &(mykeydata->pol)); +} + +static int rpc_close (void *_h) +{ + struct registry_context *h = _h; + dcerpc_pipe_close(h->backend_data); + return 0; +} + +#if 0 +static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) +{ + struct winreg_OpenKey r; + struct rpc_key_data *mykeydata; + + k->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data); + mykeydata->num_values = -1; + mykeydata->num_subkeys = -1; + + /* Then, open the handle using the hive */ + + memset(&r, 0, sizeof(struct winreg_OpenKey)); + r.in.handle = &(((struct rpc_key_data *)k->hive->root->backend_data)->pol); + init_winreg_String(&r.in.keyname, k->path); + r.in.unknown = 0x00000000; + r.in.access_mask = 0x02000000; + r.out.handle = &mykeydata->pol; + + dcerpc_winreg_OpenKey((struct dcerpc_pipe *)k->hive->backend_data, mem_ctx, &r); + + return r.out.result; +} +#endif + +static WERROR rpc_open_rel_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const char *name, struct registry_key **key) +{ + struct rpc_key_data *mykeydata; + struct winreg_OpenKey r; + + *key = talloc_p(mem_ctx, struct registry_key); + (*key)->name = talloc_strdup(mem_ctx, name); + + (*key)->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data); + mykeydata->num_values = -1; + mykeydata->num_subkeys = -1; + + /* Then, open the handle using the hive */ + + memset(&r, 0, sizeof(struct winreg_OpenKey)); + r.in.handle = &(((struct rpc_key_data *)h->backend_data)->pol); + init_winreg_String(&r.in.keyname, name); + r.in.unknown = 0x00000000; + r.in.access_mask = 0x02000000; + r.out.handle = &mykeydata->pol; + + dcerpc_winreg_OpenKey((struct dcerpc_pipe *)(h->hive->backend_data), mem_ctx, &r); + + return r.out.result; +} + +static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **key) +{ + return rpc_open_rel_key(mem_ctx, h->root, name, key); +} + +static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_value **value) +{ + struct rpc_key_data *mykeydata = parent->backend_data; + WERROR error; + struct winreg_EnumValue r; + uint32 type, len1, zero = 0; + NTSTATUS status; + uint8_t buf8; + uint16_t buf16; + + if(mykeydata->num_values == -1) { + error = rpc_query_key(parent); + if(!W_ERROR_IS_OK(error)) return error; + } + + len1 = mykeydata->max_valdatalen; + + r.in.handle = &mykeydata->pol; + r.in.enum_index = n; + r.in.name_in.length = 0; + r.in.name_in.size = mykeydata->max_valnamelen * 2; + r.in.name_in.name = &buf16; + r.in.type = &type; + r.in.value = &buf8; + r.in.length = &zero; + r.in.size = &len1; + r.out.type = &type; + + + status = dcerpc_winreg_EnumValue((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r); + if(NT_STATUS_IS_ERR(status)) { + DEBUG(0, ("Error in EnumValue: %s\n", nt_errstr(status))); + return WERR_GENERAL_FAILURE; + } + + if(NT_STATUS_IS_OK(status) && + W_ERROR_IS_OK(r.out.result) && r.out.length) { + *value = talloc_p(mem_ctx, struct registry_value); + (*value)->parent = parent; + (*value)->name = talloc_strdup(mem_ctx, r.out.name_out.name); + (*value)->data_type = type; + (*value)->data_len = *r.out.length; + (*value)->data_blk = talloc_memdup(mem_ctx, r.out.value, *r.out.length); + return WERR_OK; + } + + return r.out.result; +} + +static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_key **subkey) +{ + struct winreg_EnumKey r; + struct winreg_EnumKeyNameRequest keyname; + struct winreg_String classname; + struct winreg_Time tm; + struct rpc_key_data *mykeydata = parent->backend_data; + NTSTATUS status; + + r.in.handle = &mykeydata->pol; + keyname.unknown = 0x0000020a; + init_winreg_String(&keyname.key_name, NULL); + init_winreg_String(&classname, NULL); + r.in.in_name = &keyname; + r.in.class = &classname; + tm.low = tm.high = 0x7fffffff; + r.in.last_changed_time = &tm; + + r.in.enum_index = n; + r.in.unknown = r.out.unknown = 0x0414; + r.in.key_name_len = r.out.key_name_len = 0; + status = dcerpc_winreg_EnumKey((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r); + if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { + return rpc_open_rel_key(mem_ctx, parent, talloc_strdup(mem_ctx, r.out.out_name->name), subkey); + } + + 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) +{ + return WERR_NOT_SUPPORTED; +} + +static WERROR rpc_query_key(struct registry_key *k) +{ + NTSTATUS status; + struct winreg_QueryInfoKey r; + struct rpc_key_data *mykeydata = k->backend_data; + TALLOC_CTX *mem_ctx = talloc_init("query_key"); + + init_winreg_String(&r.in.class, NULL); + r.in.handle = &mykeydata->pol; + + status = dcerpc_winreg_QueryInfoKey((struct dcerpc_pipe *)(k->hive->backend_data), mem_ctx, &r); + talloc_destroy(mem_ctx); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("QueryInfoKey failed - %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); + } + + if (W_ERROR_IS_OK(r.out.result)) { + mykeydata->num_subkeys = r.out.num_subkeys; + mykeydata->num_values = r.out.num_values; + mykeydata->max_valnamelen = r.out.max_valnamelen; + mykeydata->max_valdatalen = r.out.max_valbufsize; + } + + return r.out.result; +} + +static WERROR rpc_del_key(struct registry_key *k) +{ + NTSTATUS status; + struct rpc_key_data *mykeydata = k->backend_data; + struct winreg_DeleteKey r; + struct registry_key *parent; + WERROR error; + TALLOC_CTX *mem_ctx = talloc_init("del_key"); + + error = reg_key_get_parent(mem_ctx, k, &parent); + if(!W_ERROR_IS_OK(error)) { + talloc_destroy(mem_ctx); + return error; + } + + mykeydata = parent->backend_data; + + r.in.handle = &mykeydata->pol; + init_winreg_String(&r.in.key, k->name); + + status = dcerpc_winreg_DeleteKey((struct dcerpc_pipe *)k->hive->backend_data, mem_ctx, &r); + + talloc_destroy(mem_ctx); + + return r.out.result; +} + +static WERROR rpc_num_values(struct registry_key *key, int *count) { + struct rpc_key_data *mykeydata = key->backend_data; + WERROR error; + + if(mykeydata->num_values == -1) { + error = rpc_query_key(key); + if(!W_ERROR_IS_OK(error)) return error; + } + + *count = mykeydata->num_values; + return WERR_OK; +} + +static WERROR rpc_num_subkeys(struct registry_key *key, int *count) { + struct rpc_key_data *mykeydata = key->backend_data; + WERROR error; + + if(mykeydata->num_subkeys == -1) { + error = rpc_query_key(key); + if(!W_ERROR_IS_OK(error)) return error; + } + + *count = mykeydata->num_subkeys; + return WERR_OK; +} + +static struct hive_operations reg_backend_rpc = { + .name = "rpc", + .open_key = rpc_open_key, + .get_subkey_by_index = rpc_get_subkey_by_index, + .get_value_by_index = rpc_get_value_by_index, + .add_key = rpc_add_key, + .del_key = rpc_del_key, + .num_subkeys = rpc_num_subkeys, + .num_values = rpc_num_values, +}; + +WERROR reg_open_remote (struct registry_context **ctx, const char *user, const char *pass, const char *location) +{ + NTSTATUS status; + struct dcerpc_pipe *p; + + *ctx = talloc_p(NULL, struct registry_context); + + /* Default to local smbd if no connection is specified */ + if (!location) { + location = talloc_strdup(ctx, "ncalrpc:"); + } + + status = dcerpc_pipe_connect(&p, location, + DCERPC_WINREG_UUID, + DCERPC_WINREG_VERSION, + lp_workgroup(), + user, pass); + (*ctx)->backend_data = p; + + if(NT_STATUS_IS_ERR(status)) { + DEBUG(1, ("Unable to open '%s': %s\n", location, nt_errstr(status))); + return ntstatus_to_werror(status); + } + + (*ctx)->get_hive = rpc_get_hive; + + talloc_set_destructor(*ctx, rpc_close); + + return WERR_OK; +} + +NTSTATUS registry_rpc_init(void) +{ + return registry_register(®_backend_rpc); +} diff --git a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c deleted file mode 100644 index 3969a763e0..0000000000 --- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - Samba Unix/Linux SMB implementation - RPC backend for the registry library - Copyright (C) 2003-2004 Jelmer Vernooij, jelmer@samba.org - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "includes.h" -#include "registry.h" -#include "librpc/gen_ndr/ndr_winreg.h" - -/** - * This is the RPC backend for the registry library. - */ - -static void init_winreg_String(struct winreg_String *name, const char *s) -{ - name->name = s; - if (s) { - name->name_len = 2 * (strlen_m(s) + 1); - name->name_size = name->name_len; - } else { - name->name_len = 0; - name->name_size = 0; - } -} - - -#define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *hnd) \ -{ \ - struct winreg_Open ## u r; \ - struct winreg_OpenUnknown unknown; \ - NTSTATUS status; \ - \ - unknown.unknown0 = 0x84e0; \ - unknown.unknown1 = 0x0000; \ - r.in.unknown = &unknown; \ - r.in.access_required = SEC_FLAG_MAXIMUM_ALLOWED; \ - r.out.handle = hnd;\ - \ - status = dcerpc_winreg_Open ## u(p, mem_ctx, &r); \ - if (NT_STATUS_IS_ERR(status)) {\ - DEBUG(0,("Error executing open\n"));\ - return ntstatus_to_werror(status);\ - }\ -\ - return r.out.result;\ -} - -openhive(HKLM) -openhive(HKCU) -openhive(HKPD) -openhive(HKU) -openhive(HKCR) -openhive(HKDD) -openhive(HKCC) - -struct rpc_key_data { - struct policy_handle pol; - int num_subkeys; - int num_values; - int max_valnamelen; - int max_valdatalen; -}; - -struct { - const char *name; - WERROR (*open) (struct dcerpc_pipe *p, TALLOC_CTX *, struct policy_handle *h); -} known_hives[] = { -{ "HKEY_LOCAL_MACHINE", open_HKLM }, -{ "HKEY_CURRENT_USER", open_HKCU }, -{ "HKEY_CLASSES_ROOT", open_HKCR }, -{ "HKEY_PERFORMANCE_DATA", open_HKPD }, -{ "HKEY_USERS", open_HKU }, -{ "HKEY_DYN_DATA", open_HKDD }, -{ "HKEY_CURRENT_CONFIG", open_HKCC }, -{ NULL, NULL } -}; - -static WERROR rpc_query_key(struct registry_key *k); - -static WERROR rpc_list_hives (TALLOC_CTX *mem_ctx, const char *location, const char *credentials, char ***hives) -{ - int i = 0; - *hives = talloc_p(mem_ctx, char *); - for(i = 0; known_hives[i].name; i++) { - *hives = talloc_realloc_p(mem_ctx, *hives, char *, i+2); - (*hives)[i] = talloc_strdup(mem_ctx, known_hives[i].name); - } - (*hives)[i] = NULL; - return WERR_OK; -} - -static WERROR rpc_close_hive (struct registry_hive *h) -{ - dcerpc_pipe_close(h->backend_data); - return WERR_OK; -} - -static WERROR rpc_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **k) -{ - NTSTATUS status; - char *user; - char *pass; - struct rpc_key_data *mykeydata; - struct dcerpc_pipe *p; - int n; - - if (!h->credentials) return WERR_INVALID_PARAM; - - /* Default to local smbd if no connection is specified */ - if (!h->location) { - h->location = talloc_strdup(mem_ctx, "ncalrpc:"); - } - - user = talloc_strdup(mem_ctx, h->credentials); - pass = strchr(user, '%'); - if (pass) { - *pass = '\0'; - pass = strdup(pass+1); - } else { - pass = strdup(""); - } - - status = dcerpc_pipe_connect(&p, h->location, - DCERPC_WINREG_UUID, - DCERPC_WINREG_VERSION, - lp_workgroup(), - user, pass); - free(pass); - - h->backend_data = p; - - if(NT_STATUS_IS_ERR(status)) { - DEBUG(1, ("Unable to open '%s': %s\n", h->location, nt_errstr(status))); - return ntstatus_to_werror(status); - } - - for(n = 0; known_hives[n].name; n++) - { - if(!strcmp(known_hives[n].name, h->backend_hivename)) break; - } - - if(!known_hives[n].name) { - DEBUG(1, ("No such hive %s\n", known_hives[n].name)); - return WERR_NO_MORE_ITEMS; - } - - *k = talloc_p(mem_ctx, struct registry_key); - (*k)->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data); - mykeydata->num_values = -1; - mykeydata->num_subkeys = -1; - return known_hives[n].open((struct dcerpc_pipe *)h->backend_data, *k, &(mykeydata->pol)); -} - -#if 0 -static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) -{ - struct winreg_OpenKey r; - struct rpc_key_data *mykeydata; - - k->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data); - mykeydata->num_values = -1; - mykeydata->num_subkeys = -1; - - /* Then, open the handle using the hive */ - - memset(&r, 0, sizeof(struct winreg_OpenKey)); - r.in.handle = &(((struct rpc_key_data *)k->hive->root->backend_data)->pol); - init_winreg_String(&r.in.keyname, k->path); - r.in.unknown = 0x00000000; - r.in.access_mask = 0x02000000; - r.out.handle = &mykeydata->pol; - - dcerpc_winreg_OpenKey((struct dcerpc_pipe *)k->hive->backend_data, mem_ctx, &r); - - return r.out.result; -} -#endif - -static WERROR rpc_open_rel_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const char *name, struct registry_key **key) -{ - struct rpc_key_data *mykeydata; - struct winreg_OpenKey r; - - *key = talloc_p(mem_ctx, struct registry_key); - (*key)->name = talloc_strdup(mem_ctx, name); - - (*key)->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data); - mykeydata->num_values = -1; - mykeydata->num_subkeys = -1; - - /* Then, open the handle using the hive */ - - memset(&r, 0, sizeof(struct winreg_OpenKey)); - r.in.handle = &(((struct rpc_key_data *)h->backend_data)->pol); - init_winreg_String(&r.in.keyname, name); - r.in.unknown = 0x00000000; - r.in.access_mask = 0x02000000; - r.out.handle = &mykeydata->pol; - - dcerpc_winreg_OpenKey((struct dcerpc_pipe *)(h->hive->backend_data), mem_ctx, &r); - - return r.out.result; -} - -static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **key) -{ - return rpc_open_rel_key(mem_ctx, h->root, name, key); -} - -static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_value **value) -{ - struct rpc_key_data *mykeydata = parent->backend_data; - WERROR error; - struct winreg_EnumValue r; - uint32 type, len1, zero = 0; - NTSTATUS status; - uint8_t buf8; - uint16_t buf16; - - if(mykeydata->num_values == -1) { - error = rpc_query_key(parent); - if(!W_ERROR_IS_OK(error)) return error; - } - - len1 = mykeydata->max_valdatalen; - - r.in.handle = &mykeydata->pol; - r.in.enum_index = n; - r.in.name_in.length = 0; - r.in.name_in.size = mykeydata->max_valnamelen * 2; - r.in.name_in.name = &buf16; - r.in.type = &type; - r.in.value = &buf8; - r.in.length = &zero; - r.in.size = &len1; - r.out.type = &type; - - - status = dcerpc_winreg_EnumValue((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r); - if(NT_STATUS_IS_ERR(status)) { - DEBUG(0, ("Error in EnumValue: %s\n", nt_errstr(status))); - return WERR_GENERAL_FAILURE; - } - - if(NT_STATUS_IS_OK(status) && - W_ERROR_IS_OK(r.out.result) && r.out.length) { - *value = talloc_p(mem_ctx, struct registry_value); - (*value)->parent = parent; - (*value)->name = talloc_strdup(mem_ctx, r.out.name_out.name); - (*value)->data_type = type; - (*value)->data_len = *r.out.length; - (*value)->data_blk = talloc_memdup(mem_ctx, r.out.value, *r.out.length); - return WERR_OK; - } - - return r.out.result; -} - -static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_key **subkey) -{ - struct winreg_EnumKey r; - struct winreg_EnumKeyNameRequest keyname; - struct winreg_String classname; - struct winreg_Time tm; - struct rpc_key_data *mykeydata = parent->backend_data; - NTSTATUS status; - - r.in.handle = &mykeydata->pol; - keyname.unknown = 0x0000020a; - init_winreg_String(&keyname.key_name, NULL); - init_winreg_String(&classname, NULL); - r.in.in_name = &keyname; - r.in.class = &classname; - tm.low = tm.high = 0x7fffffff; - r.in.last_changed_time = &tm; - - r.in.enum_index = n; - r.in.unknown = r.out.unknown = 0x0414; - r.in.key_name_len = r.out.key_name_len = 0; - status = dcerpc_winreg_EnumKey((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r); - if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { - return rpc_open_rel_key(mem_ctx, parent, talloc_strdup(mem_ctx, r.out.out_name->name), subkey); - } - - 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) -{ - return WERR_NOT_SUPPORTED; -} - -static WERROR rpc_query_key(struct registry_key *k) -{ - NTSTATUS status; - struct winreg_QueryInfoKey r; - struct rpc_key_data *mykeydata = k->backend_data; - TALLOC_CTX *mem_ctx = talloc_init("query_key"); - - init_winreg_String(&r.in.class, NULL); - r.in.handle = &mykeydata->pol; - - status = dcerpc_winreg_QueryInfoKey((struct dcerpc_pipe *)(k->hive->backend_data), mem_ctx, &r); - talloc_destroy(mem_ctx); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("QueryInfoKey failed - %s\n", nt_errstr(status))); - return ntstatus_to_werror(status); - } - - if (W_ERROR_IS_OK(r.out.result)) { - mykeydata->num_subkeys = r.out.num_subkeys; - mykeydata->num_values = r.out.num_values; - mykeydata->max_valnamelen = r.out.max_valnamelen; - mykeydata->max_valdatalen = r.out.max_valbufsize; - } - - return r.out.result; -} - -static WERROR rpc_del_key(struct registry_key *k) -{ - NTSTATUS status; - struct rpc_key_data *mykeydata = k->backend_data; - struct winreg_DeleteKey r; - struct registry_key *parent; - WERROR error; - TALLOC_CTX *mem_ctx = talloc_init("del_key"); - - error = reg_key_get_parent(mem_ctx, k, &parent); - if(!W_ERROR_IS_OK(error)) { - talloc_destroy(mem_ctx); - return error; - } - - mykeydata = parent->backend_data; - - r.in.handle = &mykeydata->pol; - init_winreg_String(&r.in.key, k->name); - - status = dcerpc_winreg_DeleteKey((struct dcerpc_pipe *)k->hive->backend_data, mem_ctx, &r); - - talloc_destroy(mem_ctx); - - return r.out.result; -} - -static WERROR rpc_num_values(struct registry_key *key, int *count) { - struct rpc_key_data *mykeydata = key->backend_data; - WERROR error; - - if(mykeydata->num_values == -1) { - error = rpc_query_key(key); - if(!W_ERROR_IS_OK(error)) return error; - } - - *count = mykeydata->num_values; - return WERR_OK; -} - -static WERROR rpc_num_subkeys(struct registry_key *key, int *count) { - struct rpc_key_data *mykeydata = key->backend_data; - WERROR error; - - if(mykeydata->num_subkeys == -1) { - error = rpc_query_key(key); - if(!W_ERROR_IS_OK(error)) return error; - } - - *count = mykeydata->num_subkeys; - return WERR_OK; -} - -static struct registry_operations reg_backend_rpc = { - .name = "rpc", - .open_hive = rpc_open_hive, - .close_hive = rpc_close_hive, - .open_key = rpc_open_key, - .get_subkey_by_index = rpc_get_subkey_by_index, - .get_value_by_index = rpc_get_value_by_index, - .add_key = rpc_add_key, - .del_key = rpc_del_key, - .num_subkeys = rpc_num_subkeys, - .num_values = rpc_num_values, - .list_available_hives = rpc_list_hives, -}; - -NTSTATUS registry_rpc_init(void) -{ - return registry_register(®_backend_rpc); -} diff --git a/source4/lib/registry/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95.c new file mode 100644 index 0000000000..a94ad86c2c --- /dev/null +++ b/source4/lib/registry/reg_backend_w95.c @@ -0,0 +1,356 @@ +/* + Samba Unix/Linux SMB client utility libeditreg.c + Copyright (C) 2004 Jelmer Vernooij, jelmer@samba.org + + Backend for Windows '95 registry files. Explanation of file format + comes from http://www.cs.mun.ca/~michael/regutils/. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "includes.h" +#include "registry.h" +#include "system/shmem.h" + +/** + * The registry starts with a header that contains pointers to + * the rgdb. + * + * After the main header follows the RGKN header (key index table). + * The RGKN keys are listed after each other. They are put into + * blocks, the first having a length of 0x2000 bytes, the others + * being 0x1000 bytes long. + * + * After the RGKN header follow one or more RGDB blocks. These blocks + * contain keys. A key is followed by its name and its values. + * + * Values are followed by their name and then their data. + * + * Basically the idea is that the RGKN contains the associations between + * the keys and the RGDB contains the actual data. + */ + +typedef uint_t DWORD; +typedef unsigned short WORD; + +typedef struct creg_block { + DWORD CREG_ID; /* CREG */ + DWORD uk1; + DWORD rgdb_offset; + DWORD chksum; + WORD num_rgdb; + WORD flags; + DWORD uk2; + DWORD uk3; + DWORD uk4; +} CREG_HDR; + +typedef struct rgkn_block { + DWORD RGKN_ID; /* RGKN */ + DWORD size; + DWORD root_offset; + DWORD free_offset; + DWORD flags; + DWORD chksum; + DWORD uk1; + DWORD uk2; +} RGKN_HDR; + +typedef struct reg_id { + WORD id; + WORD rgdb; +} REG_ID; + +typedef struct rgkn_key { + DWORD type; /* 0x00000000 = normal key, 0x80000000 = free block */ + DWORD hash; /* Contains either hash or size of free blocks that follows */ + DWORD next_free; + DWORD parent_offset; + DWORD first_child_offset; + DWORD next_offset; + REG_ID id; +} RGKN_KEY; + + +typedef struct rgdb_block { + DWORD RGDB_ID; /* RGDB */ + DWORD size; + DWORD unused_size; + WORD flags; + WORD section; + DWORD free_offset; /* -1 if there is no free space */ + WORD max_id; + WORD first_free_id; + DWORD uk1; + DWORD chksum; +} RGDB_HDR; + +typedef struct rgdb_key { + DWORD size; + REG_ID id; + DWORD used_size; + WORD name_len; + WORD num_values; + DWORD uk1; +} RGDB_KEY; + +typedef struct rgdb_value { + DWORD type; + DWORD uk1; + WORD name_len; + WORD data_len; +} RGDB_VALUE; + +typedef struct creg_struct_s { + int fd; + BOOL modified; + char *base; + struct stat sbuf; + CREG_HDR *creg_hdr; + RGKN_HDR *rgkn_hdr; + RGDB_KEY ***rgdb_keys; +} CREG; + +#define RGKN_START_SIZE 0x2000 +#define RGKN_INC_SIZE 0x1000 + +#define LOCN_RGKN(creg, o) ((RGKN_KEY *)((creg)->base + sizeof(CREG_HDR) + o)) +#define LOCN_RGDB_BLOCK(creg, o) (((creg)->base + (creg)->creg_hdr->rgdb_offset + o)) +#define LOCN_RGDB_KEY(creg, rgdb, id) ((RGDB_KEY *)((creg)->rgdb_keys[(rgdb)][(id)])) + +static DWORD str_to_dword(const char *a) { + int i; + unsigned long ret = 0; + for(i = strlen(a)-1; i >= 0; i--) { + ret = ret * 0x100 + a[i]; + } + return ret; +} + +#if 0 /* unused */ + +static DWORD calc_hash(const char *str) { + DWORD ret = 0; + int i; + for(i = 0; str[i] && str[i] != '\\'; i++) { + ret+=toupper(str[i]); + } + return ret; +} + +static void parse_rgkn_block(CREG *creg, off_t start_off, off_t end_off) +{ + off_t i; + for(i = start_off; end_off - i > sizeof(RGKN_KEY); i+= sizeof(RGKN_KEY)) { + RGKN_KEY *key = (RGKN_KEY *)LOCN_RGKN(creg, i); + if(key->type == 0) { + DEBUG(4,("Regular, id: %d, %d, parent: %x, firstchild: %x, next: %x hash: %lX\n", key->id.id, key->id.rgdb, key->parent_offset, key->first_child_offset, key->next_offset, (long)key->hash)); + } else if(key->type == 0x80000000) { + DEBUG(3,("free\n")); + i += key->hash; + } else { + DEBUG(0,("Invalid key type in RGKN: %0X\n", key->type)); + } + } +} + +#endif + +static void parse_rgdb_block(CREG *creg, RGDB_HDR *rgdb_hdr) +{ + DWORD used_size = rgdb_hdr->size - rgdb_hdr->unused_size; + DWORD offset = 0; + + while(offset < used_size) { + RGDB_KEY *key = (RGDB_KEY *)(((char *)rgdb_hdr) + sizeof(RGDB_HDR) + offset); + + if(!(key->id.id == 0xFFFF && key->id.rgdb == 0xFFFF))creg->rgdb_keys[key->id.rgdb][key->id.id] = key; + offset += key->size; + } +} + +static WERROR w95_open_reg (struct registry_hive *h, struct registry_key **root) +{ + CREG *creg; + DWORD creg_id, rgkn_id; + DWORD i; + DWORD offset; + + creg = talloc_p(h, CREG); + memset(creg, 0, sizeof(CREG)); + h->backend_data = creg; + + if((creg->fd = open(h->location, O_RDONLY, 0000)) < 0) { + return WERR_FOOBAR; + } + + if (fstat(creg->fd, &creg->sbuf) < 0) { + return WERR_FOOBAR; + } + + creg->base = mmap(0, creg->sbuf.st_size, PROT_READ, MAP_SHARED, creg->fd, 0); + + if ((int)creg->base == 1) { + DEBUG(0,("Could not mmap file: %s, %s\n", h->location, strerror(errno))); + return WERR_FOOBAR; + } + + creg->creg_hdr = (CREG_HDR *)creg->base; + + if ((creg_id = IVAL(&creg->creg_hdr->CREG_ID,0)) != str_to_dword("CREG")) { + DEBUG(0, ("Unrecognized Windows 95 registry header id: 0x%0X, %s\n", + creg_id, h->location)); + return WERR_FOOBAR; + } + + creg->rgkn_hdr = (RGKN_HDR *)LOCN_RGKN(creg, 0); + + if ((rgkn_id = IVAL(&creg->rgkn_hdr->RGKN_ID,0)) != str_to_dword("RGKN")) { + DEBUG(0, ("Unrecognized Windows 95 registry key index id: 0x%0X, %s\n", + rgkn_id, h->location)); + return WERR_FOOBAR; + } + +#if 0 + /* If'ed out because we only need to parse this stuff when allocating new + * entries (which we don't do at the moment */ + /* First parse the 0x2000 long block */ + parse_rgkn_block(creg, sizeof(RGKN_HDR), 0x2000); + + /* Then parse the other 0x1000 length blocks */ + for(offset = 0x2000; offset < creg->rgkn_hdr->size; offset+=0x1000) { + parse_rgkn_block(creg, offset, offset+0x1000); + } +#endif + + creg->rgdb_keys = talloc_array_p(h, RGDB_KEY **, creg->creg_hdr->num_rgdb); + + offset = 0; + DEBUG(3, ("Reading %d rgdb entries\n", creg->creg_hdr->num_rgdb)); + for(i = 0; i < creg->creg_hdr->num_rgdb; i++) { + RGDB_HDR *rgdb_hdr = (RGDB_HDR *)LOCN_RGDB_BLOCK(creg, offset); + + if(strncmp((char *)&(rgdb_hdr->RGDB_ID), "RGDB", 4)) { + DEBUG(0, ("unrecognized rgdb entry: %4d, %s\n", + rgdb_hdr->RGDB_ID, h->location)); + return WERR_FOOBAR; + } else { + DEBUG(3, ("Valid rgdb entry, first free id: %d, max id: %d\n", rgdb_hdr->first_free_id, rgdb_hdr->max_id)); + } + + + creg->rgdb_keys[i] = talloc_array_p(h, RGDB_KEY *, rgdb_hdr->max_id+1); + memset(creg->rgdb_keys[i], 0, sizeof(RGDB_KEY *) * (rgdb_hdr->max_id+1)); + + parse_rgdb_block(creg, rgdb_hdr); + + offset+=rgdb_hdr->size; + } + + /* First element in rgkn should be root key */ + *root = talloc_p(h, struct registry_key); + (*root)->name = NULL; + (*root)->backend_data = LOCN_RGKN(creg, sizeof(RGKN_HDR)); + + return WERR_OK; +} + +static WERROR w95_get_subkey_by_index (TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_key **key) +{ + CREG *creg = parent->hive->backend_data; + RGKN_KEY *rgkn_key = parent->backend_data; + RGKN_KEY *child; + DWORD child_offset; + DWORD cur = 0; + + /* Get id of first child */ + child_offset = rgkn_key->first_child_offset; + + while(child_offset != 0xFFFFFFFF) { + child = LOCN_RGKN(creg, child_offset); + + /* n == cur ? return! */ + if(cur == n) { + RGDB_KEY *rgdb_key; + rgdb_key = LOCN_RGDB_KEY(creg, child->id.rgdb, child->id.id); + if(!rgdb_key) { + DEBUG(0, ("Can't find %d,%d in RGDB table!\n", child->id.rgdb, child->id.id)); + return WERR_FOOBAR; + } + *key = talloc_p(mem_ctx, struct registry_key); + (*key)->backend_data = child; + (*key)->name = talloc_strndup(mem_ctx, (char *)rgdb_key + sizeof(RGDB_KEY), rgdb_key->name_len); + return WERR_OK; + } + + cur++; + + child_offset = child->next_offset; + } + + return WERR_NO_MORE_ITEMS; +} + +static WERROR w95_num_values(struct registry_key *k, int *count) +{ + RGKN_KEY *rgkn_key = k->backend_data; + RGDB_KEY *rgdb_key = LOCN_RGDB_KEY((CREG *)k->hive->backend_data, rgkn_key->id.rgdb, rgkn_key->id.id); + + if(!rgdb_key) return WERR_FOOBAR; + + *count = rgdb_key->num_values; + + return WERR_OK; +} + +static WERROR w95_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_value **value) +{ + RGKN_KEY *rgkn_key = k->backend_data; + DWORD i; + DWORD offset = 0; + RGDB_KEY *rgdb_key = LOCN_RGDB_KEY((CREG *)k->hive->backend_data, rgkn_key->id.rgdb, rgkn_key->id.id); + RGDB_VALUE *curval = NULL; + + if(!rgdb_key) return WERR_FOOBAR; + + if(idx >= rgdb_key->num_values) return WERR_NO_MORE_ITEMS; + + for(i = 0; i < idx; i++) { + curval = (RGDB_VALUE *)(((char *)rgdb_key) + sizeof(RGDB_KEY) + rgdb_key->name_len + offset); + offset+=sizeof(RGDB_VALUE) + curval->name_len + curval->data_len; + } + + *value = talloc_p(mem_ctx, struct registry_value); + (*value)->backend_data = curval; + (*value)->name = talloc_strndup(mem_ctx, (char *)curval+sizeof(RGDB_VALUE), curval->name_len); + + (*value)->data_len = curval->data_len; + (*value)->data_blk = talloc_memdup(mem_ctx, (char *)curval+sizeof(RGDB_VALUE)+curval->name_len, curval->data_len); + (*value)->data_type = curval->type; + + return WERR_OK; +} + +static struct hive_operations reg_backend_w95 = { + .name = "w95", + .open_hive = w95_open_reg, + .get_value_by_index = w95_get_value_by_id, + .num_values = w95_num_values, + .get_subkey_by_index = w95_get_subkey_by_index, +}; + +NTSTATUS registry_w95_init(void) +{ + return registry_register(®_backend_w95); +} diff --git a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c deleted file mode 100644 index 445d13a99c..0000000000 --- a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c +++ /dev/null @@ -1,356 +0,0 @@ -/* - Samba Unix/Linux SMB client utility libeditreg.c - Copyright (C) 2004 Jelmer Vernooij, jelmer@samba.org - - Backend for Windows '95 registry files. Explanation of file format - comes from http://www.cs.mun.ca/~michael/regutils/. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "includes.h" -#include "registry.h" -#include "system/shmem.h" - -/** - * The registry starts with a header that contains pointers to - * the rgdb. - * - * After the main header follows the RGKN header (key index table). - * The RGKN keys are listed after each other. They are put into - * blocks, the first having a length of 0x2000 bytes, the others - * being 0x1000 bytes long. - * - * After the RGKN header follow one or more RGDB blocks. These blocks - * contain keys. A key is followed by its name and its values. - * - * Values are followed by their name and then their data. - * - * Basically the idea is that the RGKN contains the associations between - * the keys and the RGDB contains the actual data. - */ - -typedef uint_t DWORD; -typedef unsigned short WORD; - -typedef struct creg_block { - DWORD CREG_ID; /* CREG */ - DWORD uk1; - DWORD rgdb_offset; - DWORD chksum; - WORD num_rgdb; - WORD flags; - DWORD uk2; - DWORD uk3; - DWORD uk4; -} CREG_HDR; - -typedef struct rgkn_block { - DWORD RGKN_ID; /* RGKN */ - DWORD size; - DWORD root_offset; - DWORD free_offset; - DWORD flags; - DWORD chksum; - DWORD uk1; - DWORD uk2; -} RGKN_HDR; - -typedef struct reg_id { - WORD id; - WORD rgdb; -} REG_ID; - -typedef struct rgkn_key { - DWORD type; /* 0x00000000 = normal key, 0x80000000 = free block */ - DWORD hash; /* Contains either hash or size of free blocks that follows */ - DWORD next_free; - DWORD parent_offset; - DWORD first_child_offset; - DWORD next_offset; - REG_ID id; -} RGKN_KEY; - - -typedef struct rgdb_block { - DWORD RGDB_ID; /* RGDB */ - DWORD size; - DWORD unused_size; - WORD flags; - WORD section; - DWORD free_offset; /* -1 if there is no free space */ - WORD max_id; - WORD first_free_id; - DWORD uk1; - DWORD chksum; -} RGDB_HDR; - -typedef struct rgdb_key { - DWORD size; - REG_ID id; - DWORD used_size; - WORD name_len; - WORD num_values; - DWORD uk1; -} RGDB_KEY; - -typedef struct rgdb_value { - DWORD type; - DWORD uk1; - WORD name_len; - WORD data_len; -} RGDB_VALUE; - -typedef struct creg_struct_s { - int fd; - BOOL modified; - char *base; - struct stat sbuf; - CREG_HDR *creg_hdr; - RGKN_HDR *rgkn_hdr; - RGDB_KEY ***rgdb_keys; -} CREG; - -#define RGKN_START_SIZE 0x2000 -#define RGKN_INC_SIZE 0x1000 - -#define LOCN_RGKN(creg, o) ((RGKN_KEY *)((creg)->base + sizeof(CREG_HDR) + o)) -#define LOCN_RGDB_BLOCK(creg, o) (((creg)->base + (creg)->creg_hdr->rgdb_offset + o)) -#define LOCN_RGDB_KEY(creg, rgdb, id) ((RGDB_KEY *)((creg)->rgdb_keys[(rgdb)][(id)])) - -static DWORD str_to_dword(const char *a) { - int i; - unsigned long ret = 0; - for(i = strlen(a)-1; i >= 0; i--) { - ret = ret * 0x100 + a[i]; - } - return ret; -} - -#if 0 /* unused */ - -static DWORD calc_hash(const char *str) { - DWORD ret = 0; - int i; - for(i = 0; str[i] && str[i] != '\\'; i++) { - ret+=toupper(str[i]); - } - return ret; -} - -static void parse_rgkn_block(CREG *creg, off_t start_off, off_t end_off) -{ - off_t i; - for(i = start_off; end_off - i > sizeof(RGKN_KEY); i+= sizeof(RGKN_KEY)) { - RGKN_KEY *key = (RGKN_KEY *)LOCN_RGKN(creg, i); - if(key->type == 0) { - DEBUG(4,("Regular, id: %d, %d, parent: %x, firstchild: %x, next: %x hash: %lX\n", key->id.id, key->id.rgdb, key->parent_offset, key->first_child_offset, key->next_offset, (long)key->hash)); - } else if(key->type == 0x80000000) { - DEBUG(3,("free\n")); - i += key->hash; - } else { - DEBUG(0,("Invalid key type in RGKN: %0X\n", key->type)); - } - } -} - -#endif - -static void parse_rgdb_block(CREG *creg, RGDB_HDR *rgdb_hdr) -{ - DWORD used_size = rgdb_hdr->size - rgdb_hdr->unused_size; - DWORD offset = 0; - - while(offset < used_size) { - RGDB_KEY *key = (RGDB_KEY *)(((char *)rgdb_hdr) + sizeof(RGDB_HDR) + offset); - - if(!(key->id.id == 0xFFFF && key->id.rgdb == 0xFFFF))creg->rgdb_keys[key->id.rgdb][key->id.id] = key; - offset += key->size; - } -} - -static WERROR w95_open_reg (TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **root) -{ - CREG *creg; - DWORD creg_id, rgkn_id; - DWORD i; - DWORD offset; - - creg = talloc_p(mem_ctx, CREG); - memset(creg, 0, sizeof(CREG)); - h->backend_data = creg; - - if((creg->fd = open(h->location, O_RDONLY, 0000)) < 0) { - return WERR_FOOBAR; - } - - if (fstat(creg->fd, &creg->sbuf) < 0) { - return WERR_FOOBAR; - } - - creg->base = mmap(0, creg->sbuf.st_size, PROT_READ, MAP_SHARED, creg->fd, 0); - - if ((int)creg->base == 1) { - DEBUG(0,("Could not mmap file: %s, %s\n", h->location, strerror(errno))); - return WERR_FOOBAR; - } - - creg->creg_hdr = (CREG_HDR *)creg->base; - - if ((creg_id = IVAL(&creg->creg_hdr->CREG_ID,0)) != str_to_dword("CREG")) { - DEBUG(0, ("Unrecognized Windows 95 registry header id: 0x%0X, %s\n", - creg_id, h->location)); - return WERR_FOOBAR; - } - - creg->rgkn_hdr = (RGKN_HDR *)LOCN_RGKN(creg, 0); - - if ((rgkn_id = IVAL(&creg->rgkn_hdr->RGKN_ID,0)) != str_to_dword("RGKN")) { - DEBUG(0, ("Unrecognized Windows 95 registry key index id: 0x%0X, %s\n", - rgkn_id, h->location)); - return WERR_FOOBAR; - } - -#if 0 - /* If'ed out because we only need to parse this stuff when allocating new - * entries (which we don't do at the moment */ - /* First parse the 0x2000 long block */ - parse_rgkn_block(creg, sizeof(RGKN_HDR), 0x2000); - - /* Then parse the other 0x1000 length blocks */ - for(offset = 0x2000; offset < creg->rgkn_hdr->size; offset+=0x1000) { - parse_rgkn_block(creg, offset, offset+0x1000); - } -#endif - - creg->rgdb_keys = talloc_array_p(mem_ctx, RGDB_KEY **, creg->creg_hdr->num_rgdb); - - offset = 0; - DEBUG(3, ("Reading %d rgdb entries\n", creg->creg_hdr->num_rgdb)); - for(i = 0; i < creg->creg_hdr->num_rgdb; i++) { - RGDB_HDR *rgdb_hdr = (RGDB_HDR *)LOCN_RGDB_BLOCK(creg, offset); - - if(strncmp((char *)&(rgdb_hdr->RGDB_ID), "RGDB", 4)) { - DEBUG(0, ("unrecognized rgdb entry: %4d, %s\n", - rgdb_hdr->RGDB_ID, h->location)); - return WERR_FOOBAR; - } else { - DEBUG(3, ("Valid rgdb entry, first free id: %d, max id: %d\n", rgdb_hdr->first_free_id, rgdb_hdr->max_id)); - } - - - creg->rgdb_keys[i] = talloc_array_p(mem_ctx, RGDB_KEY *, rgdb_hdr->max_id+1); - memset(creg->rgdb_keys[i], 0, sizeof(RGDB_KEY *) * (rgdb_hdr->max_id+1)); - - parse_rgdb_block(creg, rgdb_hdr); - - offset+=rgdb_hdr->size; - } - - /* First element in rgkn should be root key */ - *root = talloc_p(mem_ctx, struct registry_key); - (*root)->name = NULL; - (*root)->backend_data = LOCN_RGKN(creg, sizeof(RGKN_HDR)); - - return WERR_OK; -} - -static WERROR w95_get_subkey_by_index (TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_key **key) -{ - CREG *creg = parent->hive->backend_data; - RGKN_KEY *rgkn_key = parent->backend_data; - RGKN_KEY *child; - DWORD child_offset; - DWORD cur = 0; - - /* Get id of first child */ - child_offset = rgkn_key->first_child_offset; - - while(child_offset != 0xFFFFFFFF) { - child = LOCN_RGKN(creg, child_offset); - - /* n == cur ? return! */ - if(cur == n) { - RGDB_KEY *rgdb_key; - rgdb_key = LOCN_RGDB_KEY(creg, child->id.rgdb, child->id.id); - if(!rgdb_key) { - DEBUG(0, ("Can't find %d,%d in RGDB table!\n", child->id.rgdb, child->id.id)); - return WERR_FOOBAR; - } - *key = talloc_p(mem_ctx, struct registry_key); - (*key)->backend_data = child; - (*key)->name = talloc_strndup(mem_ctx, (char *)rgdb_key + sizeof(RGDB_KEY), rgdb_key->name_len); - return WERR_OK; - } - - cur++; - - child_offset = child->next_offset; - } - - return WERR_NO_MORE_ITEMS; -} - -static WERROR w95_num_values(struct registry_key *k, int *count) -{ - RGKN_KEY *rgkn_key = k->backend_data; - RGDB_KEY *rgdb_key = LOCN_RGDB_KEY((CREG *)k->hive->backend_data, rgkn_key->id.rgdb, rgkn_key->id.id); - - if(!rgdb_key) return WERR_FOOBAR; - - *count = rgdb_key->num_values; - - return WERR_OK; -} - -static WERROR w95_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_value **value) -{ - RGKN_KEY *rgkn_key = k->backend_data; - DWORD i; - DWORD offset = 0; - RGDB_KEY *rgdb_key = LOCN_RGDB_KEY((CREG *)k->hive->backend_data, rgkn_key->id.rgdb, rgkn_key->id.id); - RGDB_VALUE *curval = NULL; - - if(!rgdb_key) return WERR_FOOBAR; - - if(idx >= rgdb_key->num_values) return WERR_NO_MORE_ITEMS; - - for(i = 0; i < idx; i++) { - curval = (RGDB_VALUE *)(((char *)rgdb_key) + sizeof(RGDB_KEY) + rgdb_key->name_len + offset); - offset+=sizeof(RGDB_VALUE) + curval->name_len + curval->data_len; - } - - *value = talloc_p(mem_ctx, struct registry_value); - (*value)->backend_data = curval; - (*value)->name = talloc_strndup(mem_ctx, (char *)curval+sizeof(RGDB_VALUE), curval->name_len); - - (*value)->data_len = curval->data_len; - (*value)->data_blk = talloc_memdup(mem_ctx, (char *)curval+sizeof(RGDB_VALUE)+curval->name_len, curval->data_len); - (*value)->data_type = curval->type; - - return WERR_OK; -} - -static struct registry_operations reg_backend_w95 = { - .name = "w95", - .open_hive = w95_open_reg, - .get_value_by_index = w95_get_value_by_id, - .num_values = w95_num_values, - .get_subkey_by_index = w95_get_subkey_by_index, -}; - -NTSTATUS registry_w95_init(void) -{ - return registry_register(®_backend_w95); -} diff --git a/source4/lib/registry/reg_backend_wine.c b/source4/lib/registry/reg_backend_wine.c new file mode 100644 index 0000000000..8a3458b52c --- /dev/null +++ b/source4/lib/registry/reg_backend_wine.c @@ -0,0 +1,48 @@ +/* + Unix SMB/CIFS implementation. + Registry interface + Copyright (C) Jelmer Vernooij 2004. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "lib/registry/common/registry.h" +#include "windows/registry.h" + +static WERROR wine_open_reg (struct registry_hive *h, struct registry_key **key) +{ + /* FIXME: Open h->location and mmap it */ +} + + + +static REG_OPS reg_backend_wine = { + .name = "wine", + .open_hive = wine_open_reg, + +}; + +NTSTATUS registry_wine_init(void) +{ + register_backend("registry", ®_backend_wine); + return NT_STATUS_OK; +} + +WERROR reg_open_wine(struct registry_key **ctx) +{ + /* FIXME: Open ~/.wine/system.reg, etc */ + return WERR_NOT_SUPPORTED; +} diff --git a/source4/lib/registry/reg_backend_wine/reg_backend_wine.c b/source4/lib/registry/reg_backend_wine/reg_backend_wine.c deleted file mode 100644 index 249af27e13..0000000000 --- a/source4/lib/registry/reg_backend_wine/reg_backend_wine.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Registry interface - Copyright (C) Jelmer Vernooij 2004. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" -#include "lib/registry/common/registry.h" -#include "windows/registry.h" - -static REG_OPS reg_backend_wine = { - .name = "wine", -}; - -NTSTATUS registry_wine_init(void) -{ - register_backend("registry", ®_backend_wine); - return NT_STATUS_OK; -} diff --git a/source4/lib/registry/reg_samba.c b/source4/lib/registry/reg_samba.c new file mode 100644 index 0000000000..a19029524d --- /dev/null +++ b/source4/lib/registry/reg_samba.c @@ -0,0 +1,62 @@ +/* + Unix SMB/CIFS implementation. + Copyright (C) Jelmer Vernooij 2004. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "registry.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_REGISTRY + +static WERROR reg_samba_get_hive (struct registry_context *ctx, uint32 hkey, struct registry_key **k) +{ + WERROR error; + const char *conf; + char *backend, *location; + const char *hivename = reg_get_hkey_name(hkey); + + *k = NULL; + + conf = lp_parm_string(-1, "registry", hivename); + + if (!conf) { + return WERR_NOT_SUPPORTED; + } + + backend = talloc_strdup(NULL, conf); + location = strchr(backend, ':'); + + if (location) { + *location = '\0'; + location++; + } + + error = reg_open_hive(ctx, backend, location, NULL, k); + + talloc_destroy(backend); + + return error; +} + +WERROR reg_open_local (struct registry_context **ctx) +{ + *ctx = talloc_p(NULL, struct registry_context); + (*ctx)->get_hive = reg_samba_get_hive; + + return WERR_OK; +} diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 55c8f1e72f..fc2954b6af 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -113,21 +113,19 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, { int opt; poptContext pc; - const char *backend1 = NULL, *backend2 = NULL; - const char *location2; - const char *credentials1= NULL, *credentials2 = NULL; char *outputfile = NULL; FILE *fd = stdout; - struct registry_context *h1 = NULL, *h2; + struct registry_context *h1 = NULL, *h2 = NULL; int from_null = 0; int i; WERROR error, error2; struct poptOption long_options[] = { POPT_AUTOHELP - {"backend", 'b', POPT_ARG_STRING, NULL, 'b', "backend to use", NULL}, - {"credentials", 'c', POPT_ARG_STRING, NULL, 'c', "credentials", NULL}, + POPT_COMMON_CREDENTIALS {"output", 'o', POPT_ARG_STRING, &outputfile, 'o', "output file to use", NULL }, - {"null", 'n', POPT_ARG_NONE, &from_null, 'n', "Diff from NULL" }, + {"null", 'n', POPT_ARG_NONE, &from_null, 'n', "Diff from NULL", NULL }, + {"remote", 'R', POPT_ARG_STRING, NULL, 0, "Connect to remote server" , NULL }, + {"local", 'L', POPT_ARG_NONE, NULL, 0, "Open local registry", NULL }, POPT_TABLEEND }; @@ -141,49 +139,24 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); while((opt = poptGetNextOpt(pc)) != -1) { + error = WERR_OK; switch(opt) { - case 'c': - if(!credentials1 && !from_null) credentials1 = poptGetOptArg(pc); - else if(!credentials2) credentials2 = poptGetOptArg(pc); + case 'L': + if (!h1 && !from_null) error = reg_open_local(&h1); + else if (!h2) error = reg_open_local(&h2); break; - case 'b': - if(!backend1 && !from_null) backend1 = poptGetOptArg(pc); - else if(!backend2) backend2 = poptGetOptArg(pc); + case 'R': + if (!h1 && !from_null) error = reg_open_remote(&h1, cmdline_get_username(), cmdline_get_userpassword(), poptGetOptArg(pc)); + else if (!h2) error = reg_open_remote(&h2, cmdline_get_username(), cmdline_get_userpassword(), poptGetOptArg(pc)); break; } - } - setup_logging(argv[0], True); - if(!from_null) { - const char *location1; - location1 = poptGetArg(pc); - if(!location1) { - poptPrintUsage(pc, stderr, 0); + if (!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Error: %s\n", win_errstr(error)); return 1; } - - if(!backend1) backend1 = "rpc"; - - error = reg_open(&h1, backend1, location1, credentials1); - if(!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location1, backend1); - return 1; - } - } - - location2 = poptGetArg(pc); - if(!location2) { - poptPrintUsage(pc, stderr, 0); - return 2; - } - - if(!backend2) backend2 = "rpc"; - - error = reg_open(&h2, backend2, location2, credentials2); - if(!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location2, backend2); - return 1; } + setup_logging(argv[0], True); poptFreeContext(pc); @@ -196,12 +169,25 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, } fprintf(fd, "REGEDIT4\n\n"); - fprintf(fd, "; Generated using regdiff\n"); + fprintf(fd, "; Generated using regdiff, part of Samba\n"); error2 = error = WERR_OK; - for(i = 0; (!h1 || i < h1->num_hives) && i < h2->num_hives; i++) { - writediff(h1?h1->hives[i]->root:NULL, h2->hives[i]->root, fd); + for(i = HKEY_CLASSES_ROOT; i <= HKEY_PN; i++) { + struct registry_key *r1, *r2; + error = reg_get_hive(h1, i, &r1); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Unable to open hive %s for backend 1\n", reg_get_hkey_name(i))); + continue; + } + + error = reg_get_hive(h2, i, &r2); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Unable to open hive %s for backend 2\n", reg_get_hkey_name(i))); + continue; + } + + writediff(r1, r2, fd); } fclose(fd); diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index be60b96019..a4a4649c96 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -758,16 +758,14 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd { int opt; poptContext pc; - const char *location; - const char *credentials = NULL; const char *patch; - const char *backend = "rpc"; struct registry_context *h; + const char *remote = NULL; WERROR error; struct poptOption long_options[] = { POPT_AUTOHELP - {"backend", 'b', POPT_ARG_STRING, &backend, 'b', "backend to use", NULL}, - {"credentials", 'c', POPT_ARG_STRING, &credentials, 'c', "credentials (user%password", NULL}, + POPT_COMMON_CREDENTIALS + {"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL}, POPT_TABLEEND }; @@ -785,25 +783,22 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd setup_logging(argv[0], True); - location = poptGetArg(pc); - if(!location) { - poptPrintUsage(pc, stderr, 0); - return 1; + if (remote) { + error = reg_open_remote (&h, cmdline_get_username(), cmdline_get_userpassword(), remote); + } else { + error = reg_open_local (&h); } - error = reg_open(&h, backend, location, credentials); - if(!h) { - fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location, backend); + if (W_ERROR_IS_OK(error)) { + fprintf(stderr, "Error: %s\n", win_errstr(error)); return 1; } - + patch = poptGetArg(pc); if(!patch) patch = "/dev/stdin"; poptFreeContext(pc); nt_apply_reg_command_file(h, patch); - talloc_destroy(h->mem_ctx); - return 0; } diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index f18b012720..3fd9dab268 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -164,15 +164,23 @@ static struct registry_key *cmd_rmval(TALLOC_CTX *mem_ctx, struct registry_key * static struct registry_key *cmd_hive(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) { - int i; - for(i = 0; i < cur->hive->reg_ctx->num_hives; i++) { + if (!cur->hive->reg_ctx) { + fprintf(stderr, "Only one hive loaded\n"); + return cur; + } - if(argc == 1) { - printf("%s\n", cur->hive->reg_ctx->hives[i]->name); - } else if(!strcmp(cur->hive->reg_ctx->hives[i]->name, argv[1])) { - return cur->hive->reg_ctx->hives[i]->root; - } + if (argc == 1) { + printf("%s\n", cur->hive->root->name); + } else { + struct registry_key *newroot; + WERROR error = reg_get_hive_by_name(cur->hive->reg_ctx, argv[1], &newroot); + if (W_ERROR_IS_OK(error)) { + return newroot; + } else { + fprintf(stderr, "Can't switch to hive %s: %s\n", cur->hive->root->name, win_errstr(error)); + } } + return NULL; } @@ -274,11 +282,7 @@ static char **reg_complete_command(const char *text, int end) matches[0] = strdup(matches[1]); break; default: - matches[0] = malloc(samelen+1); - if (!matches[0]) - goto cleanup; - strncpy(matches[0], matches[1], samelen); - matches[0][samelen] = 0; + matches[0] = strndup(matches[1], samelen); } matches[count] = NULL; return matches; @@ -295,11 +299,11 @@ cleanup: static char **reg_complete_key(const char *text, int end) { struct registry_key *subkey; - int i, j = 0; + int i, j = 1; + int samelen = 0; int len; char **matches; TALLOC_CTX *mem_ctx; - /* Complete argument */ matches = malloc_array_p(char *, MAX_COMPLETIONS); if (!matches) return NULL; @@ -313,6 +317,12 @@ static char **reg_complete_key(const char *text, int end) if(!strncmp(text, subkey->name, len)) { matches[j] = strdup(subkey->name); j++; + + if (j == 1) + samelen = strlen(matches[j]); + else + while (strncmp(matches[j], matches[j-1], samelen) != 0) + samelen--; } } else if(W_ERROR_EQUAL(status, WERR_NO_MORE_ITEMS)) { break; @@ -322,8 +332,20 @@ static char **reg_complete_key(const char *text, int end) return NULL; } } - matches[j] = NULL; talloc_destroy(mem_ctx); + + if (j == 1) { /* No matches at all */ + SAFE_FREE(matches); + return NULL; + } + + if (j == 2) { /* Exact match */ + matches[0] = strdup(matches[1]); + } else { + matches[0] = strndup(matches[1], samelen); + } + + matches[j] = NULL; return matches; } @@ -341,18 +363,18 @@ static char **reg_completion(const char *text, int start, int end) int main(int argc, char **argv) { int opt; - const char *backend = "rpc"; - const char *credentials = NULL; + const char *backend = NULL; struct registry_key *curkey = NULL; poptContext pc; WERROR error; TALLOC_CTX *mem_ctx = talloc_init("cmd"); - struct registry_context *h; + const char *remote = NULL; + struct registry_context *h = NULL; struct poptOption long_options[] = { POPT_AUTOHELP - POPT_COMMON_SAMBA + POPT_COMMON_CREDENTIALS {"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL}, - {"credentials", 'c', POPT_ARG_STRING, &credentials, 0, "credentials", NULL}, + {"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL}, POPT_TABLEEND }; @@ -370,20 +392,31 @@ static char **reg_completion(const char *text, int start, int end) setup_logging("regtree", True); - error = reg_open(&h, backend, poptPeekArg(pc), credentials); + if (remote) { + error = reg_open_remote (&h, cmdline_get_username(), cmdline_get_userpassword(), remote); + } else if (backend) { + error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, &curkey); + } else { + error = reg_open_local(&h); + } + if(!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Unable to open '%s' with backend '%s'\n", poptGetArg(pc), backend); + fprintf(stderr, "Unable to open registry\n"); return 1; } - poptFreeContext(pc); - - curkey = h->hives[0]->root; + if (h) { + /*FIXME: What if HKEY_CLASSES_ROOT is not present ? */ + reg_get_hive(h, HKEY_CLASSES_ROOT, &curkey); + } + + poptFreeContext(pc); + while(True) { char *line, *prompt; - if(curkey->hive->name) { - asprintf(&prompt, "%s:%s> ", curkey->hive->name, curkey->path); + if(curkey->hive->root->name) { + asprintf(&prompt, "%s:%s> ", curkey->hive->root->name, curkey->path); } else { asprintf(&prompt, "%s> ", curkey->path); } diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index ced7a00f94..8ff68229eb 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -36,7 +36,7 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) /* Hive name */ if(p->hive->root == p) { - if(p->hive->name) printf("%s\n", p->hive->name); else printf("\n"); + if(p->hive->root->name) printf("%s\n", p->hive->root->name); else printf("\n"); } else { if(!p->name) printf("\n"); if(fullpath) printf("%s\n", p->path); @@ -73,17 +73,19 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) int main(int argc, char **argv) { int opt, i; - const char *backend = "rpc"; - const char *credentials = NULL; + const char *backend = NULL; + const char *remote = NULL; poptContext pc; - struct registry_context *h; + struct registry_context *h = NULL; + struct registry_key *root = NULL; WERROR error; int fullpath = 0, no_values = 0; struct poptOption long_options[] = { POPT_AUTOHELP + POPT_COMMON_CREDENTIALS {"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL}, {"fullpath", 'f', POPT_ARG_NONE, &fullpath, 0, "show full paths", NULL}, - {"credentials", 'c', POPT_ARG_STRING, &credentials, 0, "credentials (user%password)", NULL}, + {"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL }, {"no-values", 'V', POPT_ARG_NONE, &no_values, 0, "don't show values", NULL}, POPT_TABLEEND }; @@ -102,7 +104,14 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) setup_logging("regtree", True); - error = reg_open(&h, backend, poptPeekArg(pc), credentials); + if (remote) { + error = reg_open_remote(&h, cmdline_get_username(), cmdline_get_userpassword(), remote); + } else if (backend) { + error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, &root); + } else { + error = reg_open_local (&h); + } + if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open '%s' with backend '%s':%s \n", poptGetArg(pc), backend, win_errstr(error)); return 1; @@ -110,10 +119,19 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) poptFreeContext(pc); error = WERR_OK; - - for(i = 0; i < h->num_hives; i++) { - print_tree(0, h->hives[i]->root, fullpath, no_values); - } + if (!h) { + print_tree(0, root, fullpath, no_values); + } else { + for(i = HKEY_CLASSES_ROOT; i < HKEY_PN; i++) { + error = reg_get_hive(h, i, &root); + if (!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Skipping %s\n", reg_get_hkey_name(i)); + continue; + } + print_tree(0, root, fullpath, no_values); + } + } + return 0; } -- cgit From 1cd129b102ea36e534c73805884ad023a03f0329 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 10 Dec 2004 20:50:49 +0000 Subject: r4133: Cache results of subkey and value queries (This used to be commit 1e12971137f50077e04a0432572275baf4fde35e) --- source4/lib/registry/reg_backend_ldb.c | 84 +++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 26 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 7eaf6194a5..e833299b7e 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -22,6 +22,24 @@ #include "registry.h" #include "lib/ldb/include/ldb.h" +struct ldb_key_data +{ + const char *dn; + struct ldb_message **subkeys, **values; + int subkey_count, value_count; +}; + +static int reg_close_ldb_key (void *data) +{ + struct registry_key *key = data; + struct ldb_key_data *kd = key->backend_data; + struct ldb_context *c = key->hive->backend_data; + + ldb_search_free(c, kd->subkeys); kd->subkeys = NULL; + ldb_search_free(c, kd->values); kd->values = NULL; + return 0; +} + static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char *add) { char *ret = talloc_strdup(mem_ctx, ""); @@ -62,52 +80,56 @@ static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char * static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_key **subkey) { struct ldb_context *c = k->hive->backend_data; - int ret; - struct ldb_message **msg; struct ldb_message_element *el; + struct ldb_key_data *kd = k->backend_data, *newkd; - ret = ldb_search(c, (char *)k->backend_data, LDB_SCOPE_ONELEVEL, "(key=*)", NULL,&msg); + /* Do a search if necessary */ + if (kd->subkeys == NULL) { + kd->subkey_count = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL,&kd->subkeys); - if(ret < 0) { - DEBUG(0, ("Error getting subkeys for '%s': %s\n", (char *)k->backend_data, ldb_errstring(c))); - return WERR_FOOBAR; - } + if(kd->subkey_count < 0) { + DEBUG(0, ("Error getting subkeys for '%s': %s\n", kd->dn, ldb_errstring(c))); + return WERR_FOOBAR; + } + } - if(idx >= ret) return WERR_NO_MORE_ITEMS; - - el = ldb_msg_find_element(msg[idx], "key"); + if (idx >= kd->subkey_count) return WERR_NO_MORE_ITEMS; + + el = ldb_msg_find_element(kd->subkeys[idx], "key"); *subkey = talloc_p(mem_ctx, struct registry_key); + talloc_set_destructor(*subkey, reg_close_ldb_key); (*subkey)->name = talloc_strdup(mem_ctx, el->values[0].data); - (*subkey)->backend_data = talloc_strdup(mem_ctx, msg[idx]->dn); + (*subkey)->backend_data = newkd = talloc_zero_p(*subkey, struct ldb_key_data); + newkd->dn = talloc_strdup(mem_ctx, kd->subkeys[idx]->dn); - ldb_search_free(c, msg); return WERR_OK; } static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_value **value) { struct ldb_context *c = k->hive->backend_data; - int ret; - struct ldb_message **msg; struct ldb_message_element *el; + struct ldb_key_data *kd = k->backend_data; - ret = ldb_search(c, (char *)k->backend_data, LDB_SCOPE_ONELEVEL, "(value=*)", NULL,&msg); + /* Do the search if necessary */ + if (kd->values == NULL) { + kd->value_count = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(value=*)", NULL,&kd->values); - if(ret < 0) { - DEBUG(0, ("Error getting values for '%s': %s\n", (char *)k->backend_data, ldb_errstring(c))); - return WERR_FOOBAR; + if(kd->value_count < 0) { + DEBUG(0, ("Error getting values for '%s': %s\n", kd->dn, ldb_errstring(c))); + return WERR_FOOBAR; + } } - if(idx >= ret) return WERR_NO_MORE_ITEMS; + if(idx >= kd->value_count) return WERR_NO_MORE_ITEMS; - el = ldb_msg_find_element(msg[idx], "value"); + el = ldb_msg_find_element(kd->values[idx], "value"); *value = talloc_p(mem_ctx, struct registry_value); (*value)->name = talloc_strdup(mem_ctx, el->values[0].data); - (*value)->backend_data = talloc_strdup(mem_ctx, msg[idx]->dn); + (*value)->backend_data = talloc_strdup(mem_ctx, kd->values[idx]->dn); - ldb_search_free(c, msg); return WERR_OK; } @@ -117,8 +139,9 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const c struct ldb_message **msg; char *ldap_path; int ret; + struct ldb_key_data *newkd; ldap_path = reg_path_to_ldb(mem_ctx, name, NULL); - + ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL,&msg); if(ret == 0) { @@ -129,8 +152,10 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const c } *key = talloc_p(mem_ctx, struct registry_key); + talloc_set_destructor(*key, reg_close_ldb_key); (*key)->name = talloc_strdup(mem_ctx, strrchr(name, '\\')); - (*key)->backend_data = talloc_strdup(mem_ctx, msg[0]->dn); + (*key)->backend_data = newkd = talloc_zero_p(*key, struct ldb_key_data); + newkd->dn = talloc_strdup(mem_ctx, msg[0]->dn); ldb_search_free(c, msg); @@ -152,7 +177,10 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) hive->backend_data = c; hive->root = talloc_zero_p(hive, struct registry_key); + talloc_set_destructor (hive->root, reg_close_ldb_key); hive->root->name = talloc_strdup(hive->root, ""); + hive->root->backend_data = talloc_zero_p(hive->root, struct ldb_key_data); + return WERR_OK; } @@ -161,6 +189,7 @@ static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, struct registry_key *parent, con { struct ldb_context *ctx = parent->hive->backend_data; struct ldb_message msg; + struct ldb_key_data *newkd; int ret; ZERO_STRUCT(msg); @@ -176,17 +205,20 @@ static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, struct registry_key *parent, con } *newkey = talloc_zero_p(mem_ctx, struct registry_key); - (*newkey)->backend_data = msg.dn; (*newkey)->name = talloc_strdup(mem_ctx, name); + (*newkey)->backend_data = newkd = talloc_zero_p(*newkey, struct ldb_key_data); + newkd->dn = msg.dn; + return WERR_OK; } static WERROR ldb_del_key (struct registry_key *key) { int ret; + struct ldb_key_data *kd = key->backend_data; - ret = ldb_delete(key->hive->backend_data, key->backend_data); + ret = ldb_delete(key->hive->backend_data, kd->dn); if (ret < 0) { DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(key->hive->backend_data))); -- cgit From 6fb61740076f49a6e0ac3eaff5c8002e316cfe90 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 10 Dec 2004 21:31:32 +0000 Subject: r4135: improve a debug message (This used to be commit 4b45d3d2e86122dbe5bd258fc96ad674aba0d417) --- source4/lib/registry/common/reg_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 740d849db1..a93fa31836 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -222,7 +222,7 @@ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char WERROR error; if(!parent) { - DEBUG(0, ("Invalid parent key specified")); + DEBUG(0, ("Invalid parent key specified for open of '%s'\n", name)); return WERR_INVALID_PARAM; } -- cgit From a9fa37d6187eb0d0a074fec2ecffe2915b701188 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 10 Dec 2004 22:28:49 +0000 Subject: r4137: Make *_open_key take a registry_key instead of a hive (more efficient in some cases) (This used to be commit ddf7a331c58976f2c0b4a00390118f1acf60e3eb) --- source4/lib/registry/common/reg_interface.c | 10 +++------- source4/lib/registry/reg_backend_dir.c | 17 ++++++++-------- source4/lib/registry/reg_backend_gconf.c | 9 ++++++--- source4/lib/registry/reg_backend_ldb.c | 30 ++++++++++++++++++++--------- source4/lib/registry/reg_backend_rpc.c | 9 ++------- 5 files changed, 41 insertions(+), 34 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index a93fa31836..2382e4aa43 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -218,7 +218,6 @@ WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, co */ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, struct registry_key **result) { - char *fullname; WERROR error; if(!parent) { @@ -257,15 +256,12 @@ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char return WERR_NOT_SUPPORTED; } - - fullname = ((parent->hive->root == parent)?talloc_strdup(mem_ctx, name):talloc_asprintf(mem_ctx, "%s\\%s", parent->path, name)); - - error = parent->hive->functions->open_key(mem_ctx, parent->hive, fullname, result); + error = parent->hive->functions->open_key(mem_ctx, parent, name, result); if(!W_ERROR_IS_OK(error)) return error; (*result)->hive = parent->hive; - (*result)->path = fullname; + (*result)->path = ((parent->hive->root == parent)?talloc_strdup(mem_ctx, name):talloc_asprintf(mem_ctx, "%s\\%s", parent->path, name)); (*result)->hive = parent->hive; return WERR_OK; @@ -369,7 +365,7 @@ WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key, if(key->hive->functions->get_subkey_by_name) { error = key->hive->functions->get_subkey_by_name(mem_ctx, key,name,subkey); } else if(key->hive->functions->open_key) { - error = key->hive->functions->open_key(mem_ctx, key->hive, talloc_asprintf(mem_ctx, "%s\\%s", key->path, name), subkey); + error = key->hive->functions->open_key(mem_ctx, key, name, subkey); } else if(key->hive->functions->get_subkey_by_index) { for(i = 0; W_ERROR_IS_OK(error); i++) { error = reg_key_get_subkey_by_index(mem_ctx, key, i, subkey); diff --git a/source4/lib/registry/reg_backend_dir.c b/source4/lib/registry/reg_backend_dir.c index 5c3ed3c44c..c004be5a06 100644 --- a/source4/lib/registry/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir.c @@ -39,10 +39,10 @@ static WERROR reg_dir_del_key(struct registry_key *k) return (rmdir((char *)k->backend_data) == 0)?WERR_OK:WERR_GENERAL_FAILURE; } -static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **subkey) +static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, struct registry_key *p, const char *name, struct registry_key **subkey) { DIR *d; - char *fullpath; + char *fullpath, *unixpath; struct registry_key *ret; if(!name) { @@ -51,18 +51,19 @@ static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, con } - fullpath = talloc_asprintf(mem_ctx, "%s%s", h->location, name); - fullpath = reg_path_win2unix(fullpath); + fullpath = talloc_asprintf(mem_ctx, "%s/%s", (char *)p->backend_data, name); + unixpath = reg_path_win2unix(fullpath); - d = opendir(fullpath); + d = opendir(unixpath); if(!d) { - DEBUG(3,("Unable to open '%s': %s\n", fullpath, strerror(errno))); + DEBUG(3,("Unable to open '%s': %s\n", unixpath, strerror(errno))); return WERR_BADFILE; } closedir(d); ret = talloc_p(mem_ctx, struct registry_key); - ret->hive = h; + ret->hive = p->hive; ret->path = fullpath; + ret->backend_data = unixpath; *subkey = ret; return WERR_OK; } @@ -89,7 +90,6 @@ static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, struct registry_key *k, stat(thispath, &stbuf); if(S_ISDIR(stbuf.st_mode)) { - i++; if(i == idx) { (*key) = talloc_p(mem_ctx, struct registry_key); (*key)->name = e->d_name; @@ -99,6 +99,7 @@ static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, struct registry_key *k, closedir(d); return WERR_OK; } + i++; } SAFE_FREE(thispath); diff --git a/source4/lib/registry/reg_backend_gconf.c b/source4/lib/registry/reg_backend_gconf.c index 2fed2417b7..b53d0fedf5 100644 --- a/source4/lib/registry/reg_backend_gconf.c +++ b/source4/lib/registry/reg_backend_gconf.c @@ -42,15 +42,18 @@ static WERROR reg_open_gconf_hive(struct registry_hive *h, struct registry_key * return WERR_OK; } -static WERROR gconf_open_key (TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **key) +static WERROR gconf_open_key (TALLOC_CTX *mem_ctx, struct registry_key *h, const char *name, struct registry_key **key) { struct registry_key *ret; char *fullpath; - fullpath = talloc_asprintf(mem_ctx, "/%s", reg_path_win2unix(talloc_strdup(mem_ctx, name))); + fullpath = talloc_asprintf(mem_ctx, "%s%s%s", + (char *)h->backend_data, + strlen((char *)h->backend_data) == 1?"":"/", + reg_path_win2unix(talloc_strdup(mem_ctx, name))); /* Check if key exists */ - if(!gconf_client_dir_exists((GConfClient *)h->backend_data, fullpath, NULL)) { + if(!gconf_client_dir_exists((GConfClient *)h->hive->backend_data, fullpath, NULL)) { return WERR_DEST_NOT_FOUND; } diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index e833299b7e..7804a68d3d 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -35,8 +35,15 @@ static int reg_close_ldb_key (void *data) struct ldb_key_data *kd = key->backend_data; struct ldb_context *c = key->hive->backend_data; - ldb_search_free(c, kd->subkeys); kd->subkeys = NULL; - ldb_search_free(c, kd->values); kd->values = NULL; + if (kd->subkeys) { + ldb_search_free(c, kd->subkeys); + kd->subkeys = NULL; + } + + if (kd->values) { + ldb_search_free(c, kd->values); + kd->values = NULL; + } return 0; } @@ -85,7 +92,7 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, /* Do a search if necessary */ if (kd->subkeys == NULL) { - kd->subkey_count = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL,&kd->subkeys); + kd->subkey_count = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &kd->subkeys); if(kd->subkey_count < 0) { DEBUG(0, ("Error getting subkeys for '%s': %s\n", kd->dn, ldb_errstring(c))); @@ -133,14 +140,17 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, i return WERR_OK; } -static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **key) +static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const char *name, struct registry_key **key) { - struct ldb_context *c = h->backend_data; + struct ldb_context *c = h->hive->backend_data; struct ldb_message **msg; char *ldap_path; int ret; - struct ldb_key_data *newkd; - ldap_path = reg_path_to_ldb(mem_ctx, name, NULL); + 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:""); ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL,&msg); @@ -153,7 +163,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const c *key = talloc_p(mem_ctx, struct registry_key); talloc_set_destructor(*key, reg_close_ldb_key); - (*key)->name = talloc_strdup(mem_ctx, strrchr(name, '\\')); + (*key)->name = talloc_strdup(mem_ctx, strrchr(name, '\\')?strchr(name, '\\'):name); (*key)->backend_data = newkd = talloc_zero_p(*key, struct ldb_key_data); newkd->dn = talloc_strdup(mem_ctx, msg[0]->dn); @@ -165,6 +175,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const c static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) { struct ldb_context *c; + struct ldb_key_data *kd; if (!hive->location) return WERR_INVALID_PARAM; c = ldb_connect(hive->location, 0, NULL); @@ -179,7 +190,8 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) hive->root = talloc_zero_p(hive, struct registry_key); talloc_set_destructor (hive->root, reg_close_ldb_key); hive->root->name = talloc_strdup(hive->root, ""); - hive->root->backend_data = talloc_zero_p(hive->root, struct ldb_key_data); + hive->root->backend_data = kd = talloc_zero_p(hive->root, struct ldb_key_data); + kd->dn = talloc_strdup(hive->root, "key=root"); return WERR_OK; diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 18563b2478..927ed7fcaa 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -155,7 +155,7 @@ static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) } #endif -static WERROR rpc_open_rel_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const char *name, struct registry_key **key) +static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const char *name, struct registry_key **key) { struct rpc_key_data *mykeydata; struct winreg_OpenKey r; @@ -181,11 +181,6 @@ static WERROR rpc_open_rel_key(TALLOC_CTX *mem_ctx, struct registry_key *h, cons return r.out.result; } -static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **key) -{ - return rpc_open_rel_key(mem_ctx, h->root, name, key); -} - static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_value **value) { struct rpc_key_data *mykeydata = parent->backend_data; @@ -258,7 +253,7 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key * r.in.key_name_len = r.out.key_name_len = 0; status = dcerpc_winreg_EnumKey((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r); if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { - return rpc_open_rel_key(mem_ctx, parent, talloc_strdup(mem_ctx, r.out.out_name->name), subkey); + return rpc_open_key(mem_ctx, parent, talloc_strdup(mem_ctx, r.out.out_name->name), subkey); } return r.out.result; -- cgit From f0eff2525b8df834765a7162007bc8b4565e9a58 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 10 Dec 2004 22:57:43 +0000 Subject: r4140: Get rid of close_hive (replace it with talloc destructors). (This used to be commit bcbfce7b0119538bab06801c97aa9c7d4bf3a6c6) --- source4/lib/registry/common/reg_interface.c | 27 +++++++++++++++------------ source4/lib/registry/reg_backend_ldb.c | 17 ++++++++++------- 2 files changed, 25 insertions(+), 19 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 2382e4aa43..cd0b54e2dc 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -149,7 +149,8 @@ WERROR reg_get_hive(struct registry_context *ctx, uint32_t hkey, struct registry /* Open a registry file/host/etc */ WERROR reg_open_hive(struct registry_context *parent_ctx, const char *backend, const char *location, const char *credentials, struct registry_key **root) { - struct registry_hive *ret; + struct registry_hive *rethive; + struct registry_key *retkey; struct reg_init_function_entry *entry; WERROR werr; @@ -164,28 +165,30 @@ WERROR reg_open_hive(struct registry_context *parent_ctx, const char *backend, c return WERR_NOT_SUPPORTED; } - ret = talloc_p(parent_ctx, struct registry_hive); - ret->location = location?talloc_strdup(ret, location):NULL; - ret->functions = entry->hive_functions; - ret->backend_data = NULL; - ret->reg_ctx = parent_ctx; + rethive = talloc_p(parent_ctx, struct registry_hive); + rethive->location = location?talloc_strdup(rethive, location):NULL; + rethive->functions = entry->hive_functions; + rethive->backend_data = NULL; + rethive->reg_ctx = parent_ctx; - werr = entry->hive_functions->open_hive(ret, &ret->root); + werr = entry->hive_functions->open_hive(rethive, &retkey); + + rethive->root = retkey; if(!W_ERROR_IS_OK(werr)) { return werr; } - if(!ret->root) { + if(!retkey) { DEBUG(0, ("Backend %s didn't provide root key!\n", backend)); return WERR_GENERAL_FAILURE; } - ret->root->hive = ret; - ret->root->name = NULL; - ret->root->path = talloc_strdup(ret, ""); + retkey->hive = rethive; + retkey->name = NULL; + retkey->path = talloc_strdup(retkey, ""); - *root = ret->root; + *root = retkey; return WERR_OK; } diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 7804a68d3d..b20a56046d 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -29,6 +29,15 @@ struct ldb_key_data int subkey_count, value_count; }; +static int ldb_close_hive (void *_hive) +{ + struct registry_hive *hive = _hive; + ldb_close (hive->backend_data); + return 0; +} + + + static int reg_close_ldb_key (void *data) { struct registry_key *key = data; @@ -189,6 +198,7 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) hive->root = talloc_zero_p(hive, struct registry_key); talloc_set_destructor (hive->root, reg_close_ldb_key); + talloc_set_destructor (hive, ldb_close_hive); hive->root->name = talloc_strdup(hive->root, ""); hive->root->backend_data = kd = talloc_zero_p(hive->root, struct ldb_key_data); kd->dn = talloc_strdup(hive->root, "key=root"); @@ -240,18 +250,11 @@ static WERROR ldb_del_key (struct registry_key *key) return WERR_OK; } -static WERROR ldb_close_hive (struct registry_hive *hive) -{ - ldb_close (hive->backend_data); - return WERR_OK; -} - static struct hive_operations reg_backend_ldb = { .name = "ldb", .add_key = ldb_add_key, .del_key = ldb_del_key, .open_hive = ldb_open_hive, - .close_hive = ldb_close_hive, .open_key = ldb_open_key, .get_value_by_index = ldb_get_value_by_id, .get_subkey_by_index = ldb_get_subkey_by_id, -- cgit From 0bde7a2944fded24af8a9b19a3bb42015bbdd6bb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 10 Dec 2004 23:13:17 +0000 Subject: r4141: Fix crash bug in ldb backend (This used to be commit 5f64a60374486b9fc3d75786c3035a9017dd4d33) --- source4/lib/registry/common/reg_interface.c | 8 ++++---- source4/lib/registry/reg_backend_ldb.c | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index cd0b54e2dc..b7211d92a4 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -150,7 +150,7 @@ WERROR reg_get_hive(struct registry_context *ctx, uint32_t hkey, struct registry WERROR reg_open_hive(struct registry_context *parent_ctx, const char *backend, const char *location, const char *credentials, struct registry_key **root) { struct registry_hive *rethive; - struct registry_key *retkey; + struct registry_key *retkey = NULL; struct reg_init_function_entry *entry; WERROR werr; @@ -173,17 +173,17 @@ WERROR reg_open_hive(struct registry_context *parent_ctx, const char *backend, c werr = entry->hive_functions->open_hive(rethive, &retkey); - rethive->root = retkey; - if(!W_ERROR_IS_OK(werr)) { return werr; } - + if(!retkey) { DEBUG(0, ("Backend %s didn't provide root key!\n", backend)); return WERR_GENERAL_FAILURE; } + rethive->root = retkey; + retkey->hive = rethive; retkey->name = NULL; retkey->path = talloc_strdup(retkey, ""); diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index b20a56046d..e848507634 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -196,12 +196,12 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) ldb_set_debug_stderr(c); hive->backend_data = c; - hive->root = talloc_zero_p(hive, struct registry_key); - talloc_set_destructor (hive->root, reg_close_ldb_key); + *k = talloc_zero_p(hive, struct registry_key); + talloc_set_destructor (*k, reg_close_ldb_key); talloc_set_destructor (hive, ldb_close_hive); - hive->root->name = talloc_strdup(hive->root, ""); - hive->root->backend_data = kd = talloc_zero_p(hive->root, struct ldb_key_data); - kd->dn = talloc_strdup(hive->root, "key=root"); + (*k)->name = talloc_strdup(*k, ""); + (*k)->backend_data = kd = talloc_zero_p(*k, struct ldb_key_data); + kd->dn = talloc_strdup(*k, "key=root"); return WERR_OK; -- cgit From 6cf13f4d72beee3df0432d0898c5981ce8bced43 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 11 Dec 2004 17:12:16 +0000 Subject: r4154: Add definitions for HKEY_PERFORMANCE_TEXT and HKEY_PERFORMANCE_NLSTEXT Hives and predefined keys (HKEY_*) are not necessarily the same thing. (This used to be commit 217e4e5841cfedb2b18dce3f89dd88ea4a36fe8f) --- source4/lib/registry/common/reg_interface.c | 20 ++++++++++---------- source4/lib/registry/tools/regdiff.c | 2 +- source4/lib/registry/tools/regtree.c | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index b7211d92a4..ba65e570c4 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -74,7 +74,7 @@ BOOL reg_has_backend(const char *backend) } static struct { - uint32 hkey; + enum reg_predefined_key handle; const char *name; } hkey_names[] = { @@ -85,30 +85,30 @@ static struct { {HKEY_USERS, "HKEY_USERS" }, {HKEY_CURRENT_CONFIG, "HKEY_CURRENT_CONFIG" }, {HKEY_DYN_DATA, "HKEY_DYN_DATA" }, - {HKEY_PT, "HKEY_PT" }, - {HKEY_PN, "HKEY_PN" }, + {HKEY_PERFORMANCE_TEXT, "HKEY_PERFORMANCE_TEXT" }, + {HKEY_PERFORMANCE_NLSTEXT, "HKEY_PERFORMANCE_NLSTEXT" }, { 0, NULL } }; -int reg_list_hives(TALLOC_CTX *mem_ctx, char ***hives, uint32_t **hkeys) +int reg_list_predefs(TALLOC_CTX *mem_ctx, char ***hives, enum reg_predefined_key **hkeys) { int i; *hives = talloc_array_p(mem_ctx, char *, ARRAY_SIZE(hkey_names)); - *hkeys = talloc_array_p(mem_ctx, uint32_t, ARRAY_SIZE(hkey_names)); + *hkeys = talloc_array_p(mem_ctx, enum reg_predefined_key, ARRAY_SIZE(hkey_names)); for (i = 0; hkey_names[i].name; i++) { (*hives)[i] = talloc_strdup(mem_ctx, hkey_names[i].name); - (*hkeys)[i] = hkey_names[i].hkey; + (*hkeys)[i] = hkey_names[i].handle; } return i; } -const char *reg_get_hkey_name(uint32_t hkey) +const char *reg_get_hkey_name(enum reg_predefined_key hkey) { int i; for (i = 0; hkey_names[i].name; i++) { - if (hkey_names[i].hkey == hkey) return hkey_names[i].name; + if (hkey_names[i].handle == hkey) return hkey_names[i].name; } return NULL; @@ -119,7 +119,7 @@ WERROR reg_get_hive_by_name(struct registry_context *ctx, const char *name, stru int i; for (i = 0; hkey_names[i].name; i++) { - if (!strcmp(hkey_names[i].name, name)) return reg_get_hive(ctx, hkey_names[i].hkey, key); + if (!strcmp(hkey_names[i].name, name)) return reg_get_hive(ctx, hkey_names[i].handle, key); } DEBUG(1, ("No hive with name '%s'\n", name)); @@ -134,7 +134,7 @@ WERROR reg_close (struct registry_context *ctx) return WERR_OK; } -WERROR reg_get_hive(struct registry_context *ctx, uint32_t hkey, struct registry_key **key) +WERROR reg_get_hive(struct registry_context *ctx, enum reg_predefined_key hkey, struct registry_key **key) { WERROR ret = ctx->get_hive(ctx, hkey, key); diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index fc2954b6af..dfa85d636f 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -173,7 +173,7 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, error2 = error = WERR_OK; - for(i = HKEY_CLASSES_ROOT; i <= HKEY_PN; i++) { + for(i = HKEY_CLASSES_ROOT; i <= HKEY_PERFORMANCE_NLSTEXT; i++) { struct registry_key *r1, *r2; error = reg_get_hive(h1, i, &r1); if (!W_ERROR_IS_OK(error)) { diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 8ff68229eb..7adeeea731 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -123,7 +123,7 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) if (!h) { print_tree(0, root, fullpath, no_values); } else { - for(i = HKEY_CLASSES_ROOT; i < HKEY_PN; i++) { + for(i = HKEY_CLASSES_ROOT; i < HKEY_PERFORMANCE_NLSTEXT; i++) { error = reg_get_hive(h, i, &root); if (!W_ERROR_IS_OK(error)) { fprintf(stderr, "Skipping %s\n", reg_get_hkey_name(i)); -- cgit From 969e14eae941427cf36c71b5588d7dd8e1f3c615 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 11 Dec 2004 20:06:40 +0000 Subject: r4155: More destinction between hives and predefined keys (This used to be commit c37d6f3c581673d74e7ec6a644ab6a7d13a55535) --- source4/lib/registry/README | 15 ++++++- source4/lib/registry/common/reg_interface.c | 61 ++++++++++++++--------------- source4/lib/registry/reg_backend_rpc.c | 5 +-- source4/lib/registry/reg_samba.c | 19 +++++++-- source4/lib/registry/tools/regdiff.c | 8 ++-- source4/lib/registry/tools/regshell.c | 25 +----------- source4/lib/registry/tools/regtree.c | 4 +- 7 files changed, 67 insertions(+), 70 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/README b/source4/lib/registry/README index 757029cdc2..c91d361acd 100644 --- a/source4/lib/registry/README +++ b/source4/lib/registry/README @@ -1,6 +1,5 @@ This is the registry library. The registry is basically a bunch of hives -(HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, etc) that can be loaded from -different places. +that can be loaded from different places. The various registry backends provide support for loading/saving specific types of hives: @@ -28,3 +27,15 @@ registry:HKEY_CURRENT_USER = nt4:NTUSER.DAT registry:HKEY_LOCAL_MACHINE = ldb:tdb://registry.tdb WERR_NOT_SUPPORTED will be returned for all hives that haven't been set. + +On Windows the various registry hives are loaded from: + +HKEY_CURRENT_CONFIG: %SystemRoot%\System32\Config\System +HKEY_CURRENT_USER: %Profile%\NTUser.dat +HKEY_LOCAL_MACHINE\SAM: %SystemRoot%\System32\Config\Sam +HKEY_LOCAL_MACHINE\Security: %SystemRoot%\System32\Config\Security +HKEY_LOCAL_MACHINE\Software: %SystemRoot%\System32\Config\Software +HKEY_LOCAL_MACHINE\System: %SystemRoot%\System32\Config\System +HKEY_USERS\.DEFAULT: %SystemRoot%\System32\Config\Default +HKEY_LOCAL_MACHINE\HARDWARE: is autogenerated + diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index ba65e570c4..ee140e150f 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -74,9 +74,9 @@ BOOL reg_has_backend(const char *backend) } static struct { - enum reg_predefined_key handle; + uint32_t handle; const char *name; -} hkey_names[] = +} predef_names[] = { {HKEY_CLASSES_ROOT,"HKEY_CLASSES_ROOT" }, {HKEY_CURRENT_USER,"HKEY_CURRENT_USER" }, @@ -90,39 +90,39 @@ static struct { { 0, NULL } }; -int reg_list_predefs(TALLOC_CTX *mem_ctx, char ***hives, enum reg_predefined_key **hkeys) +int reg_list_predefs(TALLOC_CTX *mem_ctx, char ***predefs, uint32_t **hkeys) { int i; - *hives = talloc_array_p(mem_ctx, char *, ARRAY_SIZE(hkey_names)); - *hkeys = talloc_array_p(mem_ctx, enum reg_predefined_key, ARRAY_SIZE(hkey_names)); + *predefs = talloc_array_p(mem_ctx, char *, ARRAY_SIZE(predef_names)); + *hkeys = talloc_array_p(mem_ctx, uint32_t, ARRAY_SIZE(predef_names)); - for (i = 0; hkey_names[i].name; i++) { - (*hives)[i] = talloc_strdup(mem_ctx, hkey_names[i].name); - (*hkeys)[i] = hkey_names[i].handle; + for (i = 0; predef_names[i].name; i++) { + (*predefs)[i] = talloc_strdup(mem_ctx, predef_names[i].name); + (*hkeys)[i] = predef_names[i].handle; } return i; } -const char *reg_get_hkey_name(enum reg_predefined_key hkey) +const char *reg_get_predef_name(uint32_t hkey) { int i; - for (i = 0; hkey_names[i].name; i++) { - if (hkey_names[i].handle == hkey) return hkey_names[i].name; + for (i = 0; predef_names[i].name; i++) { + if (predef_names[i].handle == hkey) return predef_names[i].name; } return NULL; } -WERROR reg_get_hive_by_name(struct registry_context *ctx, const char *name, struct registry_key **key) +WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, const char *name, struct registry_key **key) { int i; - for (i = 0; hkey_names[i].name; i++) { - if (!strcmp(hkey_names[i].name, name)) return reg_get_hive(ctx, hkey_names[i].handle, key); + for (i = 0; predef_names[i].name; i++) { + if (!strcmp(predef_names[i].name, name)) return reg_get_predefined_key(ctx, predef_names[i].handle, key); } - DEBUG(1, ("No hive with name '%s'\n", name)); + DEBUG(1, ("No predefined key with name '%s'\n", name)); return WERR_BADFILE; } @@ -134,12 +134,12 @@ WERROR reg_close (struct registry_context *ctx) return WERR_OK; } -WERROR reg_get_hive(struct registry_context *ctx, enum reg_predefined_key hkey, struct registry_key **key) +WERROR reg_get_predefined_key(struct registry_context *ctx, uint32_t hkey, struct registry_key **key) { - WERROR ret = ctx->get_hive(ctx, hkey, key); + WERROR ret = ctx->get_predefined_key(ctx, hkey, key); if (W_ERROR_IS_OK(ret)) { - (*key)->name = talloc_strdup(*key, reg_get_hkey_name(hkey)); + (*key)->name = talloc_strdup(*key, reg_get_predef_name(hkey)); (*key)->path = ""; } @@ -147,7 +147,7 @@ WERROR reg_get_hive(struct registry_context *ctx, enum reg_predefined_key hkey, } /* Open a registry file/host/etc */ -WERROR reg_open_hive(struct registry_context *parent_ctx, const char *backend, const char *location, const char *credentials, struct registry_key **root) +WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *backend, const char *location, const char *credentials, struct registry_key **root) { struct registry_hive *rethive; struct registry_key *retkey = NULL; @@ -169,7 +169,6 @@ WERROR reg_open_hive(struct registry_context *parent_ctx, const char *backend, c rethive->location = location?talloc_strdup(rethive, location):NULL; rethive->functions = entry->hive_functions; rethive->backend_data = NULL; - rethive->reg_ctx = parent_ctx; werr = entry->hive_functions->open_hive(rethive, &retkey); @@ -193,26 +192,26 @@ WERROR reg_open_hive(struct registry_context *parent_ctx, const char *backend, c return WERR_OK; } -/* Open a key by name (including the hive name!) */ +/* Open a key by name (including the predefined key name!) */ WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result) { - struct registry_key *hive; + struct registry_key *predef; WERROR error; - int hivelength; - char *hivename; + int predeflength; + char *predefname; - if(strchr(name, '\\')) hivelength = strchr(name, '\\')-name; - else hivelength = strlen(name); + if(strchr(name, '\\')) predeflength = strchr(name, '\\')-name; + else predeflength = strlen(name); - hivename = strndup(name, hivelength); - error = reg_get_hive_by_name(handle, hivename, &hive); - SAFE_FREE(hivename); + predefname = strndup(name, predeflength); + error = reg_get_predefined_key_by_name(handle, predefname, &predef); + SAFE_FREE(predefname); if(!W_ERROR_IS_OK(error)) { return error; } - return reg_open_key(mem_ctx, hive, name, result); + return reg_open_key(mem_ctx, predef, name, result); } /* Open a key @@ -484,7 +483,7 @@ WERROR reg_key_add_name_recursive_abs(struct registry_context *handle, const cha else hivelength = strlen(name); hivename = strndup(name, hivelength); - error = reg_get_hive_by_name(handle, hivename, &hive); + error = reg_get_predefined_key_by_name(handle, hivename, &hive); SAFE_FREE(hivename); if(!W_ERROR_IS_OK(error)) return error; diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 927ed7fcaa..78c45f6365 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -93,7 +93,7 @@ struct { static WERROR rpc_query_key(struct registry_key *k); -static WERROR rpc_get_hive (struct registry_context *ctx, uint32 hkey_type, struct registry_key **k) +static WERROR rpc_get_predefined_key (struct registry_context *ctx, uint32 hkey_type, struct registry_key **k) { int n; struct registry_hive *h; @@ -113,7 +113,6 @@ static WERROR rpc_get_hive (struct registry_context *ctx, uint32 hkey_type, stru h->functions = ®_backend_rpc; h->location = NULL; h->backend_data = ctx->backend_data; - h->reg_ctx = ctx; (*k) = h->root = talloc_p(h, struct registry_key); (*k)->hive = h; @@ -380,7 +379,7 @@ WERROR reg_open_remote (struct registry_context **ctx, const char *user, const c return ntstatus_to_werror(status); } - (*ctx)->get_hive = rpc_get_hive; + (*ctx)->get_predefined_key = rpc_get_predefined_key; talloc_set_destructor(*ctx, rpc_close); diff --git a/source4/lib/registry/reg_samba.c b/source4/lib/registry/reg_samba.c index a19029524d..62973a14ab 100644 --- a/source4/lib/registry/reg_samba.c +++ b/source4/lib/registry/reg_samba.c @@ -23,12 +23,12 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_REGISTRY -static WERROR reg_samba_get_hive (struct registry_context *ctx, uint32 hkey, struct registry_key **k) +static WERROR reg_samba_get_predef (struct registry_context *ctx, uint32 hkey, struct registry_key **k) { WERROR error; const char *conf; char *backend, *location; - const char *hivename = reg_get_hkey_name(hkey); + const char *hivename = reg_get_predef_name(hkey); *k = NULL; @@ -45,7 +45,18 @@ static WERROR reg_samba_get_hive (struct registry_context *ctx, uint32 hkey, str *location = '\0'; location++; } - + + /* FIXME: Different hive backend for HKEY_CLASSES_ROOT: merged view of HKEY_LOCAL_MACHINE\Software\Classes + * and HKEY_CURRENT_USER\Software\Classes */ + + /* FIXME: HKEY_CURRENT_CONFIG is an alias for HKEY_LOCAL_MACHINE\System\CurrentControlSet\Hardware Profiles\Current */ + + /* FIXME: HKEY_PERFORMANCE_DATA is dynamically generated */ + + /* FIXME: HKEY_LOCAL_MACHINE\Hardware is autogenerated */ + + /* FIXME: HKEY_LOCAL_MACHINE\Security\SAM is an alias for HKEY_LOCAL_MACHINE\SAM */ + error = reg_open_hive(ctx, backend, location, NULL, k); talloc_destroy(backend); @@ -56,7 +67,7 @@ static WERROR reg_samba_get_hive (struct registry_context *ctx, uint32 hkey, str WERROR reg_open_local (struct registry_context **ctx) { *ctx = talloc_p(NULL, struct registry_context); - (*ctx)->get_hive = reg_samba_get_hive; + (*ctx)->get_predefined_key = reg_samba_get_predef; return WERR_OK; } diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index dfa85d636f..8d88cafe59 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -175,15 +175,15 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, for(i = HKEY_CLASSES_ROOT; i <= HKEY_PERFORMANCE_NLSTEXT; i++) { struct registry_key *r1, *r2; - error = reg_get_hive(h1, i, &r1); + error = reg_get_predefined_key(h1, i, &r1); if (!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Unable to open hive %s for backend 1\n", reg_get_hkey_name(i))); + DEBUG(0, ("Unable to open hive %s for backend 1\n", reg_get_predef_name(i))); continue; } - error = reg_get_hive(h2, i, &r2); + error = reg_get_predefined_key(h2, i, &r2); if (!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Unable to open hive %s for backend 2\n", reg_get_hkey_name(i))); + DEBUG(0, ("Unable to open hive %s for backend 2\n", reg_get_predef_name(i))); continue; } diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 3fd9dab268..47d84c1f62 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -162,28 +162,6 @@ static struct registry_key *cmd_rmval(TALLOC_CTX *mem_ctx, struct registry_key * return NULL; } -static struct registry_key *cmd_hive(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) -{ - if (!cur->hive->reg_ctx) { - fprintf(stderr, "Only one hive loaded\n"); - return cur; - } - - if (argc == 1) { - printf("%s\n", cur->hive->root->name); - } else { - struct registry_key *newroot; - WERROR error = reg_get_hive_by_name(cur->hive->reg_ctx, argv[1], &newroot); - if (W_ERROR_IS_OK(error)) { - return newroot; - } else { - fprintf(stderr, "Can't switch to hive %s: %s\n", cur->hive->root->name, win_errstr(error)); - } - } - - return NULL; -} - static struct registry_key *cmd_exit(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) { exit(0); @@ -199,7 +177,6 @@ struct { struct registry_key *(*handle)(TALLOC_CTX *mem_ctx, struct registry_key *, int argc, char **argv); } regshell_cmds[] = { {"ck", "cd", "Change current key", cmd_ck }, - {"ch", "hive", "Change current hive", cmd_hive }, {"info", "i", "Show detailed information of a key", cmd_info }, {"list", "ls", "List values/keys in current key", cmd_ls }, {"mkkey", "mkdir", "Make new key", cmd_mkkey }, @@ -407,7 +384,7 @@ static char **reg_completion(const char *text, int start, int end) if (h) { /*FIXME: What if HKEY_CLASSES_ROOT is not present ? */ - reg_get_hive(h, HKEY_CLASSES_ROOT, &curkey); + reg_get_predefined_key(h, HKEY_CLASSES_ROOT, &curkey); } poptFreeContext(pc); diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 7adeeea731..a6beb2b484 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -124,9 +124,9 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) print_tree(0, root, fullpath, no_values); } else { for(i = HKEY_CLASSES_ROOT; i < HKEY_PERFORMANCE_NLSTEXT; i++) { - error = reg_get_hive(h, i, &root); + error = reg_get_predefined_key(h, i, &root); if (!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Skipping %s\n", reg_get_hkey_name(i)); + fprintf(stderr, "Skipping %s\n", reg_get_predef_name(i)); continue; } print_tree(0, root, fullpath, no_values); -- cgit From 47fa1d33e4a6b9aeaf06ad2c12d9744bdf967bb9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 13 Dec 2004 00:45:29 +0000 Subject: r4166: More small API fixes, keep registry structs as small as possible. Implement DelValue in the RPC server (This used to be commit f6b9ec89af934e837069fb26c0e3491fc78ebc12) --- source4/lib/registry/common/reg_interface.c | 13 ++++--------- source4/lib/registry/reg_backend_dir.c | 16 +--------------- source4/lib/registry/reg_backend_ldb.c | 2 +- source4/lib/registry/reg_backend_rpc.c | 1 - source4/lib/registry/reg_backend_w95.c | 1 - source4/lib/registry/tools/regpatch.c | 6 +----- source4/lib/registry/tools/regshell.c | 8 +------- 7 files changed, 8 insertions(+), 39 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index ee140e150f..79bb0b765c 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -281,8 +281,6 @@ WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *key, return WERR_NOT_SUPPORTED; } - (*val)->parent = key; - (*val)->hive = key->hive; return WERR_OK; } @@ -408,9 +406,6 @@ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key, if(!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) return error; - (*val)->parent = key; - (*val)->hive = key->hive; - return WERR_OK; } @@ -447,7 +442,7 @@ WERROR reg_key_del_recursive(struct registry_key *key) } if(W_ERROR_IS_OK(error)) { - error = reg_del_value(val); + error = reg_del_value(key, val->name); if(!W_ERROR_IS_OK(error)) { talloc_destroy(mem_ctx); return error; @@ -564,13 +559,13 @@ WERROR reg_val_set(struct registry_key *key, const char *value, int type, void * -WERROR reg_del_value(struct registry_value *val) +WERROR reg_del_value(struct registry_key *key, const char *valname) { WERROR ret = WERR_OK; - if(!val->hive->functions->del_value) + if(!key->hive->functions->del_value) return WERR_NOT_SUPPORTED; - ret = val->hive->functions->del_value(val); + ret = key->hive->functions->del_value(key, valname); if(!W_ERROR_IS_OK(ret)) return ret; diff --git a/source4/lib/registry/reg_backend_dir.c b/source4/lib/registry/reg_backend_dir.c index c004be5a06..89f9280585 100644 --- a/source4/lib/registry/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir.c @@ -120,27 +120,13 @@ static WERROR reg_dir_open(struct registry_hive *h, struct registry_key **key) return WERR_OK; } -static WERROR reg_dir_set_value(struct registry_key *p, const char *name, int type, void *data, int len) -{ - /* FIXME */ - return WERR_NOT_SUPPORTED; -} - -static WERROR reg_dir_del_value(struct registry_value *v) -{ - /* FIXME*/ - return WERR_NOT_SUPPORTED; -} - static struct hive_operations reg_backend_dir = { .name = "dir", .open_hive = reg_dir_open, .open_key = reg_dir_open_key, .add_key = reg_dir_add_key, .del_key = reg_dir_del_key, - .get_subkey_by_index = reg_dir_key_by_index, - .set_value = reg_dir_set_value, - .del_value = reg_dir_del_value, + .get_subkey_by_index = reg_dir_key_by_index }; NTSTATUS registry_dir_init(void) diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index e848507634..ec8a6d9de3 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -144,7 +144,7 @@ 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); - (*value)->backend_data = talloc_strdup(mem_ctx, kd->values[idx]->dn); + /* FIXME */ return WERR_OK; } diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 78c45f6365..16516d25b7 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -218,7 +218,6 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *p if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result) && r.out.length) { *value = talloc_p(mem_ctx, struct registry_value); - (*value)->parent = parent; (*value)->name = talloc_strdup(mem_ctx, r.out.name_out.name); (*value)->data_type = type; (*value)->data_len = *r.out.length; diff --git a/source4/lib/registry/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95.c index a94ad86c2c..957039dea3 100644 --- a/source4/lib/registry/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95.c @@ -332,7 +332,6 @@ static WERROR w95_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, i } *value = talloc_p(mem_ctx, struct registry_value); - (*value)->backend_data = curval; (*value)->name = talloc_strndup(mem_ctx, (char *)curval+sizeof(RGDB_VALUE), curval->name_len); (*value)->data_len = curval->data_len; diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index a4a4649c96..18589a9285 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -701,13 +701,9 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd while (cmd->val_count) { VAL_SPEC_LIST *val = cmd->val_spec_list; - struct registry_value *reg_val = NULL; if (val->type == REG_DELETE) { - error = reg_key_get_value_by_name( mem_ctx, tmp, val->name, ®_val); - if(W_ERROR_IS_OK(error)) { - error = reg_del_value(reg_val); - } + error = reg_del_value(tmp, val->name); if(!W_ERROR_IS_OK(error)) { DEBUG(0, ("Error removing value '%s'\n", val->name)); } diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 47d84c1f62..0a09708869 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -142,18 +142,12 @@ static struct registry_key *cmd_rmkey(TALLOC_CTX *mem_ctx, struct registry_key * static struct registry_key *cmd_rmval(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) { - struct registry_value *val; if(argc < 2) { fprintf(stderr, "Usage: rmval \n"); return NULL; } - if(!W_ERROR_IS_OK(reg_key_get_value_by_name(mem_ctx, cur, argv[1], &val))) { - fprintf(stderr, "No such value '%s'\n", argv[1]); - return NULL; - } - - if(!W_ERROR_IS_OK(reg_del_value(val))) { + if(!W_ERROR_IS_OK(reg_del_value(cur, argv[1]))) { fprintf(stderr, "Error deleting value '%s'\n", argv[1]); } else { fprintf(stderr, "Successfully deleted value '%s'\n", argv[1]); -- cgit From 4c202a20fa7008264ad676ffb2238424bd27baf8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 13 Dec 2004 01:37:18 +0000 Subject: r4167: Fix CreateKey Support CreateKey in the RPC registry backend (This used to be commit ad8d9e6f73619332d93c38a1879233e199e8ba25) --- source4/lib/registry/reg_backend_rpc.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 16516d25b7..b14b67d609 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -259,7 +259,32 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key * 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) { - return WERR_NOT_SUPPORTED; + NTSTATUS status; + struct winreg_CreateKey r; + + init_winreg_String(&r.in.key, name); + init_winreg_String(&r.in.class, NULL); + + r.in.handle = parent->backend_data; + r.out.handle = talloc_p(mem_ctx, struct policy_handle); + r.in.options = 0; + r.in.access_mask = access_mask; + r.in.sec_desc = NULL; + + status = dcerpc_winreg_CreateKey((struct dcerpc_pipe *)(parent->hive->backend_data), mem_ctx, &r); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("CreateKey failed - %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); + } + + if (W_ERROR_IS_OK(r.out.result)) { + *key = talloc_p(mem_ctx, struct registry_key); + (*key)->name = talloc_strdup(*key, name); + (*key)->backend_data = r.out.handle; + } + + return r.out.result; } static WERROR rpc_query_key(struct registry_key *k) -- cgit From 1a340869c43f9ce741e8a4bd28ea01ec63301df5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 14 Dec 2004 20:49:18 +0000 Subject: r4204: Arguments to reg_del_key more like the RPC for more efficient usage Fix small bug in regpatch Fix segfault in regshell cmdline completion Implement set_value and del_value in ldb backend (This used to be commit 8e2aa58abeafa78afe7dafb9723f5f365e756527) --- source4/lib/registry/common/reg_interface.c | 155 +--------------------------- source4/lib/registry/common/reg_util.c | 87 ++++++++++++++++ source4/lib/registry/reg_backend_dir.c | 11 +- source4/lib/registry/reg_backend_ldb.c | 62 ++++++++++- source4/lib/registry/reg_backend_rpc.c | 18 +--- source4/lib/registry/tools/regpatch.c | 16 +-- source4/lib/registry/tools/regshell.c | 15 +-- 7 files changed, 172 insertions(+), 192 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 79bb0b765c..c729945a26 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -192,28 +192,6 @@ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *backend, const char *lo return WERR_OK; } -/* Open a key by name (including the predefined key name!) */ -WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result) -{ - struct registry_key *predef; - WERROR error; - int predeflength; - char *predefname; - - if(strchr(name, '\\')) predeflength = strchr(name, '\\')-name; - else predeflength = strlen(name); - - predefname = strndup(name, predeflength); - error = reg_get_predefined_key_by_name(handle, predefname, &predef); - SAFE_FREE(predefname); - - if(!W_ERROR_IS_OK(error)) { - return error; - } - - return reg_open_key(mem_ctx, predef, name, result); -} - /* Open a key * First tries to use the open_key function from the backend * then falls back to get_subkey_by_name and later get_subkey_by_index @@ -409,123 +387,21 @@ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key, return WERR_OK; } -WERROR reg_key_del(struct registry_key *key) +WERROR reg_key_del(struct registry_key *parent, const char *name) { WERROR error; - if(!key) return WERR_INVALID_PARAM; + if(!parent) return WERR_INVALID_PARAM; - if(!key->hive->functions->del_key) + if(!parent->hive->functions->del_key) return WERR_NOT_SUPPORTED; - error = key->hive->functions->del_key(key); + error = parent->hive->functions->del_key(parent, name); if(!W_ERROR_IS_OK(error)) return error; return WERR_OK; } -WERROR reg_key_del_recursive(struct registry_key *key) -{ - WERROR error = WERR_OK; - int i; - - TALLOC_CTX *mem_ctx = talloc_init("del_recursive"); - - /* Delete all values for specified key */ - for(i = 0; W_ERROR_IS_OK(error); i++) { - struct registry_value *val; - error = reg_key_get_value_by_index(mem_ctx, key, i, &val); - if(!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) - { - talloc_destroy(mem_ctx); - return error; - } - - if(W_ERROR_IS_OK(error)) { - error = reg_del_value(key, val->name); - if(!W_ERROR_IS_OK(error)) { - talloc_destroy(mem_ctx); - return error; - } - } - } - - error = WERR_OK; - - /* Delete all keys below this one */ - for(i = 0; W_ERROR_IS_OK(error); i++) { - struct registry_key *subkey; - - error = reg_key_get_subkey_by_index(mem_ctx, key, i, &subkey); - if(!W_ERROR_IS_OK(error)) { talloc_destroy(mem_ctx); return error; } - - error = reg_key_del_recursive(subkey); - if(!W_ERROR_IS_OK(error)) { talloc_destroy(mem_ctx); return error; } - } - - talloc_destroy(mem_ctx); - return reg_key_del(key); -} - -WERROR reg_key_add_name_recursive_abs(struct registry_context *handle, const char *name) -{ - struct registry_key *hive; - WERROR error; - int hivelength; - char *hivename; - - if(strchr(name, '\\')) hivelength = strchr(name, '\\')-name; - else hivelength = strlen(name); - - hivename = strndup(name, hivelength); - error = reg_get_predefined_key_by_name(handle, hivename, &hive); - SAFE_FREE(hivename); - - if(!W_ERROR_IS_OK(error)) return error; - - return reg_key_add_name_recursive(hive, name); -} - -WERROR reg_key_add_name_recursive(struct registry_key *parent, const char *path) -{ - struct registry_key *cur, *prevcur = parent; - WERROR error = WERR_OK; - char *dups, *begin, *end; - TALLOC_CTX *mem_ctx = talloc_init("add_recursive"); - - begin = dups = strdup(path); - - while(1) { - end = strchr(begin, '\\'); - if(end) *end = '\0'; - - error = reg_key_get_subkey_by_name(mem_ctx, prevcur, begin, &cur); - - /* Key is not there, add it */ - if(W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) { - error = reg_key_add_name(mem_ctx, prevcur, begin, 0, NULL, &cur); - if(!W_ERROR_IS_OK(error)) break; - } - - if(!W_ERROR_IS_OK(error)) { - if(end) *end = '\\'; - break; - } - - if(!end) { - error = WERR_OK; - break; - } - - *end = '\\'; - begin = end+1; - prevcur = cur; - } - SAFE_FREE(dups); - talloc_destroy(mem_ctx); - return error; -} - 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 error; @@ -547,7 +423,7 @@ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, struct registry_key *parent, const return WERR_OK; } -WERROR reg_val_set(struct registry_key *key, const char *value, int type, void *data, int len) +WERROR reg_val_set(struct registry_key *key, const char *value, uint32 type, void *data, int len) { /* A 'real' set function has preference */ if (key->hive->functions->set_value) @@ -577,27 +453,6 @@ WERROR reg_save (struct registry_context *ctx, const char *location) return WERR_NOT_SUPPORTED; } -WERROR reg_key_get_parent(TALLOC_CTX *mem_ctx, struct registry_key *key, struct registry_key **parent) -{ - char *parent_name; - char *last; - struct registry_key *root = NULL; - WERROR error; - - parent_name = strdup(key->path); - last = strrchr(parent_name, '\\'); - - if(!last) { - SAFE_FREE(parent_name); - return WERR_FOOBAR; - } - *last = '\0'; - - error = reg_open_key(mem_ctx, root, parent_name, parent); - SAFE_FREE(parent_name); - return error; -} - WERROR reg_key_flush(struct registry_key *key) { if (!key) { diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index 052ccc347b..1d1f770324 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -150,3 +150,90 @@ char *reg_path_unix2win(char *path) } return path; } + +/* Open a key by name (including the predefined key name!) */ +WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result) +{ + struct registry_key *predef; + WERROR error; + int predeflength; + char *predefname; + + if(strchr(name, '\\')) predeflength = strchr(name, '\\')-name; + else predeflength = strlen(name); + + predefname = strndup(name, predeflength); + error = reg_get_predefined_key_by_name(handle, predefname, &predef); + SAFE_FREE(predefname); + + if(!W_ERROR_IS_OK(error)) { + return error; + } + + if (strchr(name, '\\')) { + return reg_open_key(mem_ctx, predef, strchr(name, '\\')+1, result); + } else { + *result = predef; + return WERR_OK; + } +} + +static WERROR get_abs_parent(TALLOC_CTX *mem_ctx, struct registry_context *ctx, const char *path, struct registry_key **parent, const char **name) +{ + char *parent_name; + WERROR error; + + if (strchr(path, '\\') == NULL) { + return WERR_FOOBAR; + } + + parent_name = talloc_strndup(mem_ctx, path, strrchr(path, '\\')-1-path); + + error = reg_open_key_abs(mem_ctx, ctx, parent_name, parent); + if (!W_ERROR_IS_OK(error)) { + return error; + } + + *name = talloc_strdup(mem_ctx, strchr(path, '\\')+1); + + return WERR_OK; +} + +WERROR reg_key_del_abs(struct registry_context *ctx, const char *path) +{ + struct registry_key *parent; + const char *n; + TALLOC_CTX *mem_ctx = talloc_init("reg_key_del_abs"); + WERROR error; + + if (!strchr(path, '\\')) { + return WERR_FOOBAR; + } + + error = get_abs_parent(mem_ctx, ctx, path, &parent, &n); + if (W_ERROR_IS_OK(error)) { + error = reg_key_del(parent, n); + } + + talloc_destroy(mem_ctx); + + 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) +{ + struct registry_key *parent; + const char *n; + WERROR error; + + if (!strchr(path, '\\')) { + return WERR_FOOBAR; + } + + error = get_abs_parent(mem_ctx, ctx, path, &parent, &n); + if (W_ERROR_IS_OK(error)) { + error = reg_key_add_name(mem_ctx, parent, n, access_mask, sec_desc, result); + } + + return error; +} diff --git a/source4/lib/registry/reg_backend_dir.c b/source4/lib/registry/reg_backend_dir.c index 89f9280585..41a0da58c0 100644 --- a/source4/lib/registry/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir.c @@ -34,9 +34,16 @@ static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, return WERR_INVALID_PARAM; } -static WERROR reg_dir_del_key(struct registry_key *k) +static WERROR reg_dir_del_key(struct registry_key *k, const char *name) { - return (rmdir((char *)k->backend_data) == 0)?WERR_OK:WERR_GENERAL_FAILURE; + char *child = talloc_asprintf(NULL, "%s/%s", (char *)k->backend_data, name); + WERROR ret; + + if (rmdir(child) == 0) ret = WERR_OK; else ret = WERR_GENERAL_FAILURE; + + talloc_destroy(child); + + return ret; } static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, struct registry_key *p, const char *name, struct registry_key **subkey) diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index ec8a6d9de3..7a63f4a530 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -235,12 +235,15 @@ static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, struct registry_key *parent, con return WERR_OK; } -static WERROR ldb_del_key (struct registry_key *key) +static WERROR ldb_del_key (struct registry_key *key, const char *child) { int ret; struct ldb_key_data *kd = key->backend_data; + char *childdn = talloc_asprintf(NULL, "key=%s,%s", child, kd->dn); - ret = ldb_delete(key->hive->backend_data, kd->dn); + ret = ldb_delete(key->hive->backend_data, childdn); + + talloc_destroy(childdn); if (ret < 0) { DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(key->hive->backend_data))); @@ -250,6 +253,59 @@ static WERROR ldb_del_key (struct registry_key *key) return WERR_OK; } +static WERROR ldb_del_value (struct registry_key *key, const char *child) +{ + int ret; + struct ldb_key_data *kd = key->backend_data; + char *childdn = talloc_asprintf(NULL, "value=%s,%s", child, kd->dn); + + ret = ldb_delete(key->hive->backend_data, childdn); + + talloc_destroy(childdn); + + if (ret < 0) { + DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(key->hive->backend_data))); + return WERR_FOOBAR; + } + + return WERR_OK; +} + +static WERROR ldb_set_value (struct registry_key *parent, const char *name, uint32 type, void *data, int len) +{ + struct ldb_context *ctx = parent->hive->backend_data; + struct ldb_message msg; + struct ldb_val val; + 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)); + + ldb_msg_add_string(ctx, &msg, "value", talloc_strdup(mem_ctx, name)); + val.length = len; + val.data = data; + ldb_msg_add_value(ctx, &msg, "data", &val); + + type_s = talloc_asprintf(mem_ctx, "%u", type); + ldb_msg_add_string(ctx, &msg, "type", type_s); + + ret = ldb_add(ctx, &msg); + if (ret < 0) { + ret = ldb_modify(ctx, &msg); + if (ret < 0) { + DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parent->hive->backend_data))); + talloc_destroy(mem_ctx); + return WERR_FOOBAR; + } + } + + talloc_destroy(mem_ctx); + return WERR_OK; +} + static struct hive_operations reg_backend_ldb = { .name = "ldb", .add_key = ldb_add_key, @@ -258,6 +314,8 @@ static struct hive_operations reg_backend_ldb = { .open_key = ldb_open_key, .get_value_by_index = ldb_get_value_by_id, .get_subkey_by_index = ldb_get_subkey_by_id, + .set_value = ldb_set_value, + .del_value = ldb_del_value, }; NTSTATUS registry_ldb_init(void) diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index b14b67d609..224a061762 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -315,27 +315,17 @@ static WERROR rpc_query_key(struct registry_key *k) return r.out.result; } -static WERROR rpc_del_key(struct registry_key *k) +static WERROR rpc_del_key(struct registry_key *parent, const char *name) { NTSTATUS status; - struct rpc_key_data *mykeydata = k->backend_data; + struct rpc_key_data *mykeydata = parent->backend_data; struct winreg_DeleteKey r; - struct registry_key *parent; - WERROR error; TALLOC_CTX *mem_ctx = talloc_init("del_key"); - error = reg_key_get_parent(mem_ctx, k, &parent); - if(!W_ERROR_IS_OK(error)) { - talloc_destroy(mem_ctx); - return error; - } - - mykeydata = parent->backend_data; - r.in.handle = &mykeydata->pol; - init_winreg_String(&r.in.key, k->name); + init_winreg_String(&r.in.key, name); - status = dcerpc_winreg_DeleteKey((struct dcerpc_pipe *)k->hive->backend_data, mem_ctx, &r); + status = dcerpc_winreg_DeleteKey((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r); talloc_destroy(mem_ctx); diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 18589a9285..600c1f60e7 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -686,13 +686,7 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd /* If we found it, apply the other bits, else create such a key */ if (W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) { - if(W_ERROR_IS_OK(reg_key_add_name_recursive_abs(r, cmd->key))) { - error = reg_open_key_abs(mem_ctx, r, cmd->key, &tmp); - if(!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error finding new key '%s' after it has been added\n", cmd->key)); - continue; - } - } else { + if(!W_ERROR_IS_OK(reg_key_add_abs(mem_ctx, r, cmd->key, 0, NULL, &tmp))) { DEBUG(0, ("Error adding new key '%s'\n", cmd->key)); continue; } @@ -730,13 +724,7 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd * Find the key if it exists, and delete it ... */ - error = reg_open_key_abs(mem_ctx, r, cmd->key, &tmp); - if(!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Unable to open key '%s'\n", cmd->key)); - continue; - } - - error = reg_key_del_recursive(tmp); + error = reg_key_del_abs(r, cmd->key); if(!W_ERROR_IS_OK(error)) { DEBUG(0, ("Unable to delete key '%s'\n", cmd->key)); continue; diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 0a09708869..6de8b25c9c 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -120,18 +120,12 @@ static struct registry_key *cmd_mkkey(TALLOC_CTX *mem_ctx, struct registry_key * static struct registry_key *cmd_rmkey(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv) { - struct registry_key *key; if(argc < 2) { fprintf(stderr, "Usage: rmkey \n"); return NULL; } - if(!W_ERROR_IS_OK(reg_open_key(mem_ctx, cur, argv[1], &key))) { - fprintf(stderr, "No such subkey '%s'\n", argv[1]); - return NULL; - } - - if(!W_ERROR_IS_OK(reg_key_del(key))) { + if(!W_ERROR_IS_OK(reg_key_del(cur, argv[1]))) { fprintf(stderr, "Error deleting '%s'\n", argv[1]); } else { fprintf(stderr, "Successfully deleted '%s'\n", argv[1]); @@ -259,9 +253,10 @@ static char **reg_complete_command(const char *text, int end) return matches; cleanup: - while (i >= 0) { - free(matches[i]); - i--; + count--; + while (count >= 0) { + free(matches[count]); + count--; } free(matches); return NULL; -- cgit 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/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 ++++++++++++++++++++--------- 7 files changed, 160 insertions(+), 67 deletions(-) (limited to 'source4/lib/registry') 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; } } -- cgit From efdf83f4a676d8c8faa66e3c073c72a0d649bde8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 15 Dec 2004 02:27:22 +0000 Subject: r4213: Store REG_SZ in UTF16, not the unix charset.. It is now possible to use the "Add..." button in the Security tab of the File Properties Dialog box. (This used to be commit 9fa25260d3f18dd0dd041477c48571b53d86f3c4) --- source4/lib/registry/common/reg_util.c | 10 ++++------ source4/lib/registry/reg_backend_nt4.c | 7 ------- 2 files changed, 4 insertions(+), 13 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index 68144fc56f..3da875ca0b 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -57,11 +57,10 @@ char *reg_val_data_string(TALLOC_CTX *mem_ctx, struct registry_value *v) if(v->data_len == 0) return talloc_strdup(mem_ctx, ""); switch (v->data_type) { - case REG_SZ: - return talloc_strndup(mem_ctx, v->data_blk, v->data_len); - case REG_EXPAND_SZ: - return talloc_strndup(mem_ctx, v->data_blk, v->data_len); + case REG_SZ: + convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, v->data_blk, v->data_len, (void **)&ret); + return ret; case REG_BINARY: ret = talloc(mem_ctx, v->data_len * 3 + 2); @@ -120,8 +119,7 @@ BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *da { case REG_SZ: case REG_EXPAND_SZ: - (*value)->data_blk = talloc_strdup(mem_ctx, data_str); - (*value)->data_len = strlen(data_str); + (*value)->data_len = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, data_str, strlen(data_str), &(*value)->data_blk); break; case REG_DWORD: (*value)->data_len = sizeof(uint32); diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index 5633156b20..6c48b9bd1b 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -935,13 +935,6 @@ static WERROR vk_to_val(TALLOC_CTX *mem_ctx, struct registry_key *parent, VK_HDR } - if(tmp->data_type == REG_SZ) { - char *ret; - dat_len = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, dtmp, dat_len, (void **)&ret); - dtmp = ret; - } - - tmp->data_blk = dtmp; tmp->data_len = dat_len; } -- cgit From 616cf701281331bf0bcad56cbfd22ca22576e3d1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 21 Dec 2004 00:01:02 +0000 Subject: r4298: Update to credentials.h after feedback from Andrew Bartlett Move pack/unpack of values in ldb registry backend to seperate functions (This used to be commit ceb4e92735f6dae96bb0b9d98211c9808159e56a) --- source4/lib/registry/reg_backend_ldb.c | 59 ++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 25 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 9b0b5759ce..9435da5dd6 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -36,6 +36,32 @@ static int ldb_close_hive (void *_hive) return 0; } +static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, char **name, uint32 *type, void **data, int *len) +{ + const struct ldb_val *val; + *name = talloc_strdup(mem_ctx, ldb_msg_find_string(msg, "value", NULL)); + *type = ldb_msg_find_uint(msg, "type", 0); + val = ldb_msg_find_ldb_val(msg, "data"); + *data = talloc_memdup(mem_ctx, val->data, val->length); + *len = val->length; +} + +static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, const char *name, uint32 type, void *data, int len) +{ + struct ldb_val val; + struct ldb_message *msg = talloc_zero_p(mem_ctx, struct ldb_message); + char *type_s; + + ldb_msg_add_string(ctx, msg, "value", talloc_strdup(mem_ctx, name)); + val.length = len; + val.data = data; + ldb_msg_add_value(ctx, msg, "data", &val); + + type_s = talloc_asprintf(mem_ctx, "%u", type); + ldb_msg_add_string(ctx, msg, "type", type_s); + + return msg; +} static int reg_close_ldb_key (void *data) @@ -121,9 +147,7 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_value **value) { 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) { @@ -136,15 +160,10 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, i } if(idx >= kd->value_count) return WERR_NO_MORE_ITEMS; - - el = ldb_msg_find_element(kd->values[idx], "value"); - + *value = talloc_p(mem_ctx, struct registry_value); - (*value)->name = talloc_strdup(mem_ctx, el->values[0].data); - (*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; + + reg_ldb_unpack_value(mem_ctx, kd->values[idx], &(*value)->name, &(*value)->data_type, &(*value)->data_blk, &(*value)->data_len); return WERR_OK; } @@ -275,28 +294,18 @@ static WERROR ldb_del_value (struct registry_key *key, const char *child) static WERROR ldb_set_value (struct registry_key *parent, const char *name, uint32 type, void *data, int len) { struct ldb_context *ctx = parent->hive->backend_data; - struct ldb_message msg; - struct ldb_val val; + struct ldb_message *msg; 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 = talloc_asprintf(mem_ctx, "value=%s,%s", name, kd->dn); + msg = reg_ldb_pack_value(ctx, mem_ctx, name, type, data, len); - ldb_msg_add_string(ctx, &msg, "value", talloc_strdup(mem_ctx, name)); - val.length = len; - val.data = data; - ldb_msg_add_value(ctx, &msg, "data", &val); + msg->dn = talloc_asprintf(mem_ctx, "value=%s,%s", name, kd->dn); - type_s = talloc_asprintf(mem_ctx, "%u", type); - ldb_msg_add_string(ctx, &msg, "type", type_s); - - ret = ldb_add(ctx, &msg); + ret = ldb_add(ctx, msg); if (ret < 0) { - ret = ldb_modify(ctx, &msg); + ret = ldb_modify(ctx, msg); if (ret < 0) { DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parent->hive->backend_data))); talloc_destroy(mem_ctx); -- cgit From 9547649006770022bdcddcc319b81b555222f1c4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 21 Dec 2004 00:31:18 +0000 Subject: r4299: Store REG_SZ, REG_EXPAND_SZ and REG_DWORD values in human-readable (and human-editable) format in the ldb registry backend. (This used to be commit 6eafd055d1a7d45734a0112228e18ee59d1f7867) --- source4/lib/registry/common/reg_util.c | 2 +- source4/lib/registry/reg_backend_ldb.c | 40 +++++++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 6 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index 3da875ca0b..3a17369144 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -124,7 +124,7 @@ BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *da case REG_DWORD: (*value)->data_len = sizeof(uint32); (*value)->data_blk = talloc_p(mem_ctx, uint32); - *((uint32 *)(*value)->data_blk) = atol(data_str); + *((uint32 *)(*value)->data_blk) = strtol(data_str, NULL, 0); break; case REG_NONE: diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 9435da5dd6..f7b743fd72 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -42,8 +42,25 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, c *name = talloc_strdup(mem_ctx, ldb_msg_find_string(msg, "value", NULL)); *type = ldb_msg_find_uint(msg, "type", 0); val = ldb_msg_find_ldb_val(msg, "data"); - *data = talloc_memdup(mem_ctx, val->data, val->length); - *len = val->length; + + switch (*type) + { + case REG_SZ: + case REG_EXPAND_SZ: + *len = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, val->data, val->length, data); + break; + + case REG_DWORD_LE: + *len = 4; + *data = talloc_p(mem_ctx, uint32); + SIVAL(*data, 0, strtol(val->data, NULL, 0)); + break; + + default: + *data = talloc_memdup(mem_ctx, val->data, val->length); + *len = val->length; + break; + } } static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, const char *name, uint32 type, void *data, int len) @@ -53,9 +70,22 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, TALLOC_CT char *type_s; ldb_msg_add_string(ctx, msg, "value", talloc_strdup(mem_ctx, name)); - val.length = len; - val.data = data; - ldb_msg_add_value(ctx, msg, "data", &val); + + switch (type) { + case REG_SZ: + case REG_EXPAND_SZ: + val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8, data, len, &val.data); + ldb_msg_add_value(ctx, msg, "data", &val); + break; + case REG_DWORD_LE: + ldb_msg_add_string(ctx, msg, "data", talloc_asprintf(mem_ctx, "0x%x", IVAL(data, 0))); + break; + default: + val.length = len; + val.data = data; + ldb_msg_add_value(ctx, msg, "data", &val); + } + type_s = talloc_asprintf(mem_ctx, "%u", type); ldb_msg_add_string(ctx, msg, "type", type_s); -- cgit From b0e6ce645a433c8972eb131cbc4cf0aed3ce1055 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 26 Dec 2004 22:41:38 +0000 Subject: r4371: Add "Create Key", "Delete Key" and "Delete Value" buttons. gregedit now can do the same things as regedt32 except for finding data and setting values. (and a few segfaults...) (This used to be commit ada16f31e4da919731767ce31000aa270f22ffd5) --- source4/lib/registry/reg_backend_ldb.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index f7b743fd72..ffb9215cf0 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -237,12 +237,13 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) if (!hive->location) return WERR_INVALID_PARAM; 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))); + if(!wrap) { + DEBUG(1, ("ldb_open_hive: unable to connect\n")); return WERR_FOOBAR; } + + c = wrap->ldb; + ldb_set_debug_stderr(c); hive->backend_data = c; -- cgit From dcff66281cc7da27b06d605af90fed74076da19f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 27 Dec 2004 00:32:13 +0000 Subject: r4373: Support setting values and fix a segfault (This used to be commit cdb6980cdcf4b093e98b3b025f784333d46ac957) --- source4/lib/registry/common/reg_interface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index f5c3598721..e48fe38eb9 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -273,10 +273,10 @@ WERROR reg_key_num_subkeys(struct registry_key *key, int *count) if(key->hive->functions->get_subkey_by_index) { int i; WERROR error; - struct registry_key *dest; + struct registry_key *dest = NULL; TALLOC_CTX *mem_ctx = talloc_init("num_subkeys"); - for(i = 0; W_ERROR_IS_OK(error = key->hive->functions->get_subkey_by_index(mem_ctx, key, i, &dest)); i++); + for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(mem_ctx, key, i, &dest)); i++); talloc_destroy(mem_ctx); *count = i; -- cgit From f05bc12213477676967b5c1780c8cca61b262317 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 29 Dec 2004 12:28:35 +0000 Subject: r4390: Registry value and key names are case-insensitive Nicer menu layout in gregedit (This used to be commit 2948b9750d756880c3af7fb352f0a684a1fae9c9) --- source4/lib/registry/common/reg_interface.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index e48fe38eb9..9b03a69f3f 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -119,7 +119,7 @@ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, const char * int i; for (i = 0; predef_names[i].name; i++) { - if (!strcmp(predef_names[i].name, name)) return reg_get_predefined_key(ctx, predef_names[i].handle, key); + if (!strcasecmp(predef_names[i].name, name)) return reg_get_predefined_key(ctx, predef_names[i].handle, key); } DEBUG(1, ("No predefined key with name '%s'\n", name)); @@ -347,7 +347,7 @@ WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key, } else if(key->hive->functions->get_subkey_by_index) { 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)) { + if(W_ERROR_IS_OK(error) && !strcasecmp((*subkey)->name, name)) { break; } } @@ -378,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) && !strcmp((*val)->name, name)) { + if(W_ERROR_IS_OK(error) && !strcasecmp((*val)->name, name)) { break; } } -- cgit From 500d5523d2a83234d6bfbf264d78293426488bfc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 2 Jan 2005 07:51:13 +0000 Subject: r4475: fixed smbd to work with the small changes in the ldb API (the most important change was in the ldb_msg_add_*() routines, which now use the msg as a context, and thus it needs to be a talloc ptr) (This used to be commit 1a4713bfd0e519f3eb7b3241121ff914a6eeef18) --- source4/lib/registry/reg_backend_ldb.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index ffb9215cf0..e0d7b6e2cb 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -261,17 +261,17 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) 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; + struct ldb_message *msg; struct ldb_key_data *newkd; int ret; - ZERO_STRUCT(msg); + msg = ldb_msg_new(mem_ctx); - msg.dn = reg_path_to_ldb(mem_ctx, parent, name, NULL); + msg->dn = reg_path_to_ldb(msg, parent, name, NULL); - ldb_msg_add_string(ctx, &msg, "key", talloc_strdup(mem_ctx, name)); + ldb_msg_add_string(ctx, msg, "key", talloc_strdup(mem_ctx, name)); - ret = ldb_add(ctx, &msg); + ret = ldb_add(ctx, msg); if (ret < 0) { DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parent->hive->backend_data))); return WERR_FOOBAR; @@ -281,7 +281,7 @@ static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, struct registry_key *parent, con (*newkey)->name = talloc_strdup(mem_ctx, name); (*newkey)->backend_data = newkd = talloc_zero_p(*newkey, struct ldb_key_data); - newkd->dn = msg.dn; + newkd->dn = talloc_steal(newkd, msg->dn); return WERR_OK; } -- cgit From f4b349127bdfe233476fe2efba961912f39a5cbd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 2 Jan 2005 12:55:33 +0000 Subject: r4479: added the function talloc_autofree_context() which returns a talloc context that will automatically be freed on program exit. This is useful for reducing clutter in leak reports (This used to be commit cf73dda652e0a121901f22771104be6751c0fcb9) --- source4/lib/registry/common/reg_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 9b03a69f3f..442b34bc13 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -44,7 +44,7 @@ NTSTATUS registry_register(const void *_hive_ops) return NT_STATUS_OBJECT_NAME_COLLISION; } - entry = talloc_p(NULL, struct reg_init_function_entry); + entry = talloc_p(talloc_autofree_context(), struct reg_init_function_entry); entry->hive_functions = hive_ops; DLIST_ADD(backends, entry); -- cgit From ddc10d4d37984246a6547e34a32d629c689c40d1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Jan 2005 03:06:58 +0000 Subject: r4549: got rid of a lot more uses of plain talloc(), instead using talloc_size() or talloc_array_p() where appropriate. also fixed a memory leak in pvfs_copy_file() (failed to free a memory context) (This used to be commit 89b74b53546e1570b11b3702f40bee58aed8c503) --- source4/lib/registry/common/reg_util.c | 2 +- source4/lib/registry/reg_backend_nt4.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index 3a17369144..67c62fe5c8 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -63,7 +63,7 @@ char *reg_val_data_string(TALLOC_CTX *mem_ctx, struct registry_value *v) return ret; case REG_BINARY: - ret = talloc(mem_ctx, v->data_len * 3 + 2); + ret = talloc_array(mem_ctx, 3, v->data_len+1, "REG_BINARY"); asciip = ret; for (i=0; idata_len; i++) { int str_rem = v->data_len * 3 - (asciip - ret); diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index 6c48b9bd1b..cd3be85a23 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -917,7 +917,7 @@ static WERROR vk_to_val(TALLOC_CTX *mem_ctx, struct registry_key *parent, VK_HDR if (dat_len&0x7FFFFFFF) { - char *dtmp = (char *)talloc(mem_ctx, dat_len&0x7FFFFFFF); + char *dtmp = talloc_size(mem_ctx, dat_len&0x7FFFFFFF); if ((dat_len&0x80000000) == 0) { /* The data is pointed to by the offset */ char *dat_ptr = LOCN(regf->base, dat_off); -- cgit From 11ce2cfd70df264c5c91b4daaa9a01c5abc673b0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Jan 2005 04:39:16 +0000 Subject: r4591: - converted the other _p talloc functions to not need _p - added #if TALLOC_DEPRECATED around the _p functions - fixes the code that broke from the above while doing this I fixed quite a number of places that were incorrectly using the non type-safe talloc functions to use the type safe ones. Some were even doing multiplies for array allocation, which is potentially unsafe. (This used to be commit 6e7754abd0c225527fb38363996a6e241b87b37e) --- source4/lib/registry/common/reg_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index 67c62fe5c8..ef46dd6174 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -63,7 +63,7 @@ char *reg_val_data_string(TALLOC_CTX *mem_ctx, struct registry_value *v) return ret; case REG_BINARY: - ret = talloc_array(mem_ctx, 3, v->data_len+1, "REG_BINARY"); + ret = talloc_array_size(mem_ctx, 3, v->data_len+1); asciip = ret; for (i=0; idata_len; i++) { int str_rem = v->data_len * 3 - (asciip - ret); -- cgit From 1303f51099c2054c3966c6ba34490c5ffad85c13 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 9 Jan 2005 19:06:49 +0000 Subject: r4623: Convert values from UTF8 to UTF16 in gconf registry backend (caught by Andrew Bartlett) (This used to be commit da3c7712d234291f9c5a3c48daae02bdf0878bf0) --- source4/lib/registry/reg_backend_gconf.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_gconf.c b/source4/lib/registry/reg_backend_gconf.c index b53d0fedf5..47d8c760ab 100644 --- a/source4/lib/registry/reg_backend_gconf.c +++ b/source4/lib/registry/reg_backend_gconf.c @@ -72,6 +72,7 @@ static WERROR gconf_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *p, GConfValue *value; struct registry_value *newval; char *fullpath = p->backend_data; + const char *tmp; int i; cur = entries = gconf_client_all_entries((GConfClient*)p->hive->backend_data, fullpath, NULL); @@ -92,8 +93,8 @@ static WERROR gconf_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *p, case GCONF_VALUE_STRING: newval->data_type = REG_SZ; - newval->data_blk = talloc_strdup(mem_ctx, gconf_value_get_string(value)); - newval->data_len = strlen(newval->data_blk); + tmp = gconf_value_get_string(value); + newval->data_len = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, tmp, strlen(tmp), &(newval->data_blk)); break; case GCONF_VALUE_INT: @@ -149,7 +150,7 @@ static WERROR gconf_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *p return WERR_OK; } -static WERROR gconf_set_value(struct registry_key *key, const char *valname, int type, void *data, int len) +static WERROR gconf_set_value(struct registry_key *key, const char *valname, uint32 type, void *data, int len) { GError *error = NULL; char *valpath; -- cgit From 759da3b915e2006d4c87b5ace47f399accd9ce91 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 27 Jan 2005 07:08:20 +0000 Subject: r5037: got rid of all of the TALLOC_DEPRECATED stuff. My apologies for the large commit. I thought this was worthwhile to get done for consistency. (This used to be commit ec32b22ed5ec224f6324f5e069d15e92e38e15c0) --- source4/lib/registry/common/reg_interface.c | 18 ++++++++--------- source4/lib/registry/common/reg_util.c | 6 +++--- source4/lib/registry/reg_backend_dir.c | 8 ++++---- source4/lib/registry/reg_backend_gconf.c | 14 +++++++------- source4/lib/registry/reg_backend_ldb.c | 30 ++++++++++++++--------------- source4/lib/registry/reg_backend_nt4.c | 6 +++--- source4/lib/registry/reg_backend_rpc.c | 24 +++++++++++------------ source4/lib/registry/reg_backend_w95.c | 12 ++++++------ source4/lib/registry/reg_samba.c | 4 ++-- source4/lib/registry/tools/regdiff.c | 8 ++++---- source4/lib/registry/tools/regshell.c | 8 ++++---- source4/lib/registry/tools/regtree.c | 4 ++-- 12 files changed, 71 insertions(+), 71 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 442b34bc13..8385cef108 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -44,7 +44,7 @@ NTSTATUS registry_register(const void *_hive_ops) return NT_STATUS_OBJECT_NAME_COLLISION; } - entry = talloc_p(talloc_autofree_context(), struct reg_init_function_entry); + entry = talloc(talloc_autofree_context(), struct reg_init_function_entry); entry->hive_functions = hive_ops; DLIST_ADD(backends, entry); @@ -93,8 +93,8 @@ static struct { int reg_list_predefs(TALLOC_CTX *mem_ctx, char ***predefs, uint32_t **hkeys) { int i; - *predefs = talloc_array_p(mem_ctx, char *, ARRAY_SIZE(predef_names)); - *hkeys = talloc_array_p(mem_ctx, uint32_t, ARRAY_SIZE(predef_names)); + *predefs = talloc_array(mem_ctx, char *, ARRAY_SIZE(predef_names)); + *hkeys = talloc_array(mem_ctx, uint32_t, ARRAY_SIZE(predef_names)); for (i = 0; predef_names[i].name; i++) { (*predefs)[i] = talloc_strdup(mem_ctx, predef_names[i].name); @@ -129,7 +129,7 @@ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, const char * WERROR reg_close (struct registry_context *ctx) { - talloc_destroy(ctx); + talloc_free(ctx); return WERR_OK; } @@ -165,7 +165,7 @@ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *backend, const char *lo return WERR_NOT_SUPPORTED; } - rethive = talloc_p(parent_ctx, struct registry_hive); + rethive = talloc(parent_ctx, struct registry_hive); rethive->location = location?talloc_strdup(rethive, location):NULL; rethive->functions = entry->hive_functions; rethive->backend_data = NULL; @@ -277,7 +277,7 @@ WERROR reg_key_num_subkeys(struct registry_key *key, int *count) TALLOC_CTX *mem_ctx = talloc_init("num_subkeys"); for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(mem_ctx, key, i, &dest)); i++); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); *count = i; if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) error = WERR_OK; @@ -303,7 +303,7 @@ WERROR reg_key_num_values(struct registry_key *key, int *count) 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); + talloc_free(mem_ctx); *count = i; if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) error = WERR_OK; @@ -490,7 +490,7 @@ WERROR reg_key_subkeysizes(struct registry_key *key, uint32 *max_subkeylen, uint i++; } while (W_ERROR_IS_OK(error)); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return WERR_OK; } @@ -517,7 +517,7 @@ WERROR reg_key_valuesizes(struct registry_key *key, uint32 *max_valnamelen, uint i++; } while (W_ERROR_IS_OK(error)); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return WERR_OK; } diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index ef46dd6174..b11b24151e 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -99,7 +99,7 @@ char *reg_val_description(TALLOC_CTX *mem_ctx, struct registry_value *val) BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, struct registry_value **value) { int i; - *value = talloc_p(mem_ctx, struct registry_value); + *value = talloc(mem_ctx, struct registry_value); (*value)->data_type = -1; /* Find the correct type */ @@ -123,7 +123,7 @@ BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *da break; case REG_DWORD: (*value)->data_len = sizeof(uint32); - (*value)->data_blk = talloc_p(mem_ctx, uint32); + (*value)->data_blk = talloc(mem_ctx, uint32); *((uint32 *)(*value)->data_blk) = strtol(data_str, NULL, 0); break; @@ -264,7 +264,7 @@ WERROR reg_key_del_abs(struct registry_context *ctx, const char *path) error = reg_key_del(parent, n); } - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return error; } diff --git a/source4/lib/registry/reg_backend_dir.c b/source4/lib/registry/reg_backend_dir.c index 4af219facb..bac0f43c20 100644 --- a/source4/lib/registry/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir.c @@ -41,7 +41,7 @@ static WERROR reg_dir_del_key(struct registry_key *k, const char *name) if (rmdir(child) == 0) ret = WERR_OK; else ret = WERR_GENERAL_FAILURE; - talloc_destroy(child); + talloc_free(child); return ret; } @@ -67,7 +67,7 @@ static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, struct registry_key *p, cons return WERR_BADFILE; } closedir(d); - ret = talloc_p(mem_ctx, struct registry_key); + ret = talloc(mem_ctx, struct registry_key); ret->hive = p->hive; ret->path = fullpath; ret->backend_data = unixpath; @@ -98,7 +98,7 @@ static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, struct registry_key *k, if(S_ISDIR(stbuf.st_mode)) { if(i == idx) { - (*key) = talloc_p(mem_ctx, struct registry_key); + (*key) = talloc(mem_ctx, struct registry_key); (*key)->name = e->d_name; (*key)->path = NULL; (*key)->backend_data = talloc_strdup(mem_ctx, thispath); @@ -122,7 +122,7 @@ static WERROR reg_dir_open(struct registry_hive *h, struct registry_key **key) { if(!h->location) return WERR_INVALID_PARAM; - *key = talloc_p(h, struct registry_key); + *key = talloc(h, struct registry_key); (*key)->backend_data = talloc_strdup(*key, h->location); return WERR_OK; } diff --git a/source4/lib/registry/reg_backend_gconf.c b/source4/lib/registry/reg_backend_gconf.c index 47d8c760ab..a912a42e55 100644 --- a/source4/lib/registry/reg_backend_gconf.c +++ b/source4/lib/registry/reg_backend_gconf.c @@ -35,7 +35,7 @@ static WERROR reg_open_gconf_hive(struct registry_hive *h, struct registry_key * h->backend_data = (void *)gconf_client_get_default(); if(!h->backend_data) return WERR_FOOBAR; - *k = talloc_p(h, struct registry_key); + *k = talloc(h, struct registry_key); (*k)->name = talloc_strdup(*k, ""); (*k)->path = talloc_strdup(*k, ""); (*k)->backend_data = talloc_strdup(*k, "/"); @@ -57,7 +57,7 @@ static WERROR gconf_open_key (TALLOC_CTX *mem_ctx, struct registry_key *h, const return WERR_DEST_NOT_FOUND; } - ret = talloc_p(mem_ctx, struct registry_key); + ret = talloc(mem_ctx, struct registry_key); ret->backend_data = fullpath; *key = ret; @@ -83,7 +83,7 @@ static WERROR gconf_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *p, entry = cur->data; value = gconf_entry_get_value(entry); - newval = talloc_p(mem_ctx, struct registry_value); + newval = talloc(mem_ctx, struct registry_value); newval->name = talloc_strdup(mem_ctx, strrchr(gconf_entry_get_key(entry), '/')+1); if(value) { switch(value->type) { @@ -99,20 +99,20 @@ static WERROR gconf_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *p, case GCONF_VALUE_INT: newval->data_type = REG_DWORD; - newval->data_blk = talloc_p(mem_ctx, long); + newval->data_blk = talloc(mem_ctx, long); *((long *)newval->data_blk) = gconf_value_get_int(value); newval->data_len = sizeof(long); break; case GCONF_VALUE_FLOAT: - newval->data_blk = talloc_p(mem_ctx, double); + newval->data_blk = talloc(mem_ctx, double); newval->data_type = REG_BINARY; *((double *)newval->data_blk) = gconf_value_get_float(value); newval->data_len = sizeof(double); break; case GCONF_VALUE_BOOL: - newval->data_blk = talloc_p(mem_ctx, BOOL); + newval->data_blk = talloc(mem_ctx, BOOL); newval->data_type = REG_BINARY; *((BOOL *)newval->data_blk) = gconf_value_get_bool(value); newval->data_len = sizeof(BOOL); @@ -142,7 +142,7 @@ static WERROR gconf_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *p if(!cur) return WERR_NO_MORE_ITEMS; - *sub = talloc_p(mem_ctx, struct registry_key); + *sub = talloc(mem_ctx, struct registry_key); (*sub)->name = talloc_strdup(mem_ctx, strrchr((char *)cur->data, '/')+1); (*sub)->backend_data = talloc_strdup(mem_ctx, cur->data); diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index e0d7b6e2cb..930ea9642e 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -52,7 +52,7 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, c case REG_DWORD_LE: *len = 4; - *data = talloc_p(mem_ctx, uint32); + *data = talloc(mem_ctx, uint32); SIVAL(*data, 0, strtol(val->data, NULL, 0)); break; @@ -66,7 +66,7 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, c static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, const char *name, uint32 type, void *data, int len) { struct ldb_val val; - struct ldb_message *msg = talloc_zero_p(mem_ctx, struct ldb_message); + struct ldb_message *msg = talloc_zero(mem_ctx, struct ldb_message); char *type_s; ldb_msg_add_string(ctx, msg, "value", talloc_strdup(mem_ctx, name)); @@ -165,10 +165,10 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, el = ldb_msg_find_element(kd->subkeys[idx], "key"); - *subkey = talloc_p(mem_ctx, struct registry_key); + *subkey = talloc(mem_ctx, struct registry_key); talloc_set_destructor(*subkey, reg_close_ldb_key); (*subkey)->name = talloc_strdup(mem_ctx, el->values[0].data); - (*subkey)->backend_data = newkd = talloc_zero_p(*subkey, struct ldb_key_data); + (*subkey)->backend_data = newkd = talloc_zero(*subkey, struct ldb_key_data); newkd->dn = talloc_strdup(mem_ctx, kd->subkeys[idx]->dn); return WERR_OK; @@ -191,7 +191,7 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, i if(idx >= kd->value_count) return WERR_NO_MORE_ITEMS; - *value = talloc_p(mem_ctx, struct registry_value); + *value = talloc(mem_ctx, struct registry_value); reg_ldb_unpack_value(mem_ctx, kd->values[idx], &(*value)->name, &(*value)->data_type, &(*value)->data_blk, &(*value)->data_len); @@ -217,10 +217,10 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const ch return WERR_FOOBAR; } - *key = talloc_p(mem_ctx, struct registry_key); + *key = talloc(mem_ctx, struct registry_key); talloc_set_destructor(*key, reg_close_ldb_key); (*key)->name = talloc_strdup(mem_ctx, strrchr(name, '\\')?strchr(name, '\\'):name); - (*key)->backend_data = newkd = talloc_zero_p(*key, struct ldb_key_data); + (*key)->backend_data = newkd = talloc_zero(*key, struct ldb_key_data); newkd->dn = talloc_strdup(mem_ctx, msg[0]->dn); ldb_search_free(c, msg); @@ -247,11 +247,11 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) ldb_set_debug_stderr(c); hive->backend_data = c; - *k = talloc_zero_p(hive, struct registry_key); + *k = talloc_zero(hive, struct registry_key); talloc_set_destructor (*k, reg_close_ldb_key); talloc_set_destructor (hive, ldb_close_hive); (*k)->name = talloc_strdup(*k, ""); - (*k)->backend_data = kd = talloc_zero_p(*k, struct ldb_key_data); + (*k)->backend_data = kd = talloc_zero(*k, struct ldb_key_data); kd->dn = talloc_strdup(*k, "hive="); @@ -277,10 +277,10 @@ static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, struct registry_key *parent, con return WERR_FOOBAR; } - *newkey = talloc_zero_p(mem_ctx, struct registry_key); + *newkey = talloc_zero(mem_ctx, struct registry_key); (*newkey)->name = talloc_strdup(mem_ctx, name); - (*newkey)->backend_data = newkd = talloc_zero_p(*newkey, struct ldb_key_data); + (*newkey)->backend_data = newkd = talloc_zero(*newkey, struct ldb_key_data); newkd->dn = talloc_steal(newkd, msg->dn); return WERR_OK; @@ -294,7 +294,7 @@ static WERROR ldb_del_key (struct registry_key *key, const char *child) ret = ldb_delete(key->hive->backend_data, childdn); - talloc_destroy(childdn); + talloc_free(childdn); if (ret < 0) { DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(key->hive->backend_data))); @@ -312,7 +312,7 @@ static WERROR ldb_del_value (struct registry_key *key, const char *child) ret = ldb_delete(key->hive->backend_data, childdn); - talloc_destroy(childdn); + talloc_free(childdn); if (ret < 0) { DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(key->hive->backend_data))); @@ -339,12 +339,12 @@ static WERROR ldb_set_value (struct registry_key *parent, const char *name, uint ret = ldb_modify(ctx, msg); if (ret < 0) { DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parent->hive->backend_data))); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return WERR_FOOBAR; } } - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return WERR_OK; } diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index cd3be85a23..88033a8a8b 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -902,7 +902,7 @@ static WERROR vk_to_val(TALLOC_CTX *mem_ctx, struct registry_key *parent, VK_HDR dat_len = IVAL(&vk_hdr->dat_len,0); /* If top bit, offset contains data */ dat_off = IVAL(&vk_hdr->dat_off,0); - tmp = talloc_p(mem_ctx, struct registry_value); + tmp = talloc(mem_ctx, struct registry_value); tmp->data_type = dat_type; if (flag & FLAG_HAS_NAME) { @@ -1070,7 +1070,7 @@ static WERROR nk_to_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, NK_HDR *nk return WERR_GENERAL_FAILURE; } - tmp = talloc_p(mem_ctx, struct registry_key); + tmp = talloc(mem_ctx, struct registry_key); tmp->name = talloc_strdup(mem_ctx, key_name); tmp->backend_data = nk_hdr; @@ -1574,7 +1574,7 @@ static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) uint_t regf_id, hbin_id; HBIN_HDR *hbin_hdr; - regf = (REGF *)talloc_p(h, REGF); + regf = (REGF *)talloc(h, REGF); memset(regf, 0, sizeof(REGF)); regf->owner_sid_str = NULL; /* FIXME: Fill in */ h->backend_data = regf; diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index c5ed9b2c88..d2809f644a 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -109,14 +109,14 @@ static WERROR rpc_get_predefined_key (struct registry_context *ctx, uint32 hkey_ return WERR_NO_MORE_ITEMS; } - h = talloc_p(ctx, struct registry_hive); + h = talloc(ctx, struct registry_hive); h->functions = ®_backend_rpc; h->location = NULL; h->backend_data = ctx->backend_data; - (*k) = h->root = talloc_p(h, struct registry_key); + (*k) = h->root = talloc(h, struct registry_key); (*k)->hive = h; - (*k)->backend_data = mykeydata = talloc_p(*k, struct rpc_key_data); + (*k)->backend_data = mykeydata = talloc(*k, struct rpc_key_data); mykeydata->num_values = -1; mykeydata->num_subkeys = -1; return known_hives[n].open((struct dcerpc_pipe *)ctx->backend_data, *k, &(mykeydata->pol)); @@ -135,7 +135,7 @@ static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) struct winreg_OpenKey r; struct rpc_key_data *mykeydata; - k->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data); + k->backend_data = mykeydata = talloc(mem_ctx, struct rpc_key_data); mykeydata->num_values = -1; mykeydata->num_subkeys = -1; @@ -159,10 +159,10 @@ static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const ch struct rpc_key_data *mykeydata; struct winreg_OpenKey r; - *key = talloc_p(mem_ctx, struct registry_key); + *key = talloc(mem_ctx, struct registry_key); (*key)->name = talloc_strdup(mem_ctx, name); - (*key)->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data); + (*key)->backend_data = mykeydata = talloc(mem_ctx, struct rpc_key_data); mykeydata->num_values = -1; mykeydata->num_subkeys = -1; @@ -217,7 +217,7 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *p if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result) && r.out.length) { - *value = talloc_p(mem_ctx, struct registry_value); + *value = talloc(mem_ctx, struct registry_value); (*value)->name = talloc_strdup(mem_ctx, r.out.name_out.name); (*value)->data_type = type; (*value)->data_len = *r.out.length; @@ -266,7 +266,7 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, cons init_winreg_String(&r.in.class, NULL); r.in.handle = parent->backend_data; - r.out.handle = talloc_p(mem_ctx, struct policy_handle); + r.out.handle = talloc(mem_ctx, struct policy_handle); r.in.options = 0; r.in.access_mask = access_mask; r.in.sec_desc = NULL; @@ -279,7 +279,7 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, cons } if (W_ERROR_IS_OK(r.out.result)) { - *key = talloc_p(mem_ctx, struct registry_key); + *key = talloc(mem_ctx, struct registry_key); (*key)->name = talloc_strdup(*key, name); (*key)->backend_data = r.out.handle; } @@ -298,7 +298,7 @@ static WERROR rpc_query_key(struct registry_key *k) r.in.handle = &mykeydata->pol; status = dcerpc_winreg_QueryInfoKey((struct dcerpc_pipe *)(k->hive->backend_data), mem_ctx, &r); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("QueryInfoKey failed - %s\n", nt_errstr(status))); @@ -327,7 +327,7 @@ static WERROR rpc_del_key(struct registry_key *parent, const char *name) status = dcerpc_winreg_DeleteKey((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return r.out.result; } @@ -374,7 +374,7 @@ WERROR reg_open_remote (struct registry_context **ctx, const char *user, const c NTSTATUS status; struct dcerpc_pipe *p; - *ctx = talloc_p(NULL, struct registry_context); + *ctx = talloc(NULL, struct registry_context); /* Default to local smbd if no connection is specified */ if (!location) { diff --git a/source4/lib/registry/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95.c index 957039dea3..ff02f4d12b 100644 --- a/source4/lib/registry/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95.c @@ -187,7 +187,7 @@ static WERROR w95_open_reg (struct registry_hive *h, struct registry_key **root) DWORD i; DWORD offset; - creg = talloc_p(h, CREG); + creg = talloc(h, CREG); memset(creg, 0, sizeof(CREG)); h->backend_data = creg; @@ -234,7 +234,7 @@ static WERROR w95_open_reg (struct registry_hive *h, struct registry_key **root) } #endif - creg->rgdb_keys = talloc_array_p(h, RGDB_KEY **, creg->creg_hdr->num_rgdb); + creg->rgdb_keys = talloc_array(h, RGDB_KEY **, creg->creg_hdr->num_rgdb); offset = 0; DEBUG(3, ("Reading %d rgdb entries\n", creg->creg_hdr->num_rgdb)); @@ -250,7 +250,7 @@ static WERROR w95_open_reg (struct registry_hive *h, struct registry_key **root) } - creg->rgdb_keys[i] = talloc_array_p(h, RGDB_KEY *, rgdb_hdr->max_id+1); + creg->rgdb_keys[i] = talloc_array(h, RGDB_KEY *, rgdb_hdr->max_id+1); memset(creg->rgdb_keys[i], 0, sizeof(RGDB_KEY *) * (rgdb_hdr->max_id+1)); parse_rgdb_block(creg, rgdb_hdr); @@ -259,7 +259,7 @@ static WERROR w95_open_reg (struct registry_hive *h, struct registry_key **root) } /* First element in rgkn should be root key */ - *root = talloc_p(h, struct registry_key); + *root = talloc(h, struct registry_key); (*root)->name = NULL; (*root)->backend_data = LOCN_RGKN(creg, sizeof(RGKN_HDR)); @@ -288,7 +288,7 @@ static WERROR w95_get_subkey_by_index (TALLOC_CTX *mem_ctx, struct registry_key DEBUG(0, ("Can't find %d,%d in RGDB table!\n", child->id.rgdb, child->id.id)); return WERR_FOOBAR; } - *key = talloc_p(mem_ctx, struct registry_key); + *key = talloc(mem_ctx, struct registry_key); (*key)->backend_data = child; (*key)->name = talloc_strndup(mem_ctx, (char *)rgdb_key + sizeof(RGDB_KEY), rgdb_key->name_len); return WERR_OK; @@ -331,7 +331,7 @@ static WERROR w95_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, i offset+=sizeof(RGDB_VALUE) + curval->name_len + curval->data_len; } - *value = talloc_p(mem_ctx, struct registry_value); + *value = talloc(mem_ctx, struct registry_value); (*value)->name = talloc_strndup(mem_ctx, (char *)curval+sizeof(RGDB_VALUE), curval->name_len); (*value)->data_len = curval->data_len; diff --git a/source4/lib/registry/reg_samba.c b/source4/lib/registry/reg_samba.c index 62973a14ab..a81b9e5a42 100644 --- a/source4/lib/registry/reg_samba.c +++ b/source4/lib/registry/reg_samba.c @@ -59,14 +59,14 @@ static WERROR reg_samba_get_predef (struct registry_context *ctx, uint32 hkey, s error = reg_open_hive(ctx, backend, location, NULL, k); - talloc_destroy(backend); + talloc_free(backend); return error; } WERROR reg_open_local (struct registry_context **ctx) { - *ctx = talloc_p(NULL, struct registry_context); + *ctx = talloc(NULL, struct registry_context); (*ctx)->get_predefined_key = reg_samba_get_predef; return WERR_OK; diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 8d88cafe59..ceae3a427e 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -41,7 +41,7 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, } } - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { DEBUG(0, ("Error occured while getting subkey by index: %d\n", W_ERROR_V(error1))); @@ -60,7 +60,7 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, writediff(t2, t1, out); } - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { DEBUG(0, ("Error occured while getting subkey by index: %d\n", W_ERROR_V(error1))); @@ -82,7 +82,7 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, } } - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { DEBUG(0, ("Error occured while getting value by index: %d\n", W_ERROR_V(error1))); @@ -101,7 +101,7 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, } } - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { DEBUG(0, ("Error occured while getting value by index: %d\n", W_ERROR_V(error1))); diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 1dd0e04561..ac7dbca49b 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -329,14 +329,14 @@ static char **reg_complete_key(const char *text, int start, int end) break; } else { printf("Error creating completion list: %s\n", win_errstr(status)); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return NULL; } } if (j == 1) { /* No matches at all */ SAFE_FREE(matches); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return NULL; } @@ -345,7 +345,7 @@ static char **reg_complete_key(const char *text, int start, int end) } else { asprintf(&matches[0], "%s%s", base_n, talloc_strndup(mem_ctx, matches[1], samelen)); } - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); matches[j] = NULL; return matches; @@ -435,7 +435,7 @@ static char **reg_completion(const char *text, int start, int end) if(new)curkey = new; } } - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return 0; } diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index a6beb2b484..f061f33bd3 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -47,7 +47,7 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(mem_ctx, p, i, &subkey)); i++) { print_tree(l+1, subkey, fullpath, novals); } - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { DEBUG(0, ("Error occured while fetching subkeys for '%s': %s\n", p->path, win_errstr(error))); @@ -62,7 +62,7 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) desc = reg_val_description(mem_ctx, value); printf("%s\n", desc); } - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { DEBUG(0, ("Error occured while fetching values for '%s': %s\n", p->path, win_errstr(error))); -- cgit From 73a0b6ea476ee19bb814c3257daca7c116d42872 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 31 Jan 2005 15:58:54 +0000 Subject: r5134: - fix types to always use _t types - add #include "system/filesys.h" where needed metze (This used to be commit 6bb07a0ed8a4baaeaa1d63bde8ce773364860fd2) --- source4/lib/registry/common/reg_interface.c | 6 +++--- source4/lib/registry/common/reg_util.c | 10 +++++----- source4/lib/registry/reg_backend_nt4.c | 1 + source4/lib/registry/reg_backend_w95.c | 1 + source4/lib/registry/tools/regpatch.c | 1 + 5 files changed, 11 insertions(+), 8 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 8385cef108..42bf8f9389 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -426,7 +426,7 @@ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, struct registry_key *parent, const return WERR_OK; } -WERROR reg_val_set(struct registry_key *key, const char *value, uint32 type, void *data, int len) +WERROR reg_val_set(struct registry_key *key, const char *value, uint32_t type, void *data, int len) { /* A 'real' set function has preference */ if (key->hive->functions->set_value) @@ -470,7 +470,7 @@ WERROR reg_key_flush(struct registry_key *key) return WERR_OK; } -WERROR reg_key_subkeysizes(struct registry_key *key, uint32 *max_subkeylen, uint32 *max_subkeysize) +WERROR reg_key_subkeysizes(struct registry_key *key, uint32_t *max_subkeylen, uint32_t *max_subkeysize) { int i = 0; struct registry_key *subkey; @@ -495,7 +495,7 @@ WERROR reg_key_subkeysizes(struct registry_key *key, uint32 *max_subkeylen, uint return WERR_OK; } -WERROR reg_key_valuesizes(struct registry_key *key, uint32 *max_valnamelen, uint32 *max_valbufsize) +WERROR reg_key_valuesizes(struct registry_key *key, uint32_t *max_valnamelen, uint32_t *max_valbufsize) { int i = 0; struct registry_value *value; diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index b11b24151e..d4fdc59d70 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -25,7 +25,7 @@ #define DBGC_CLASS DBGC_REGISTRY static const struct { - uint32 id; + uint32_t id; const char *name; } reg_value_types[] = { { REG_SZ, "REG_SZ" }, @@ -122,9 +122,9 @@ BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *da (*value)->data_len = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, data_str, strlen(data_str), &(*value)->data_blk); break; case REG_DWORD: - (*value)->data_len = sizeof(uint32); - (*value)->data_blk = talloc(mem_ctx, uint32); - *((uint32 *)(*value)->data_blk) = strtol(data_str, NULL, 0); + (*value)->data_len = sizeof(uint32_t); + (*value)->data_blk = talloc(mem_ctx, uint32_t); + *((uint32_t *)(*value)->data_blk) = strtol(data_str, NULL, 0); break; case REG_NONE: @@ -269,7 +269,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, struct security_descriptor *sec_desc, struct registry_key **result) +WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx, const char *path, uint32_t 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_nt4.c b/source4/lib/registry/reg_backend_nt4.c index 88033a8a8b..d700070cde 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -306,6 +306,7 @@ Hope this helps.... (Although it was "fun" for me to uncover this things, #include "includes.h" #include "registry.h" +#include "system/filesys.h" #include "system/shmem.h" #define REG_KEY_LIST_SIZE 10 diff --git a/source4/lib/registry/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95.c index ff02f4d12b..45b6105801 100644 --- a/source4/lib/registry/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95.c @@ -21,6 +21,7 @@ #include "includes.h" #include "registry.h" +#include "system/filesys.h" #include "system/shmem.h" /** diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 600c1f60e7..ee7568cc0f 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -24,6 +24,7 @@ #include "dynconfig.h" #include "registry.h" #include "lib/cmdline/popt_common.h" +#include "system/filesys.h" /* * Routines to parse a REGEDIT4 file -- cgit From 480ee7243c06aff088c6ad7c2fd122f87c58f42d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Feb 2005 23:10:31 +0000 Subject: r5240: Don't return WERR_OK when no values were found (reported by Matt Cobb) (This used to be commit f2e6d71584672e9bf0eaa7176d76781a30d317d1) --- source4/lib/registry/common/reg_interface.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 42bf8f9389..407d0d3345 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -384,10 +384,10 @@ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key, } } - if(!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) - return error; - - return WERR_OK; + if (W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) + return WERR_DEST_NOT_FOUND; + + return error; } WERROR reg_key_del(struct registry_key *parent, const char *name) -- cgit From e82aad1ce39a6b7a2e51b9e2cb494d74ec70e158 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 05:09:35 +0000 Subject: r5298: - got rid of pstring.h from includes.h. This at least makes it a bit less likely that anyone will use pstring for new code - got rid of winbind_client.h from includes.h. This one triggered a huge change, as winbind_client.h was including system/filesys.h and defining the old uint32 and uint16 types, as well as its own pstring and fstring. (This used to be commit 9db6c79e902ec538108d6b7d3324039aabe1704f) --- source4/lib/registry/reg_backend_dir.c | 1 + source4/lib/registry/reg_backend_ldb.c | 8 ++++---- source4/lib/registry/reg_backend_rpc.c | 6 +++--- source4/lib/registry/reg_samba.c | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_dir.c b/source4/lib/registry/reg_backend_dir.c index bac0f43c20..68f02d1745 100644 --- a/source4/lib/registry/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir.c @@ -21,6 +21,7 @@ #include "includes.h" #include "registry.h" #include "system/dir.h" +#include "system/filesys.h" 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) { diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 930ea9642e..c7b7bf587f 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -36,7 +36,7 @@ static int ldb_close_hive (void *_hive) return 0; } -static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, char **name, uint32 *type, void **data, int *len) +static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, char **name, uint32_t *type, void **data, int *len) { const struct ldb_val *val; *name = talloc_strdup(mem_ctx, ldb_msg_find_string(msg, "value", NULL)); @@ -52,7 +52,7 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, c case REG_DWORD_LE: *len = 4; - *data = talloc(mem_ctx, uint32); + *data = talloc(mem_ctx, uint32_t); SIVAL(*data, 0, strtol(val->data, NULL, 0)); break; @@ -63,7 +63,7 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, c } } -static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, const char *name, uint32 type, void *data, int len) +static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, const char *name, uint32_t type, void *data, int len) { struct ldb_val val; struct ldb_message *msg = talloc_zero(mem_ctx, struct ldb_message); @@ -322,7 +322,7 @@ static WERROR ldb_del_value (struct registry_key *key, const char *child) return WERR_OK; } -static WERROR ldb_set_value (struct registry_key *parent, const char *name, uint32 type, void *data, int len) +static WERROR ldb_set_value (struct registry_key *parent, const char *name, uint32_t type, void *data, int len) { struct ldb_context *ctx = parent->hive->backend_data; struct ldb_message *msg; diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index d2809f644a..2302416554 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -78,7 +78,7 @@ struct rpc_key_data { }; struct { - uint32 hkey; + uint32_t hkey; WERROR (*open) (struct dcerpc_pipe *p, TALLOC_CTX *, struct policy_handle *h); } known_hives[] = { { HKEY_LOCAL_MACHINE, open_HKLM }, @@ -93,7 +93,7 @@ struct { static WERROR rpc_query_key(struct registry_key *k); -static WERROR rpc_get_predefined_key (struct registry_context *ctx, uint32 hkey_type, struct registry_key **k) +static WERROR rpc_get_predefined_key (struct registry_context *ctx, uint32_t hkey_type, struct registry_key **k) { int n; struct registry_hive *h; @@ -185,7 +185,7 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *p struct rpc_key_data *mykeydata = parent->backend_data; WERROR error; struct winreg_EnumValue r; - uint32 type, len1, zero = 0; + uint32_t type, len1, zero = 0; NTSTATUS status; uint8_t buf8; uint16_t buf16; diff --git a/source4/lib/registry/reg_samba.c b/source4/lib/registry/reg_samba.c index a81b9e5a42..7188109daa 100644 --- a/source4/lib/registry/reg_samba.c +++ b/source4/lib/registry/reg_samba.c @@ -23,7 +23,7 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_REGISTRY -static WERROR reg_samba_get_predef (struct registry_context *ctx, uint32 hkey, struct registry_key **k) +static WERROR reg_samba_get_predef (struct registry_context *ctx, uint32_t hkey, struct registry_key **k) { WERROR error; const char *conf; -- cgit From 8fb475f626c61b977d6dcd3b20b3495fd9d0b95d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 06:45:13 +0000 Subject: r5303: fixed build of gconf registry backend (This used to be commit b4993c738ba7ce38de4eaf6270db60f8cd551cdd) --- source4/lib/registry/reg_backend_gconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_gconf.c b/source4/lib/registry/reg_backend_gconf.c index a912a42e55..9986f6f71a 100644 --- a/source4/lib/registry/reg_backend_gconf.c +++ b/source4/lib/registry/reg_backend_gconf.c @@ -150,7 +150,7 @@ static WERROR gconf_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *p return WERR_OK; } -static WERROR gconf_set_value(struct registry_key *key, const char *valname, uint32 type, void *data, int len) +static WERROR gconf_set_value(struct registry_key *key, const char *valname, uint32_t type, void *data, int len) { GError *error = NULL; char *valpath; -- cgit From a5bd1ccadab723c531963c219a1ac2b6b0c8b845 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 07:22:25 +0000 Subject: r5307: removed db_wrap.h from includes.h (This used to be commit 826baec7b348814a7bbdcdbec8c8526514f25da1) --- source4/lib/registry/reg_backend_ldb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index c7b7bf587f..9f44f92888 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -21,6 +21,7 @@ #include "includes.h" #include "registry.h" #include "lib/ldb/include/ldb.h" +#include "db_wrap.h" struct ldb_key_data { -- cgit From b1b14817eaa6e6579596d54166e17bc8d5605c01 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 27 Feb 2005 11:35:47 +0000 Subject: r5585: LDB interfaces change: changes: - ldb_wrap disappears from code and become a private structure of db_wrap.c thanks to our move to talloc in ldb code, we do not need to expose it anymore - removal of ldb_close() function form the code thanks to our move to talloc in ldb code, we do not need it anymore use talloc_free() to close and free an ldb database - some minor updates to ldb modules code to cope with the change and fix some bugs I found out during the process (This used to be commit d58be9e74b786a11a57e89df36081d55730dfe0a) --- source4/lib/registry/reg_backend_ldb.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 9f44f92888..7e63b14245 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -30,10 +30,10 @@ struct ldb_key_data int subkey_count, value_count; }; -static int ldb_close_hive (void *_hive) +static int ldb_free_hive (void *_hive) { struct registry_hive *hive = _hive; - ldb_close (hive->backend_data); + talloc_free(hive->backend_data); return 0; } @@ -231,9 +231,8 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const ch 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; + struct ldb_context *wrap; if (!hive->location) return WERR_INVALID_PARAM; wrap = ldb_wrap_connect(hive, hive->location, 0, NULL); @@ -243,14 +242,12 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) return WERR_FOOBAR; } - c = wrap->ldb; - - ldb_set_debug_stderr(c); - hive->backend_data = c; + ldb_set_debug_stderr(wrap); + hive->backend_data = wrap; *k = talloc_zero(hive, struct registry_key); talloc_set_destructor (*k, reg_close_ldb_key); - talloc_set_destructor (hive, ldb_close_hive); + talloc_set_destructor (hive, ldb_free_hive); (*k)->name = talloc_strdup(*k, ""); (*k)->backend_data = kd = talloc_zero(*k, struct ldb_key_data); kd->dn = talloc_strdup(*k, "hive="); -- cgit From 3e88cae57bd473b492735f90be86940e44e0e78d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 7 Mar 2005 12:02:48 +0000 Subject: r5680: Don't crash if none of the predefined keys is available (reported by Alexander) (This used to be commit 0d789872a890062b0b95aa039bb853bb6c07b2d0) --- source4/lib/registry/tools/regshell.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index ac7dbca49b..ee80837bab 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -408,8 +408,34 @@ static char **reg_completion(const char *text, int start, int end) } if (h) { - /*FIXME: What if HKEY_CLASSES_ROOT is not present ? */ - reg_get_predefined_key(h, HKEY_CLASSES_ROOT, &curkey); + enum reg_predefined_key try_hkeys[] = { + HKEY_CLASSES_ROOT, + HKEY_CURRENT_USER, + HKEY_LOCAL_MACHINE, + HKEY_USERS, + HKEY_PERFORMANCE_DATA, + HKEY_CURRENT_CONFIG, + HKEY_DYN_DATA, + HKEY_PERFORMANCE_TEXT, + HKEY_PERFORMANCE_NLSTEXT, + 0 + }; + int i; + + for (i = 0; try_hkeys[i]; i++) { + WERROR err; + err = reg_get_predefined_key(h, HKEY_CLASSES_ROOT, &curkey); + if (W_ERROR_IS_OK(err)) { + break; + } else { + curkey = NULL; + } + } + } + + if (!curkey) { + fprintf(stderr, "Unable to access any of the predefined keys\n"); + return -1; } poptFreeContext(pc); -- cgit From df643022136a4b229aca817f5b57f7302a97f852 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 19 Mar 2005 08:34:43 +0000 Subject: r5902: A rather large change... I wanted to add a simple 'workstation' argument to the DCERPC authenticated binding calls, but this patch kind of grew from there. With SCHANNEL, the 'workstation' name (the netbios name of the client) matters, as this is what ties the session between the NETLOGON ops and the SCHANNEL bind. This changes a lot of files, and these will again be changed when jelmer does the credentials work. I also correct some schannel IDL to distinguish between workstation names and account names. The distinction matters for domain trust accounts. Issues in handling this (issues with lifetime of talloc pointers) caused me to change the 'creds_CredentialsState' and 'struct dcerpc_binding' pointers to always be talloc()ed pointers. In the schannel DB, we now store both the domain and computername, and query on both. This should ensure we fault correctly when the domain is specified incorrectly in the SCHANNEL bind. In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out, where the comment claimed we re-used a connection, but in fact we made a new connection. This was achived by breaking apart some of the dcerpc_secondary_connection() logic. The addition of workstation handling was also propogated to NTLMSSP and GENSEC, for completeness. The RPC-SAMSYNC test has been cleaned up a little, using a loop over usernames/passwords rather than manually expanded tests. This will be expanded further (the code in #if 0 in this patch) to use a newly created user account for testing. In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO server, caused by the removal of [ref] and the assoicated pointer from the IDL. This has been re-added, until the underlying pidl issues are solved. (This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9) --- source4/lib/registry/reg_backend_rpc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 2302416554..4a285262c6 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -384,6 +384,7 @@ WERROR reg_open_remote (struct registry_context **ctx, const char *user, const c status = dcerpc_pipe_connect(&p, location, DCERPC_WINREG_UUID, DCERPC_WINREG_VERSION, + lp_netbios_name(), lp_workgroup(), user, pass); (*ctx)->backend_data = p; -- cgit From 02075be0bbc2095073f8898350fded64a7c97c79 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 21 Mar 2005 02:08:38 +0000 Subject: r5917: First step in using the new cli_credentials structure. This patch puts support for it into popt_common, adds a few utility functions (in lib/credentials.c) and the callback functions for the command-line (lib/cmdline/credentials.c). Comments are welcome :-) (This used to be commit 1d49b57c50fe8c2683ea23e9df41ce8ad774db98) --- source4/lib/registry/tools/regdiff.c | 4 ++-- source4/lib/registry/tools/regpatch.c | 2 +- source4/lib/registry/tools/regshell.c | 2 +- source4/lib/registry/tools/regtree.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index ceae3a427e..7206e1e44d 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -146,8 +146,8 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, else if (!h2) error = reg_open_local(&h2); break; case 'R': - if (!h1 && !from_null) error = reg_open_remote(&h1, cmdline_get_username(), cmdline_get_userpassword(), poptGetOptArg(pc)); - else if (!h2) error = reg_open_remote(&h2, cmdline_get_username(), cmdline_get_userpassword(), poptGetOptArg(pc)); + if (!h1 && !from_null) error = reg_open_remote(&h1, cli_credentials_get_username(cmdline_credentials), cli_credentials_get_password(cmdline_credentials), poptGetOptArg(pc)); + else if (!h2) error = reg_open_remote(&h2, cli_credentials_get_username(cmdline_credentials), cli_credentials_get_password(cmdline_credentials), poptGetOptArg(pc)); break; } diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index ee7568cc0f..ce3d9a7e1b 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -769,7 +769,7 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd setup_logging(argv[0], True); if (remote) { - error = reg_open_remote (&h, cmdline_get_username(), cmdline_get_userpassword(), remote); + error = reg_open_remote (&h, cli_credentials_get_username(cmdline_credentials), cli_credentials_get_password(cmdline_credentials), remote); } else { error = reg_open_local (&h); } diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index ee80837bab..cab2c5e34b 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -395,7 +395,7 @@ static char **reg_completion(const char *text, int start, int end) setup_logging("regtree", True); if (remote) { - error = reg_open_remote (&h, cmdline_get_username(), cmdline_get_userpassword(), remote); + error = reg_open_remote (&h, cli_credentials_get_username(cmdline_credentials), cli_credentials_get_password(cmdline_credentials), remote); } else if (backend) { error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, &curkey); } else { diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index f061f33bd3..81a7fb7f99 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -105,7 +105,7 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) setup_logging("regtree", True); if (remote) { - error = reg_open_remote(&h, cmdline_get_username(), cmdline_get_userpassword(), remote); + error = reg_open_remote(&h, cli_credentials_get_username(cmdline_credentials), cli_credentials_get_password(cmdline_credentials), remote); } else if (backend) { error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, &root); } else { -- cgit From 05bc2d7b2c11a3583a6d1221cfbd618eb6730518 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 21 Mar 2005 21:22:07 +0000 Subject: r5928: Use cli_credentials in: - gtk+ (returned by GtkHostBindingDialog as well now) - torture/ - librpc/ - lib/com/dcom/ (This used to be commit ccefd782335e01e8e6ecb2bcd28a4f999c53b1a6) --- source4/lib/registry/reg_backend_rpc.c | 6 ++---- source4/lib/registry/tools/regdiff.c | 5 +++-- source4/lib/registry/tools/regpatch.c | 2 +- source4/lib/registry/tools/regshell.c | 2 +- source4/lib/registry/tools/regtree.c | 2 +- 5 files changed, 8 insertions(+), 9 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 4a285262c6..a72d104521 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -369,7 +369,7 @@ static struct hive_operations reg_backend_rpc = { .num_values = rpc_num_values, }; -WERROR reg_open_remote (struct registry_context **ctx, const char *user, const char *pass, const char *location) +WERROR reg_open_remote (struct registry_context **ctx, struct cli_credentials *credentials, const char *location) { NTSTATUS status; struct dcerpc_pipe *p; @@ -384,9 +384,7 @@ WERROR reg_open_remote (struct registry_context **ctx, const char *user, const c status = dcerpc_pipe_connect(&p, location, DCERPC_WINREG_UUID, DCERPC_WINREG_VERSION, - lp_netbios_name(), - lp_workgroup(), - user, pass); + credentials); (*ctx)->backend_data = p; if(NT_STATUS_IS_ERR(status)) { diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 7206e1e44d..dfc8be13ca 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -146,8 +146,9 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, else if (!h2) error = reg_open_local(&h2); break; case 'R': - if (!h1 && !from_null) error = reg_open_remote(&h1, cli_credentials_get_username(cmdline_credentials), cli_credentials_get_password(cmdline_credentials), poptGetOptArg(pc)); - else if (!h2) error = reg_open_remote(&h2, cli_credentials_get_username(cmdline_credentials), cli_credentials_get_password(cmdline_credentials), poptGetOptArg(pc)); + if (!h1 && !from_null) + error = reg_open_remote(&h1, cmdline_credentials, poptGetOptArg(pc)); + else if (!h2) error = reg_open_remote(&h2, cmdline_credentials, poptGetOptArg(pc)); break; } diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index ce3d9a7e1b..2462fd8241 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -769,7 +769,7 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd setup_logging(argv[0], True); if (remote) { - error = reg_open_remote (&h, cli_credentials_get_username(cmdline_credentials), cli_credentials_get_password(cmdline_credentials), remote); + error = reg_open_remote (&h, cmdline_credentials, remote); } else { error = reg_open_local (&h); } diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index cab2c5e34b..bb7533e55e 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -395,7 +395,7 @@ static char **reg_completion(const char *text, int start, int end) setup_logging("regtree", True); if (remote) { - error = reg_open_remote (&h, cli_credentials_get_username(cmdline_credentials), cli_credentials_get_password(cmdline_credentials), remote); + error = reg_open_remote (&h, cmdline_credentials, remote); } else if (backend) { error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, &curkey); } else { diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 81a7fb7f99..72cb0670de 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -105,7 +105,7 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) setup_logging("regtree", True); if (remote) { - error = reg_open_remote(&h, cli_credentials_get_username(cmdline_credentials), cli_credentials_get_password(cmdline_credentials), remote); + error = reg_open_remote(&h, cmdline_credentials, remote); } else if (backend) { error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, &root); } else { -- cgit From 645711c602313940dcf80ec786557920ecfbf884 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 22 Mar 2005 08:00:45 +0000 Subject: r5941: Commit this patch much earlier than I would normally prefer, but metze needs a working tree... The main volume of this patch was what I started working on today: - Cleans up memory handling around DCE/RPC pipes, to have a parent talloc context. - Uses sepereate inner loops for some of the DCE/RPC tests The other and more important part of this patch fixes issues surrounding the new credentials framwork: This makes the struct cli_credentials always a talloc() structure, rather than on the stack. Parts of the cli_credentials code already assumed this. There were other issues, particularly in the DCERPC over SMB handling, as well as little things that had to be tidied up before test_w2k3.sh would start to pass. Andrew Bartlett (This used to be commit 0453f9d05d2e336fba1f85dbf2718d01fa2bf778) --- source4/lib/registry/reg_backend_rpc.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index a72d104521..5240cf5696 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -122,13 +122,6 @@ static WERROR rpc_get_predefined_key (struct registry_context *ctx, uint32_t hke return known_hives[n].open((struct dcerpc_pipe *)ctx->backend_data, *k, &(mykeydata->pol)); } -static int rpc_close (void *_h) -{ - struct registry_context *h = _h; - dcerpc_pipe_close(h->backend_data); - return 0; -} - #if 0 static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) { @@ -381,7 +374,8 @@ WERROR reg_open_remote (struct registry_context **ctx, struct cli_credentials *c location = talloc_strdup(ctx, "ncalrpc:"); } - status = dcerpc_pipe_connect(&p, location, + status = dcerpc_pipe_connect(*ctx /* TALLOC_CTX */, + &p, location, DCERPC_WINREG_UUID, DCERPC_WINREG_VERSION, credentials); @@ -389,13 +383,13 @@ WERROR reg_open_remote (struct registry_context **ctx, struct cli_credentials *c if(NT_STATUS_IS_ERR(status)) { DEBUG(1, ("Unable to open '%s': %s\n", location, nt_errstr(status))); + talloc_free(*ctx); + *ctx = NULL; return ntstatus_to_werror(status); } (*ctx)->get_predefined_key = rpc_get_predefined_key; - talloc_set_destructor(*ctx, rpc_close); - return WERR_OK; } -- cgit From 2fa732c6251f6dd23c3c8ef1facf638c9c531bdd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 24 Mar 2005 20:29:04 +0000 Subject: r6045: Couple of small GTK+ fixes Use uint32_t and uint16_t rather then DWORD and WORD in the NT4 backend. Add some more unknown fields.. (This used to be commit 6c3b1ec3296c7ab1ddfdcee86162f2eb0d73f5a8) --- source4/lib/registry/reg_backend_nt4.c | 121 ++++++++++++++++----------------- 1 file changed, 60 insertions(+), 61 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index d700070cde..6072222a87 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -1,7 +1,7 @@ /* Samba Unix/Linux SMB client utility libeditreg.c Copyright (C) 2002 Richard Sharpe, rsharpe@richardsharpe.com - Copyright (C) 2003-2004 Jelmer Vernooij, jelmer@samba.org + Copyright (C) 2003-2005 Jelmer Vernooij, jelmer@samba.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -342,9 +342,6 @@ const char *def_owner_sid_str = NULL; #define BLK_SIZE(b) ((int)*(int *)(((int *)b)-1)) -typedef uint_t DWORD; -typedef unsigned short WORD; - typedef struct sk_struct SK_HDR; /* * This structure keeps track of the output format of the registry @@ -353,65 +350,67 @@ typedef struct sk_struct SK_HDR; #define REG_OUTBLK_HBIN 2 typedef struct regf_block { - DWORD REGF_ID; /* regf */ - DWORD uk1; - DWORD uk2; - DWORD tim1, tim2; - DWORD uk3; /* 1 */ - DWORD uk4; /* 3 */ - DWORD uk5; /* 0 */ - DWORD uk6; /* 1 */ - DWORD first_key; /* offset */ - uint_t dblk_size; - DWORD uk7[116]; /* 1 */ - DWORD chksum; + uint32_t REGF_ID; /* regf */ + uint32_t update_counter1; + uint32_t update_counter2; + uint32_t tim1, tim2; + uint32_t uk3; /* 1 */ + uint32_t uk4; /* 3 */ + uint32_t uk5; /* 0 */ + uint32_t uk6; /* 1 */ + uint32_t first_key; /* offset */ + uint32_t dblk_size; + uint32_t uk7; /* 1 */ + wchar_t filename[64]; + uint32_t unused[83]; + uint32_t chksum; /* Checksum of first 0x200 bytes */ } REGF_HDR; typedef struct hbin_sub_struct { - DWORD dblocksize; + uint32_t dblocksize; char data[1]; } HBIN_SUB_HDR; typedef struct hbin_struct { - DWORD HBIN_ID; /* hbin */ - DWORD off_from_first; - DWORD off_to_next; - DWORD uk1; - DWORD uk2; - DWORD uk3; - DWORD uk4; - DWORD blk_size; + uint32_t HBIN_ID; /* hbin */ + uint32_t off_from_first; + uint32_t off_to_next; + uint32_t uk1; + uint32_t uk2; + uint32_t uk3; + uint32_t uk4; + uint32_t blk_size; HBIN_SUB_HDR hbin_sub_hdr; } HBIN_HDR; typedef struct nk_struct { - WORD NK_ID; - WORD type; - DWORD t1, t2; - DWORD uk1; - DWORD own_off; - DWORD subk_num; - DWORD uk2; - DWORD lf_off; - DWORD uk3; - DWORD val_cnt; - DWORD val_off; - DWORD sk_off; - DWORD clsnam_off; - DWORD unk4[4]; - DWORD unk5; - WORD nam_len; - WORD clsnam_len; + uint16_t NK_ID; + uint16_t type; + uint32_t t1, t2; + uint32_t uk1; + uint32_t own_off; + uint32_t subk_num; + uint32_t uk2; + uint32_t lf_off; + uint32_t uk3; + uint32_t val_cnt; + uint32_t val_off; + uint32_t sk_off; + uint32_t clsnam_off; + uint32_t unk4[4]; + uint32_t unk5; + uint16_t nam_len; + uint16_t clsnam_len; char key_nam[1]; /* Actual length determined by nam_len */ } NK_HDR; struct sk_struct { - WORD SK_ID; - WORD uk1; - DWORD prev_off; - DWORD next_off; - DWORD ref_cnt; - DWORD rec_size; + uint16_t SK_ID; + uint16_t uk1; + uint32_t prev_off; + uint32_t next_off; + uint32_t ref_cnt; + uint32_t rec_size; char sec_desc[1]; }; @@ -431,27 +430,27 @@ typedef struct sk_map_s { } SK_MAP; typedef struct vk_struct { - WORD VK_ID; - WORD nam_len; - DWORD dat_len; /* If top-bit set, offset contains the data */ - DWORD dat_off; - DWORD dat_type; - WORD flag; /* =1, has name, else no name (=Default). */ - WORD unk1; + uint16_t VK_ID; + uint16_t nam_len; + uint32_t dat_len; /* If top-bit set, offset contains the data */ + uint32_t dat_off; + uint32_t dat_type; + uint16_t flag; /* =1, has name, else no name (=Default). */ + uint16_t unk1; char dat_name[1]; /* Name starts here ... */ } VK_HDR; -typedef DWORD VL_TYPE[1]; /* Value list is an array of vk rec offsets */ +typedef uint32_t VL_TYPE[1]; /* Value list is an array of vk rec offsets */ typedef struct hash_struct { - DWORD nk_off; + uint32_t nk_off; char hash[4]; } HASH_REC; typedef struct lf_struct { - WORD LF_ID; - WORD key_count; + uint16_t LF_ID; + uint16_t key_count; struct hash_struct hr[1]; /* Array of hash records, depending on key_count */} LF_HDR; @@ -491,7 +490,7 @@ typedef struct regf_struct_s { HBIN_BLK *blk_head, *blk_tail, *free_space; } REGF; -static DWORD str_to_dword(const char *a) { +static uint32_t str_to_dword(const char *a) { int i; unsigned long ret = 0; for(i = strlen(a)-1; i >= 0; i--) { @@ -1373,7 +1372,7 @@ static uint_t nt_store_sec_desc(struct registry_hive *regf, SEC_DESC *sd, char * rsd->revision = SEC_DESC_REVISION; rsd->type = SEC_DESC_DACL_PRESENT | SEC_DESC_SELF_RELATIVE; - off = 4 * sizeof(DWORD) + 4; + off = 4 * sizeof(uint32_t) + 4; if (sd->sacl){ size = nt_store_acl(regf, sd->sacl, (char *)(locn + off)); -- cgit From fe4d985b6f3d318d9b58a16677be3b4ae34fba15 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 25 Apr 2005 12:46:18 +0000 Subject: r6470: Remove ldb_search_free() it is not needed anymore. Just use talloc_free() to release the memory after an ldb_search(). (This used to be commit 4f0948dab0aa5e8b6a4ce486f3668ca8dfae23db) --- source4/lib/registry/reg_backend_ldb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 7e63b14245..fc01de61a5 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -102,12 +102,12 @@ static int reg_close_ldb_key (void *data) struct ldb_context *c = key->hive->backend_data; if (kd->subkeys) { - ldb_search_free(c, kd->subkeys); + talloc_free(kd->subkeys); kd->subkeys = NULL; } if (kd->values) { - ldb_search_free(c, kd->values); + talloc_free(kd->values); kd->values = NULL; } return 0; @@ -224,7 +224,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const ch (*key)->backend_data = newkd = talloc_zero(*key, struct ldb_key_data); newkd->dn = talloc_strdup(mem_ctx, msg[0]->dn); - ldb_search_free(c, msg); + talloc_free(msg); return WERR_OK; } -- cgit From 1403bb7e62d5cf3afe0a108acafb6410d614bd71 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sat, 30 Apr 2005 04:46:17 +0000 Subject: r6520: Fix unused variable warning. (This used to be commit 36de31a63189dcc6126dd0c10b1af8d183d8c235) --- source4/lib/registry/reg_backend_ldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index fc01de61a5..5f4e296edf 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -99,7 +99,7 @@ static int reg_close_ldb_key (void *data) { struct registry_key *key = data; struct ldb_key_data *kd = key->backend_data; - struct ldb_context *c = key->hive->backend_data; +/* struct ldb_context *c = key->hive->backend_data; */ if (kd->subkeys) { talloc_free(kd->subkeys); -- cgit From 5b18cf22680c76abb1262a6b75a30b8a37899467 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 15 May 2005 20:16:26 +0000 Subject: r6795: Make some functions static and remove some unused ones. (This used to be commit 46509eb89980bfe6dabd71264d570ea356ee5a22) --- source4/lib/registry/common/reg_interface.c | 7 ------ source4/lib/registry/common/reg_util.c | 38 ----------------------------- source4/lib/registry/reg_backend_rpc.c | 2 +- source4/lib/registry/tools/regpatch.c | 2 +- source4/lib/registry/tools/regshell.c | 2 +- 5 files changed, 3 insertions(+), 48 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 407d0d3345..76de2f041f 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -127,13 +127,6 @@ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, const char * return WERR_BADFILE; } -WERROR reg_close (struct registry_context *ctx) -{ - talloc_free(ctx); - - return WERR_OK; -} - WERROR reg_get_predefined_key(struct registry_context *ctx, uint32_t hkey, struct registry_key **key) { WERROR ret = ctx->get_predefined_key(ctx, hkey, key); diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index d4fdc59d70..e12cff186a 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -139,44 +139,6 @@ BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *da 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) -{ - struct registry_key *k; - WERROR error = reg_key_get_subkey_by_name(mem_ctx, key, subname, &k); - if(!W_ERROR_IS_OK(error)) return error; - - return reg_key_get_value_by_name(mem_ctx, k, valname, val); -} - -/*********************************************************************** - Utility function for splitting the base path of a registry path off - by setting base and new_path to the apprapriate offsets withing the - path. - - WARNING!! Does modify the original string! - ***********************************************************************/ - -BOOL reg_split_path( char *path, char **base, char **new_path ) -{ - char *p; - - *new_path = *base = NULL; - - if ( !path) - return False; - - *base = path; - - p = strchr( path, '\\' ); - - if ( p ) { - *p = '\0'; - *new_path = p+1; - } - - return True; -} - /** * Replace all \'s with /'s */ diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 5240cf5696..88cce2584e 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -77,7 +77,7 @@ struct rpc_key_data { int max_valdatalen; }; -struct { +static struct { uint32_t hkey; WERROR (*open) (struct dcerpc_pipe *p, TALLOC_CTX *, struct policy_handle *h); } known_hives[] = { diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 2462fd8241..aeb418560d 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -576,7 +576,7 @@ typedef struct command_ops_s { int (*exec_cmd)(CMD *cmd); } CMD_OPS; -CMD_OPS default_cmd_ops[] = { +static CMD_OPS default_cmd_ops[] = { {0, regedit4_file_type, regedit4_get_cmd, regedit4_exec_cmd}, {1, editreg_1_0_file_type, editreg_1_0_get_cmd, editreg_1_0_exec_cmd}, {-1, NULL, NULL, NULL} diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index bb7533e55e..ecc2bfc7aa 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -187,7 +187,7 @@ static struct registry_key *cmd_exit(TALLOC_CTX *mem_ctx, struct registry_contex static struct registry_key *cmd_help(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *, int, char **); -struct { +static struct { const char *name; const char *alias; const char *help; -- cgit From 4867378592656d812fcd02d1ea24ccb2c99bf9b7 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 24 May 2005 05:51:20 +0000 Subject: r6951: Fix all calls to setup_logging() that use 'True' as a second argument. In Samba4 this is now an enum. Possibly by accident, True just happens to map to the right value in this case. (-: (This used to be commit affacc539864435cbc749a4c1a6b848c61b7182b) --- source4/lib/registry/tools/regdiff.c | 2 +- source4/lib/registry/tools/regpatch.c | 2 +- source4/lib/registry/tools/regshell.c | 2 +- source4/lib/registry/tools/regtree.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index dfc8be13ca..4260a56142 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -157,7 +157,7 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, return 1; } } - setup_logging(argv[0], True); + setup_logging(argv[0], DEBUG_STDOUT); poptFreeContext(pc); diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index aeb418560d..5c9851b71b 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -766,7 +766,7 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd while((opt = poptGetNextOpt(pc)) != -1) { } - setup_logging(argv[0], True); + setup_logging(argv[0], DEBUG_STDOUT); if (remote) { error = reg_open_remote (&h, cmdline_credentials, remote); diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index ecc2bfc7aa..f1fd740830 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -392,7 +392,7 @@ static char **reg_completion(const char *text, int start, int end) while((opt = poptGetNextOpt(pc)) != -1) { } - setup_logging("regtree", True); + setup_logging("regtree", DEBUG_STDOUT); if (remote) { error = reg_open_remote (&h, cmdline_credentials, remote); diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 72cb0670de..2cf5f6ab96 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -102,7 +102,7 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) while((opt = poptGetNextOpt(pc)) != -1) { } - setup_logging("regtree", True); + setup_logging("regtree", DEBUG_STDOUT); if (remote) { error = reg_open_remote(&h, cmdline_credentials, remote); -- cgit From dde05bc78735a111e814ab5ece9e79af4555153b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 30 May 2005 15:11:10 +0000 Subject: r7113: Move manpages from docs repository to source repository (This used to be commit f16d346032b9052c9dcd6b15cf65dd62e6943cd3) --- source4/lib/registry/man/regdiff.1.xml | 102 +++++++++++++++++ source4/lib/registry/man/regpatch.1.xml | 88 +++++++++++++++ source4/lib/registry/man/regshell.1.xml | 188 ++++++++++++++++++++++++++++++++ source4/lib/registry/man/regtree.1.xml | 101 +++++++++++++++++ 4 files changed, 479 insertions(+) create mode 100644 source4/lib/registry/man/regdiff.1.xml create mode 100644 source4/lib/registry/man/regpatch.1.xml create mode 100644 source4/lib/registry/man/regshell.1.xml create mode 100644 source4/lib/registry/man/regtree.1.xml (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/man/regdiff.1.xml b/source4/lib/registry/man/regdiff.1.xml new file mode 100644 index 0000000000..d4d9d75b91 --- /dev/null +++ b/source4/lib/registry/man/regdiff.1.xml @@ -0,0 +1,102 @@ + + + + + + regdiff + 1 + + + + + regdiff + Diff program for Windows registry files + + + + + regdiff + --help + --backend=BACKEND + --backend=BACKEND + --credentials=CREDENTIALS + --credentials=CREDENTIALS + location + location + + + + + DESCRIPTION + + regdiff compares two Windows registry files key by key + and value by value and generates a text file that contains the + differences between the two files. + + A file generated by regdiff can later be applied to a + registry file by the regpatch utility. + + regdiff and regpatch use the same file format as + the regedit32.exe utility from Windows. + + + + + OPTIONS + + + + --help + + Show list of available options. + + + + --backend BACKEND + Name of backend to load. Possible values are: + w95, nt4, gconf, dir and rpc. The default is dir. + + + This argument can be specified twice: once for the first + registry file and once for the second. + + + + + --credentials=CREDENTIALS + + Credentials to use, if any. Password should be separated from user name by a percent sign. + + + This argument can be specified twice: once for the first + registry file and once for the second. + + + + + +&man.registry.backends; + + + VERSION + + This man page is correct for version 4.0 of the Samba suite. + + + + SEE ALSO + + gregedit, regshell, regpatch, regtree, samba, patch, diff + + + + + AUTHOR + + &man.credits.samba; + + This manpage and regdiff were written by Jelmer Vernooij. + + + + diff --git a/source4/lib/registry/man/regpatch.1.xml b/source4/lib/registry/man/regpatch.1.xml new file mode 100644 index 0000000000..f1792d8bc9 --- /dev/null +++ b/source4/lib/registry/man/regpatch.1.xml @@ -0,0 +1,88 @@ + + + + + + regpatch + 1 + + + + + regpatch + Applies registry patches to registry files + + + + + regpatch + --help + --backend=BACKEND + --credentials=CREDENTIALS + location + patch-file + + + + + DESCRIPTION + + The regpatch utility applies registry patches to Windows registry + files. The patch files should have the same format as is being used + by the regdiff utility and regedit32.exe from Windows. + + If no patch file is specified on the command line, + regpatch attempts to read it from standard input. + + + + + OPTIONS + + + + --help + + Show list of available options. + + + + --backend BACKEND + Name of backend to load. Possible values are: + w95, nt4, gconf, dir and rpc. The default is dir. + + + + + --credentials=CREDENTIALS + + Credentials to use, if any. Password should be separated from user name by a percent sign. + + + + +&man.registry.backends; + + + VERSION + + This man page is correct for version 4.0 of the Samba suite. + + + + SEE ALSO + + regdiff, regtree, regshell, gregedit, samba, diff, patch + + + + + AUTHOR + + &man.credits.samba; + + This manpage and regpatch were written by Jelmer Vernooij. + + + + diff --git a/source4/lib/registry/man/regshell.1.xml b/source4/lib/registry/man/regshell.1.xml new file mode 100644 index 0000000000..fbfff86b09 --- /dev/null +++ b/source4/lib/registry/man/regshell.1.xml @@ -0,0 +1,188 @@ + + + + + + regshell + 1 + + + + + regshell + Windows registry file browser using readline + + + + + regshell + --help + --backend=BACKEND + --credentials=CREDENTIALS + location + + + + + DESCRIPTION + + + regshell is a utility that lets you browse thru a Windows registry + file as if you were using a regular unix shell to browse thru a + file system. + + + + + + + OPTIONS + + + + --help + + Show list of available options. + + + + --backend BACKEND + Name of backend to load. Possible values are: + w95, nt4, gconf, dir and rpc. The default is dir. + + + + + --credentials=CREDENTIALS + + Credentials to use, if any. Password should be separated from user name by a percent sign. + + + + + + COMMANDS + + + + ck|cd <keyname> + + Go to the specified subkey. + + + + + ch|predef [predefined-key-name] + + Go to the specified predefined key. + + + + + list|ls + + List subkeys and values of the current key. + + + + + mkkey|mkdir <keyname> + + Create a key with the specified keyname as a subkey of the current key. + + + + + rmval|rm <valname> + + Delete the specified value. + + + + + rmkey|rmdir <keyname> + + Delete the specified subkey recursively. + + + + + pwd|pwk + Print the full name of the current key. + + + + set|update + Update the value of a key value. Not implemented at the moment. + + + + help|? + Print a list of available commands. + + + exit|quit + Leave regshell. + + + + +&man.registry.backends; + + + EXAMPLES + + Browsing thru a nt4 registry file + +regshell -b nt4 NTUSER.DAT +$$$PROTO.HIV> ls +K AppEvents +K Console +K Control Panel +K Environment +K Identities +K Keyboard Layout +K Network +K Printers +K Software +K UNICODE Program Groups +K Windows 3.1 Migration Status +$$$PROTO.HIV> exit + + +Listing the subkeys of HKEY_CURRENT_USER\AppEvents on a remote computer: + +regshell --remote=ncacn_np:aurelia -c "jelmer%secret" +HKEY_CURRENT_MACHINE> predef HKEY_CURRENT_USER +HKEY_CURRENT_USER> cd AppEvents +Current path is: HKEY_CURRENT_USER\AppEvents +HKEY_CURRENT_USER\AppEvents> ls +K EventLabels +K Schemes +HKEY_CURRENT_USER\AppEvents> exit + + + + + VERSION + + This man page is correct for version 4.0 of the Samba suite. + + + + SEE ALSO + + regtree, regdiff, regpatch, gregedit, samba + + + + + AUTHOR + + &man.credits.samba; + + This manpage and regshell were written by Jelmer Vernooij. + + + + diff --git a/source4/lib/registry/man/regtree.1.xml b/source4/lib/registry/man/regtree.1.xml new file mode 100644 index 0000000000..7fc0de2721 --- /dev/null +++ b/source4/lib/registry/man/regtree.1.xml @@ -0,0 +1,101 @@ + + + + + + regtree + 1 + + + + + regtree + Text-mode registry viewer + + + + + regtree + --help + --backend=BACKEND + --fullpath + --no-values + --credentials=CREDENTIALS + location + + + + + DESCRIPTION + + The regtree utility prints out all the contents of a + Windows registry file. Subkeys are printed with one level + more indentation then their parents. + + + + + + OPTIONS + + + + --help + + Show list of available options. + + + + --backend BACKEND + Name of backend to load. Possible values are: + w95, nt4, gconf, dir and rpc. The default is dir. + + + + + --credentials=CREDENTIALS + + Credentials to use, if any. Password should be separated from user name by a percent sign. + + + + --fullpath + + Print the full path to each key instead of only its name. + + + + + --no-values + Don't print values, just keys. + + + + + + +&man.registry.backends; + + + VERSION + + This man page is correct for version 4.0 of the Samba suite. + + + + SEE ALSO + + gregedit, regshell, regdiff, regpatch, samba + + + + + AUTHOR + + &man.credits.samba; + + This manpage and regtree were written by Jelmer Vernooij. + + + + -- cgit From 77c3d463c88af9f41f5f76446d380c80262ce712 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 3 Jun 2005 20:44:46 +0000 Subject: r7248: Remove enum that is causing trouble on AIX (This used to be commit 512536c9165eb4a630c8bf4e43e71def26006047) --- source4/lib/registry/tools/regshell.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index f1fd740830..03cb09c443 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -408,7 +408,7 @@ static char **reg_completion(const char *text, int start, int end) } if (h) { - enum reg_predefined_key try_hkeys[] = { + uint32_t try_hkeys[] = { HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, @@ -424,7 +424,7 @@ static char **reg_completion(const char *text, int start, int end) for (i = 0; try_hkeys[i]; i++) { WERROR err; - err = reg_get_predefined_key(h, HKEY_CLASSES_ROOT, &curkey); + err = reg_get_predefined_key(h, try_hkeys[i], &curkey); if (W_ERROR_IS_OK(err)) { break; } else { -- cgit From c6a3ee8baba002d7568d17fb0bc73908eb4da2e7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Jun 2005 18:11:59 +0000 Subject: r7373: Disable reg_gconf by default, allow building it with --enable-reg-gconf (This used to be commit 6596f619c0500a419a680a7488a0838c234f2069) --- source4/lib/registry/config.m4 | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index abadcbe1a0..d0d1d2c54b 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -11,9 +11,13 @@ SMB_MODULE_DEFAULT(registry_gconf, NOT) SMB_EXT_LIB_FROM_PKGCONFIG(gconf, gconf-2.0) -if test t$SMB_EXT_LIB_ENABLE_gconf = tYES; then - SMB_MODULE_DEFAULT(registry_gconf, STATIC) -fi +AC_ARG_ENABLE(reg-gconf, +[ --enable-reg-gconf Enable support for GConf registry backend], +[ + if test t$enable = tyes && test t$SMB_EXT_LIB_ENABLE_gconf = tYES; then + SMB_MODULE_DEFAULT(registry_gconf, STATIC) + fi +]) if test x"$experimental" = x"yes"; then SMB_LIBRARY_ENABLE(libwinregistry, YES) -- cgit From 2b4791ae733488845b2c36bca64db695203de571 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 13 Jun 2005 08:12:39 +0000 Subject: r7525: Unify lp_load(), load_interfaces and logging setup into popt(). There is now a new --debug-stderr option to enable debug to STDERR. popt isn't perfect, but the callbacks are used in all the main Samba binaries, and should be used in the rest. This avoids duplicated code, and ensures every binary is setup correctly. This also ensures the setup happens early enough to have -s function, and have a correct impact on the credentials code. (Fixing a bug that frustrated tridge earlier today). The only 'subtle' aspect of all this is that I'm pretty sure that the SAMBA_COMMON popt code must be above the CREDENTIALS code, in the popt tables. Andrew Bartlett (This used to be commit 50f3c2b3a22971f40e0d3a88127b5120bfc47591) --- source4/lib/registry/tools/regdiff.c | 10 +++------- source4/lib/registry/tools/regpatch.c | 10 ++-------- source4/lib/registry/tools/regshell.c | 11 +++-------- source4/lib/registry/tools/regtree.c | 10 ++-------- 4 files changed, 10 insertions(+), 31 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 4260a56142..f86c0ae383 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -121,21 +121,18 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, WERROR error, error2; struct poptOption long_options[] = { POPT_AUTOHELP - POPT_COMMON_CREDENTIALS {"output", 'o', POPT_ARG_STRING, &outputfile, 'o', "output file to use", NULL }, {"null", 'n', POPT_ARG_NONE, &from_null, 'n', "Diff from NULL", NULL }, {"remote", 'R', POPT_ARG_STRING, NULL, 0, "Connect to remote server" , NULL }, {"local", 'L', POPT_ARG_NONE, NULL, 0, "Open local registry", NULL }, + POPT_COMMON_SAMBA + POPT_COMMON_CREDENTIALS + POPT_COMMON_VERSION POPT_TABLEEND }; regdiff_init_subsystems; - if (!lp_load(dyn_CONFIGFILE,True,False,False)) { - fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE); - } - - pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); while((opt = poptGetNextOpt(pc)) != -1) { @@ -157,7 +154,6 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, return 1; } } - setup_logging(argv[0], DEBUG_STDOUT); poptFreeContext(pc); diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 5c9851b71b..02ef4d4655 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -749,25 +749,19 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd WERROR error; struct poptOption long_options[] = { POPT_AUTOHELP - POPT_COMMON_CREDENTIALS {"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL}, + POPT_COMMON_SAMBA + POPT_COMMON_CREDENTIALS POPT_TABLEEND }; regpatch_init_subsystems; - if (!lp_load(dyn_CONFIGFILE,True,False,False)) { - fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE); - } - - pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); while((opt = poptGetNextOpt(pc)) != -1) { } - setup_logging(argv[0], DEBUG_STDOUT); - if (remote) { error = reg_open_remote (&h, cmdline_credentials, remote); } else { diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 03cb09c443..0c53f737b8 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -374,26 +374,21 @@ static char **reg_completion(const char *text, int start, int end) struct registry_context *h = NULL; struct poptOption long_options[] = { POPT_AUTOHELP - POPT_COMMON_CREDENTIALS {"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL}, {"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL}, + POPT_COMMON_SAMBA + POPT_COMMON_CREDENTIALS + POPT_COMMON_VERSION POPT_TABLEEND }; regshell_init_subsystems; - if (!lp_load(dyn_CONFIGFILE,True,False,False)) { - fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE); - } - - pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); while((opt = poptGetNextOpt(pc)) != -1) { } - setup_logging("regtree", DEBUG_STDOUT); - if (remote) { error = reg_open_remote (&h, cmdline_credentials, remote); } else if (backend) { diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 2cf5f6ab96..f18467b523 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -82,28 +82,22 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) int fullpath = 0, no_values = 0; struct poptOption long_options[] = { POPT_AUTOHELP - POPT_COMMON_CREDENTIALS {"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL}, {"fullpath", 'f', POPT_ARG_NONE, &fullpath, 0, "show full paths", NULL}, {"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL }, {"no-values", 'V', POPT_ARG_NONE, &no_values, 0, "don't show values", NULL}, + POPT_COMMON_SAMBA + POPT_COMMON_CREDENTIALS POPT_TABLEEND }; regtree_init_subsystems; - if (!lp_load(dyn_CONFIGFILE,True,False,False)) { - fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE); - } - - pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); while((opt = poptGetNextOpt(pc)) != -1) { } - setup_logging("regtree", DEBUG_STDOUT); - if (remote) { error = reg_open_remote(&h, cmdline_credentials, remote); } else if (backend) { -- cgit From af237084ecd4f9928c6c282b9c5c73598d5c73d6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 16 Jun 2005 11:36:09 +0000 Subject: r7633: this patch started as an attempt to make the dcerpc code use a given event_context for the socket_connect() call, so that when things that use dcerpc are running alongside anything else it doesn't block the whole process during a connect. Then of course I needed to change any code that created a dcerpc connection (such as the auth code) to also take an event context, and anything that called that and so on .... thus the size of the patch. There were 3 places where I punted: - abartlet wanted me to add a gensec_set_event_context() call instead of adding it to the gensec init calls. Andrew, my apologies for not doing this. I didn't do it as adding a new parameter allowed me to catch all the callers with the compiler. Now that its done, we could go back and use gensec_set_event_context() - the ejs code calls auth initialisation, which means it should pass in the event context from the web server. I punted on that. Needs fixing. - I used a NULL event context in dcom_get_pipe(). This is equivalent to what we did already, but should be fixed to use a callers event context. Jelmer, can you think of a clean way to do that? I also cleaned up a couple of things: - libnet_context_destroy() makes no sense. I removed it. - removed some unused vars in various places (This used to be commit 3a3025485bdb8f600ab528c0b4b4eef0c65e3fc9) --- source4/lib/registry/reg_backend_rpc.c | 5 +++-- source4/lib/registry/tools/regdiff.c | 6 ++++-- source4/lib/registry/tools/regpatch.c | 2 +- source4/lib/registry/tools/regshell.c | 2 +- source4/lib/registry/tools/regtree.c | 2 +- 5 files changed, 10 insertions(+), 7 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 88cce2584e..3c38b5d312 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -362,7 +362,8 @@ static struct hive_operations reg_backend_rpc = { .num_values = rpc_num_values, }; -WERROR reg_open_remote (struct registry_context **ctx, struct cli_credentials *credentials, const char *location) +WERROR reg_open_remote(struct registry_context **ctx, struct cli_credentials *credentials, + const char *location, struct event_context *ev) { NTSTATUS status; struct dcerpc_pipe *p; @@ -378,7 +379,7 @@ WERROR reg_open_remote (struct registry_context **ctx, struct cli_credentials *c &p, location, DCERPC_WINREG_UUID, DCERPC_WINREG_VERSION, - credentials); + credentials, ev); (*ctx)->backend_data = p; if(NT_STATUS_IS_ERR(status)) { diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index f86c0ae383..a9d189c033 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -144,8 +144,10 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, break; case 'R': if (!h1 && !from_null) - error = reg_open_remote(&h1, cmdline_credentials, poptGetOptArg(pc)); - else if (!h2) error = reg_open_remote(&h2, cmdline_credentials, poptGetOptArg(pc)); + error = reg_open_remote(&h1, cmdline_credentials, + poptGetOptArg(pc), NULL); + else if (!h2) error = reg_open_remote(&h2, cmdline_credentials, + poptGetOptArg(pc), NULL); break; } diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 02ef4d4655..3ada9f66e2 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -763,7 +763,7 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd } if (remote) { - error = reg_open_remote (&h, cmdline_credentials, remote); + error = reg_open_remote (&h, cmdline_credentials, remote, NULL); } else { error = reg_open_local (&h); } diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 0c53f737b8..108cc17336 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -390,7 +390,7 @@ static char **reg_completion(const char *text, int start, int end) } if (remote) { - error = reg_open_remote (&h, cmdline_credentials, remote); + error = reg_open_remote (&h, cmdline_credentials, remote, NULL); } else if (backend) { error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, &curkey); } else { diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index f18467b523..2385123b7f 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -99,7 +99,7 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) } if (remote) { - error = reg_open_remote(&h, cmdline_credentials, remote); + error = reg_open_remote(&h, cmdline_credentials, remote, NULL); } else if (backend) { error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, &root); } else { -- cgit From fa8d539e0fbce952266a246364e5e9cd537b29fd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 27 Jun 2005 12:09:52 +0000 Subject: r7943: Add 'make manpages', fix 'make installman' and 'make uninstallman'. Not part of the "all" make target yet, as it requires xsltproc (This used to be commit fd3f4636438cf1d9c0dd802064033271b9e4d935) --- source4/lib/registry/config.mk | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index af9fb83bab..ab699a8ac0 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -98,6 +98,7 @@ OBJ_FILES= \ lib/registry/tools/regdiff.o REQUIRED_SUBSYSTEMS = \ CONFIG LIBCMDLINE REGISTRY +MANPAGE = lib/registry/man/regdiff.1 # End BINARY regdiff ################################################ @@ -108,6 +109,7 @@ OBJ_FILES= \ lib/registry/tools/regpatch.o REQUIRED_SUBSYSTEMS = \ CONFIG LIBCMDLINE REGISTRY +MANPAGE = lib/registry/man/regpatch.1 # End BINARY regpatch ################################################ @@ -118,6 +120,7 @@ OBJ_FILES= \ lib/registry/tools/regshell.o REQUIRED_SUBSYSTEMS = \ CONFIG LIBCMDLINE REGISTRY +MANPAGE = lib/registry/man/regshell.1 # End BINARY regshell ################################################ @@ -128,5 +131,6 @@ OBJ_FILES= \ lib/registry/tools/regtree.o REQUIRED_SUBSYSTEMS = \ CONFIG LIBCMDLINE REGISTRY +MANPAGE = lib/registry/man/regtree.1 # End BINARY regtree ################################################ -- cgit From 372f3fae88799ce321342dd976a317a8afc375e2 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 6 Jul 2005 01:53:34 +0000 Subject: r8171: According to Samba 3 and Ethereal, the winreg_OpenUnkown stuff is actually a uint16 * without the [string] attribute, a la the the system_name argument to samr_Connect(). Initialising the pointer to NULL is sufficient and we still pass the RPC-WINREG test against win2k3. (This used to be commit 407d962dacf7c833b36cb739e48fe97226968a34) --- source4/lib/registry/reg_backend_rpc.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 3c38b5d312..73d2d54687 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -43,12 +43,9 @@ static void init_winreg_String(struct winreg_String *name, const char *s) #define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *hnd) \ { \ struct winreg_Open ## u r; \ - struct winreg_OpenUnknown unknown; \ NTSTATUS status; \ \ - unknown.unknown0 = 0x84e0; \ - unknown.unknown1 = 0x0000; \ - r.in.unknown = &unknown; \ + r.in.system_name = 0; \ r.in.access_required = SEC_FLAG_MAXIMUM_ALLOWED; \ r.out.handle = hnd;\ \ -- cgit From e835621799647ee70630b389fb53d15b15d68355 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 17 Jul 2005 09:20:52 +0000 Subject: r8520: fixed a pile of warnings from the build farm gcc -Wall output on S390. This is an attempt to avoid the panic we're seeing in the automatic builds. The main fixes are: - assumptions that sizeof(size_t) == sizeof(int), mostly in printf formats - use of NULL format statements to perform dn searches. - assumption that sizeof() returns an int (This used to be commit a58ea6b3854973b694d2b1e22323ed7eb00e3a3f) --- source4/lib/registry/reg_backend_nt4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index 6072222a87..e07534884c 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -1051,7 +1051,7 @@ static WERROR nk_to_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, NK_HDR *nk if (-size < (sizeof(NK_HDR) - 1 + namlen)) { DEBUG(0, ("Incorrect NK_HDR size: %d, %0X\n", -size, (int)nk_hdr)); DEBUG(0, ("Sizeof NK_HDR: %d, name_len %d, clsname_len %d\n", - sizeof(NK_HDR), namlen, clsname_len)); + (int)sizeof(NK_HDR), namlen, clsname_len)); return WERR_GENERAL_FAILURE; } -- cgit From 9f611ffddeced5661b81fbe6264502a0d59f187b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 3 Aug 2005 00:08:28 +0000 Subject: r8966: Simplify the makefile generation system a bit. Autogenerate list of binaries (rather then having them hardcoded in build/smb_build/makefile.pm) Add INSTALLDIR keyword to .mk files (This used to be commit ce0935112b846486cf705ec69f12350be9c4c89d) --- source4/lib/registry/config.mk | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index ab699a8ac0..c533e17ea9 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -94,6 +94,7 @@ REQUIRED_SUBSYSTEMS = \ ################################################ # Start BINARY regdiff [BINARY::regdiff] +INSTALLDIR = BINDIR OBJ_FILES= \ lib/registry/tools/regdiff.o REQUIRED_SUBSYSTEMS = \ @@ -105,6 +106,7 @@ MANPAGE = lib/registry/man/regdiff.1 ################################################ # Start BINARY regpatch [BINARY::regpatch] +INSTALLDIR = BINDIR OBJ_FILES= \ lib/registry/tools/regpatch.o REQUIRED_SUBSYSTEMS = \ @@ -116,6 +118,7 @@ MANPAGE = lib/registry/man/regpatch.1 ################################################ # Start BINARY regshell [BINARY::regshell] +INSTALLDIR = BINDIR OBJ_FILES= \ lib/registry/tools/regshell.o REQUIRED_SUBSYSTEMS = \ @@ -127,6 +130,7 @@ MANPAGE = lib/registry/man/regshell.1 ################################################ # Start BINARY regtree [BINARY::regtree] +INSTALLDIR = BINDIR OBJ_FILES= \ lib/registry/tools/regtree.o REQUIRED_SUBSYSTEMS = \ -- cgit From a689b968b6c1b47b0425f753472f1e221d2dea67 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 8 Aug 2005 03:19:28 +0000 Subject: r9209: - fixed the ldb registry backend to work with the new provision ldif - default to ldb backend if none specified (This used to be commit 8c3f57f7917efceb11b3b6a2ac76ec44968fbfb6) --- source4/lib/registry/reg_backend_ldb.c | 2 +- source4/lib/registry/reg_samba.c | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 5f4e296edf..8a5eac59c5 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -250,7 +250,7 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) talloc_set_destructor (hive, ldb_free_hive); (*k)->name = talloc_strdup(*k, ""); (*k)->backend_data = kd = talloc_zero(*k, struct ldb_key_data); - kd->dn = talloc_strdup(*k, "hive="); + kd->dn = talloc_strdup(*k, "hive=NONE"); return WERR_OK; diff --git a/source4/lib/registry/reg_samba.c b/source4/lib/registry/reg_samba.c index 7188109daa..3c9ae3f415 100644 --- a/source4/lib/registry/reg_samba.c +++ b/source4/lib/registry/reg_samba.c @@ -27,7 +27,8 @@ static WERROR reg_samba_get_predef (struct registry_context *ctx, uint32_t hkey, { WERROR error; const char *conf; - char *backend, *location; + char *backend; + const char *location; const char *hivename = reg_get_predef_name(hkey); *k = NULL; @@ -38,12 +39,13 @@ static WERROR reg_samba_get_predef (struct registry_context *ctx, uint32_t hkey, return WERR_NOT_SUPPORTED; } - backend = talloc_strdup(NULL, conf); - location = strchr(backend, ':'); - + location = strchr(conf, ':'); if (location) { - *location = '\0'; + backend = talloc_strndup(ctx, conf, (int)(location - conf)); location++; + } else { + backend = talloc_strdup(ctx, "ldb"); + location = conf; } /* FIXME: Different hive backend for HKEY_CLASSES_ROOT: merged view of HKEY_LOCAL_MACHINE\Software\Classes -- cgit From 9fffd12799239219a276b1ca83319d1340d97232 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Aug 2005 01:25:58 +0000 Subject: r9338: fixed the winreg IDL to be correct for the EnumKey and EnumValue calls. The previous IDL was just a workaround for the limitations of our older rpc infrastructure. Now that Jelmer has added much improved string support using the charset keyword we can correctly implemenent the unusual winreg string buffers. Jelmer, note the little comment I put on winreg_StringBuf() about why I couldn't use [value()] for the length field. This also fixes EnumKey() and EnumValue() to use NTTIME fields for the last_changed_time. I don't know why we were using a pair of uint32's, as it is just a NTTIME. (This used to be commit 8354b016122cc4f3cff042b3ada1de07e1614eb7) --- source4/lib/registry/reg_backend_rpc.c | 49 ++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 23 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 73d2d54687..5734b96770 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -177,8 +177,8 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *p struct winreg_EnumValue r; uint32_t type, len1, zero = 0; NTSTATUS status; - uint8_t buf8; - uint16_t buf16; + struct winreg_StringBuf name; + uint8_t u8; if(mykeydata->num_values == -1) { error = rpc_query_key(parent); @@ -187,17 +187,18 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *p len1 = mykeydata->max_valdatalen; + name.length = 0; + name.size = mykeydata->max_valnamelen * 2; + name.name = ""; + r.in.handle = &mykeydata->pol; r.in.enum_index = n; - r.in.name_in.length = 0; - r.in.name_in.size = mykeydata->max_valnamelen * 2; - r.in.name_in.name = &buf16; + r.in.name = &name; r.in.type = &type; - r.in.value = &buf8; + r.in.value = &u8; r.in.length = &zero; r.in.size = &len1; - r.out.type = &type; - + r.out.name = &name; status = dcerpc_winreg_EnumValue((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r); if(NT_STATUS_IS_ERR(status)) { @@ -208,7 +209,7 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *p if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result) && r.out.length) { *value = talloc(mem_ctx, struct registry_value); - (*value)->name = talloc_strdup(mem_ctx, r.out.name_out.name); + (*value)->name = talloc_strdup(mem_ctx, r.out.name->name); (*value)->data_type = type; (*value)->data_len = *r.out.length; (*value)->data_blk = talloc_memdup(mem_ctx, r.out.value, *r.out.length); @@ -221,27 +222,29 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *p static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_key **subkey) { struct winreg_EnumKey r; - struct winreg_EnumKeyNameRequest keyname; - struct winreg_String classname; - struct winreg_Time tm; struct rpc_key_data *mykeydata = parent->backend_data; NTSTATUS status; + struct winreg_StringBuf namebuf, classbuf; + NTTIME change_time = 0; - r.in.handle = &mykeydata->pol; - keyname.unknown = 0x0000020a; - init_winreg_String(&keyname.key_name, NULL); - init_winreg_String(&classname, NULL); - r.in.in_name = &keyname; - r.in.class = &classname; - tm.low = tm.high = 0x7fffffff; - r.in.last_changed_time = &tm; + namebuf.length = 0; + namebuf.size = 1024; + namebuf.name = NULL; + classbuf.length = 0; + classbuf.size = 0; + classbuf.name = NULL; + r.in.handle = &mykeydata->pol; r.in.enum_index = n; - r.in.unknown = r.out.unknown = 0x0414; - r.in.key_name_len = r.out.key_name_len = 0; + r.in.name = &namebuf; + r.in.class = &classbuf; + r.in.last_changed_time = &change_time; + r.out.name = &namebuf; + status = dcerpc_winreg_EnumKey((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r); if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { - return rpc_open_key(mem_ctx, parent, talloc_strdup(mem_ctx, r.out.out_name->name), subkey); + char *name = talloc_strdup(mem_ctx, r.out.name->name); + return rpc_open_key(mem_ctx, parent, name, subkey); } return r.out.result; -- cgit From 878e139f09e6e2f87de35341f4340119959469e5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 17 Aug 2005 12:51:07 +0000 Subject: r9357: Remove DBGC_CLASS cruft copied over from Samba 3. I would like to replace this with something funkier. (This used to be commit 8d376d56c78894b9bbd27ed7fa70da415c0cd038) --- source4/lib/registry/common/reg_interface.c | 3 --- source4/lib/registry/common/reg_util.c | 3 --- source4/lib/registry/reg_samba.c | 3 --- 3 files changed, 9 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 76de2f041f..2abe90f2d1 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -22,9 +22,6 @@ #include "dlinklist.h" #include "registry.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_REGISTRY - /* List of available backends */ static struct reg_init_function_entry *backends = NULL; diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index e12cff186a..2d933f2e6b 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -21,9 +21,6 @@ #include "includes.h" #include "registry.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_REGISTRY - static const struct { uint32_t id; const char *name; diff --git a/source4/lib/registry/reg_samba.c b/source4/lib/registry/reg_samba.c index 3c9ae3f415..6341a1c4ee 100644 --- a/source4/lib/registry/reg_samba.c +++ b/source4/lib/registry/reg_samba.c @@ -20,9 +20,6 @@ #include "includes.h" #include "registry.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_REGISTRY - static WERROR reg_samba_get_predef (struct registry_context *ctx, uint32_t hkey, struct registry_key **k) { WERROR error; -- cgit From 20b6f0a11b7827f327de05b68370759129db1fe2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Aug 2005 06:14:10 +0000 Subject: r9378: initialise the last_mod attribute in the ldb backend. Better to return 0 than an uninitialised value, but we should put proper last_modified time support into the ldb winreg backend in the future (This used to be commit 899bf07908d4a04cb3d1cd4034dca0c91e6a912b) --- source4/lib/registry/reg_backend_ldb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 8a5eac59c5..19d982c109 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -170,6 +170,8 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, talloc_set_destructor(*subkey, reg_close_ldb_key); (*subkey)->name = talloc_strdup(mem_ctx, el->values[0].data); (*subkey)->backend_data = newkd = talloc_zero(*subkey, struct ldb_key_data); + (*subkey)->last_mod = 0; /* TODO: we need to add this to the + ldb backend properly */ newkd->dn = talloc_strdup(mem_ctx, kd->subkeys[idx]->dn); return WERR_OK; -- cgit From 09085941d130542cf4609ec4cb5b743ba1c25f42 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 18 Aug 2005 07:00:37 +0000 Subject: r9381: Line wrapping. (This used to be commit 2cebdd59387786c8aeee4c6757e38ed5303f7315) --- source4/lib/registry/README | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/README b/source4/lib/registry/README index c91d361acd..db1fb7a678 100644 --- a/source4/lib/registry/README +++ b/source4/lib/registry/README @@ -1,22 +1,23 @@ -This is the registry library. The registry is basically a bunch of hives -that can be loaded from different places. +This is the registry library. The registry is basically a bunch of +hives that can be loaded from different places. + +The various registry backends provide support for loading/saving +specific types of hives: -The various registry backends provide support for loading/saving specific types -of hives: - ldb - w95 (USER.DAT-style files) - nt4 (NTUSER.DAT-style files) - gconf (GNOME configuration) - rpc (Remote individual hives) -Instead of opening individual hives, one can also open a 'complete' registry by -using one of these three functions: +Instead of opening individual hives, one can also open a 'complete' +registry by using one of these three functions: - reg_open_local() - load local registry, see below - reg_open_remote() - connect to remote registry over RPC - reg_open_wine() (not working yet) -reg_open_local() loads a set of hives based on smb.conf settings. +reg_open_local() loads a set of hives based on smb.conf settings. Lines in smb.conf should have the following syntax: registry: = : @@ -38,4 +39,3 @@ HKEY_LOCAL_MACHINE\Software: %SystemRoot%\System32\Config\Software HKEY_LOCAL_MACHINE\System: %SystemRoot%\System32\Config\System HKEY_USERS\.DEFAULT: %SystemRoot%\System32\Config\Default HKEY_LOCAL_MACHINE\HARDWARE: is autogenerated - -- cgit From 6c1dde71f4ace7901fa13347ef9ced0ac8b16233 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Aug 2005 10:58:05 +0000 Subject: r9386: OpenKey with a bad name must return WERR_BADFILE (w2k3 regedit relies on this) (This used to be commit ae42976590b3c532790d854be45fff49074aef68) --- source4/lib/registry/reg_backend_ldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 19d982c109..784d8ac6fa 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -214,7 +214,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const ch ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL,&msg); if(ret == 0) { - return WERR_NO_MORE_ITEMS; + return WERR_BADFILE; } else if(ret < 0) { DEBUG(0, ("Error opening key '%s': %s\n", ldap_path, ldb_errstring(c))); return WERR_FOOBAR; -- cgit From 6195932b4241d94453438a857179debc08495ece Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Aug 2005 11:15:15 +0000 Subject: r9387: regedit uses "New Key #nn" for newly created keys, which conflicts with the stricter DN rules in ldb. Escape the DN components to cope. Simo, sorry for making a change in ldb_dn.c while you have changes pending. Please feel free to revert these and switch reg_backend_ldb.c to use the new dn construction code. (This used to be commit 136ecf5cb23758558b4119b08047fc273be8b0f8) --- source4/lib/registry/reg_backend_ldb.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 784d8ac6fa..114614597f 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -126,12 +126,24 @@ static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, struct registry_key *from, con while(mypath) { char *keyname; begin = strrchr(mypath, '\\'); + struct ldb_val val; + char *key; - if(begin) keyname = begin + 1; + if (begin) keyname = begin + 1; else keyname = mypath; - if(strlen(keyname)) - ret = talloc_asprintf_append(ret, "key=%s,", keyname); + val.data = keyname; + val.length = strlen(keyname); + + key = ldb_dn_escape_value(mem_ctx, val); + if (key == NULL) { + return NULL; + } + + if (strlen(key)) + ret = talloc_asprintf_append(ret, "key=%s,", key); + + talloc_free(key); if(begin) { *begin = '\0'; -- cgit From a8d51f87620a688a286603766cbb7edb2b7c6e60 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Aug 2005 12:21:42 +0000 Subject: r9390: fixed mixing of code and data (This used to be commit ae2122e76a7e50435dafcc412ee425b522c0c766) --- source4/lib/registry/reg_backend_ldb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 114614597f..3c50258d02 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -125,10 +125,11 @@ static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, struct registry_key *from, con while(mypath) { char *keyname; - begin = strrchr(mypath, '\\'); struct ldb_val val; char *key; + begin = strrchr(mypath, '\\'); + if (begin) keyname = begin + 1; else keyname = mypath; -- cgit From 3e4c4cff2177af33efdb15f03a1bbcb639505cee Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 18 Aug 2005 15:02:01 +0000 Subject: r9391: Convert all the code to use struct ldb_dn to ohandle ldap like distinguished names Provide more functions to handle DNs in this form (This used to be commit 692e35b7797e39533dd2a1c4b63d9da30f1eb5ba) --- source4/lib/registry/reg_backend_ldb.c | 61 ++++++++++++++++------------------ 1 file changed, 29 insertions(+), 32 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 3c50258d02..404dab4dc1 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -25,7 +25,7 @@ struct ldb_key_data { - const char *dn; + const struct ldb_dn *dn; struct ldb_message **subkeys, **values; int subkey_count, value_count; }; @@ -113,39 +113,34 @@ static int reg_close_ldb_key (void *data) return 0; } -static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, struct registry_key *from, const char *path, const char *add) +static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, struct registry_key *from, const char *path, const char *add) { - char *ret = talloc_strdup(mem_ctx, ""); + TALLOC_CTX *local_ctx; + struct ldb_dn *ret = ldb_dn_new(mem_ctx); 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); + local_ctx = talloc_named(mem_ctx, 0, "reg_path_to_ldb context"); + + if (add) + ret = ldb_dn_compose(local_ctx, ret, ldb_dn_explode(mem_ctx, add)); while(mypath) { char *keyname; - struct ldb_val val; - char *key; begin = strrchr(mypath, '\\'); if (begin) keyname = begin + 1; else keyname = mypath; - val.data = keyname; - val.length = strlen(keyname); - - key = ldb_dn_escape_value(mem_ctx, val); - if (key == NULL) { - return NULL; - } + if(strlen(keyname)) { + struct ldb_dn *base; - if (strlen(key)) - ret = talloc_asprintf_append(ret, "key=%s,", key); + base = ldb_dn_build_child(local_ctx, "key", keyname, NULL); + ret = ldb_dn_compose(local_ctx, ret, base); + } - talloc_free(key); - if(begin) { *begin = '\0'; } else { @@ -153,7 +148,7 @@ static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, struct registry_key *from, con } } - ret = talloc_asprintf_append(ret, "%s", kd->dn); + ret = ldb_dn_compose(local_ctx, ret, kd->dn); return ret; } @@ -170,7 +165,7 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, kd->subkey_count = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &kd->subkeys); if(kd->subkey_count < 0) { - DEBUG(0, ("Error getting subkeys for '%s': %s\n", kd->dn, ldb_errstring(c))); + DEBUG(0, ("Error getting subkeys for '%s': %s\n", ldb_dn_linearize(mem_ctx, kd->dn), ldb_errstring(c))); return WERR_FOOBAR; } } @@ -185,7 +180,7 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, (*subkey)->backend_data = newkd = talloc_zero(*subkey, struct ldb_key_data); (*subkey)->last_mod = 0; /* TODO: we need to add this to the ldb backend properly */ - newkd->dn = talloc_strdup(mem_ctx, kd->subkeys[idx]->dn); + newkd->dn = ldb_dn_copy(mem_ctx, kd->subkeys[idx]->dn); return WERR_OK; } @@ -200,7 +195,7 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, i kd->value_count = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(value=*)", NULL,&kd->values); if(kd->value_count < 0) { - DEBUG(0, ("Error getting values for '%s': %s\n", kd->dn, ldb_errstring(c))); + DEBUG(0, ("Error getting values for '%s': %s\n", ldb_dn_linearize(mem_ctx, kd->dn), ldb_errstring(c))); return WERR_FOOBAR; } } @@ -218,18 +213,18 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const ch { struct ldb_context *c = h->hive->backend_data; struct ldb_message **msg; - char *ldap_path; + struct ldb_dn *ldap_path; int ret; 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); + ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL, &msg); if(ret == 0) { return WERR_BADFILE; } else if(ret < 0) { - DEBUG(0, ("Error opening key '%s': %s\n", ldap_path, ldb_errstring(c))); + DEBUG(0, ("Error opening key '%s': %s\n", ldb_dn_linearize(ldap_path, ldap_path), ldb_errstring(c))); return WERR_FOOBAR; } @@ -237,7 +232,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const ch talloc_set_destructor(*key, reg_close_ldb_key); (*key)->name = talloc_strdup(mem_ctx, strrchr(name, '\\')?strchr(name, '\\'):name); (*key)->backend_data = newkd = talloc_zero(*key, struct ldb_key_data); - newkd->dn = talloc_strdup(mem_ctx, msg[0]->dn); + newkd->dn = ldb_dn_copy(mem_ctx, msg[0]->dn); talloc_free(msg); @@ -265,7 +260,7 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) talloc_set_destructor (hive, ldb_free_hive); (*k)->name = talloc_strdup(*k, ""); (*k)->backend_data = kd = talloc_zero(*k, struct ldb_key_data); - kd->dn = talloc_strdup(*k, "hive=NONE"); + kd->dn = ldb_dn_explode(*k, "hive=NONE"); return WERR_OK; @@ -303,11 +298,12 @@ static WERROR ldb_del_key (struct registry_key *key, const char *child) { int ret; struct ldb_key_data *kd = key->backend_data; - char *childdn = talloc_asprintf(NULL, "key=%s,%s", child, kd->dn); + TALLOC_CTX *local_ctx = talloc_named(NULL, 0, "ldb_del_key mem ctx"); + struct ldb_dn *childdn = ldb_dn_build_child(local_ctx, "key", child, kd->dn); ret = ldb_delete(key->hive->backend_data, childdn); - talloc_free(childdn); + talloc_free(local_ctx); if (ret < 0) { DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(key->hive->backend_data))); @@ -321,11 +317,12 @@ static WERROR ldb_del_value (struct registry_key *key, const char *child) { int ret; struct ldb_key_data *kd = key->backend_data; - char *childdn = talloc_asprintf(NULL, "value=%s,%s", child, kd->dn); + TALLOC_CTX *local_ctx = talloc_named(NULL, 0, "ldb_del_value mem ctx"); + struct ldb_dn *childdn = ldb_dn_build_child(local_ctx, "value", child, kd->dn); ret = ldb_delete(key->hive->backend_data, childdn); - talloc_free(childdn); + talloc_free(local_ctx); if (ret < 0) { DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(key->hive->backend_data))); @@ -345,7 +342,7 @@ static WERROR ldb_set_value (struct registry_key *parent, const char *name, uint msg = reg_ldb_pack_value(ctx, mem_ctx, name, type, data, len); - msg->dn = talloc_asprintf(mem_ctx, "value=%s,%s", name, kd->dn); + msg->dn = ldb_dn_build_child(msg, "value", name, kd->dn); ret = ldb_add(ctx, msg); if (ret < 0) { -- cgit From a92e61c4528b46628275216c9252a7a7f6e07dfc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 23 Aug 2005 03:22:25 +0000 Subject: r9503: removed duplicate REG_* defines from registry.h now that they are generated in winreg.h (This used to be commit fc15e1b003a2b24dc73a6a7f2bbc45e20373dda1) --- source4/lib/registry/common/reg_util.c | 1 + source4/lib/registry/reg_backend_ldb.c | 5 +++-- source4/lib/registry/tools/regpatch.c | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index 2d933f2e6b..65f1167832 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -20,6 +20,7 @@ #include "includes.h" #include "registry.h" +#include "librpc/gen_ndr/winreg.h" static const struct { uint32_t id; diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 404dab4dc1..76ad1facc1 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -22,6 +22,7 @@ #include "registry.h" #include "lib/ldb/include/ldb.h" #include "db_wrap.h" +#include "librpc/gen_ndr/winreg.h" struct ldb_key_data { @@ -51,7 +52,7 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, c *len = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, val->data, val->length, data); break; - case REG_DWORD_LE: + case REG_DWORD: *len = 4; *data = talloc(mem_ctx, uint32_t); SIVAL(*data, 0, strtol(val->data, NULL, 0)); @@ -78,7 +79,7 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, TALLOC_CT val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8, data, len, &val.data); ldb_msg_add_value(ctx, msg, "data", &val); break; - case REG_DWORD_LE: + case REG_DWORD: ldb_msg_add_string(ctx, msg, "data", talloc_asprintf(mem_ctx, "0x%x", IVAL(data, 0))); break; default: diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 3ada9f66e2..c2f01ce5b4 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -25,6 +25,7 @@ #include "registry.h" #include "lib/cmdline/popt_common.h" #include "system/filesys.h" +#include "librpc/gen_ndr/winreg.h" /* * Routines to parse a REGEDIT4 file -- cgit From 649882d8d59f35cf51166bedd73c2eab4cea7e50 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 Aug 2005 08:31:39 +0000 Subject: r9567: fixed the winreg IDL for CreateKey, including a security descriptor. To keep it simple I just use normal IDL buffers for now, avoiding the complex methods metze used in spoolss. We might change that later Also added decoding of the security_descriptor in winreg_GetKeySecurity() in smbtorture (This used to be commit 439f34a9621e2e96329c30cfed8d78b8fdfbd8a2) --- source4/lib/registry/reg_backend_rpc.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 5734b96770..44de3bcd77 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -29,14 +29,7 @@ static struct hive_operations reg_backend_rpc; static void init_winreg_String(struct winreg_String *name, const char *s) { - name->name = s; - if (s) { - name->name_len = 2 * (strlen_m(s) + 1); - name->name_size = name->name_len; - } else { - name->name_len = 0; - name->name_size = 0; - } + name->name = s; } @@ -255,14 +248,14 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, cons NTSTATUS status; struct winreg_CreateKey r; - init_winreg_String(&r.in.key, name); + init_winreg_String(&r.in.name, name); init_winreg_String(&r.in.class, NULL); r.in.handle = parent->backend_data; - r.out.handle = talloc(mem_ctx, struct policy_handle); + r.out.new_handle = talloc(mem_ctx, struct policy_handle); r.in.options = 0; - r.in.access_mask = access_mask; - r.in.sec_desc = NULL; + r.in.access_required = access_mask; + r.in.secdesc = NULL; status = dcerpc_winreg_CreateKey((struct dcerpc_pipe *)(parent->hive->backend_data), mem_ctx, &r); @@ -274,7 +267,7 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, cons if (W_ERROR_IS_OK(r.out.result)) { *key = talloc(mem_ctx, struct registry_key); (*key)->name = talloc_strdup(*key, name); - (*key)->backend_data = r.out.handle; + (*key)->backend_data = r.out.new_handle; } return r.out.result; -- cgit From 201fd3bd72d5f080eb16455f35e182c266aaf64b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 3 Sep 2005 14:58:00 +0000 Subject: r9995: Add file describing the REGF file format in IDL. (used in reg_backend_nt4.c rewrite) (This used to be commit 5e1a16eda28d432b94dc933b44da3ca556f92fdf) --- source4/lib/registry/regf.idl | 154 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 source4/lib/registry/regf.idl (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/regf.idl b/source4/lib/registry/regf.idl new file mode 100644 index 0000000000..8bef15c79e --- /dev/null +++ b/source4/lib/registry/regf.idl @@ -0,0 +1,154 @@ +/* + Definitions for the REGF registry file format as used by + Windows NT4 and above. + + Written by Jelmer Vernooij, 2005 + + Based on two files from Samba 3: + regedit.c by Richard Sharpe + regfio.c by Jerry Carter + + Thanks to Wilco Baan Hofman for some of the info on li and ri fields. +*/ + +interface regf +{ + typedef struct { + uint32 major; + uint32 minor; + uint32 release; + uint32 build; + } regf_version; + + /* 1.3.0.1 for WinNT 4 + * 1.5.0.1 for WinXP + */ + + + /* + "regf" is obviously the abbreviation for "Registry file". "regf" is the + signature of the header-block which is always 4kb in size, although only + the first 64 bytes seem to be used and a checksum is calculated over + the first 0x200 bytes only! + */ + + typedef [public] struct { + [charset(DOS)] uint8 REGF_ID[4]; /* 'regf' */ + uint32 update_counter1; + uint32 update_counter2; + NTTIME modtime; + regf_version version; + uint32 data_offset; + uint32 last_block; + [value(1)] uint32 uk7; /* 1 */ + [charset(UTF16)] uint16 description[0x40]; + uint32 padding[83]; /* Padding */ + /* Checksum of first 0x200 bytes XOR-ed */ + uint32 chksum; + } regf_hdr; + + /* + hbin probably means hive-bin (what bin stands for I don't know) + This block is always a multiple + of 4kb in size. + */ + typedef [public] struct { + [charset(DOS)] uint8 HBIN_ID[4]; /* hbin */ + uint32 off_from_first; /* Offset from 1st hbin-Block */ + uint32 off_to_next; /* Offset to the next hbin-Block */ + uint32 unknown[2]; + NTTIME last_change; + uint32 block_size; /* Block size */ + uint8 data[block_size]; /* Filled with hbin_data blocks */ + } hbin_block; + + typedef struct { + uint32 length; + [charset(DOS)] uint8 header[2]; /* li, lh, ri, nk, vk, sk, lf or \0\0 */ + uint8 data[length-2]; + } hbin_data; + + typedef enum { + REG_ROOT_KEY = 0x20, + REG_SUB_KEY = 0x2C, + REG_SYM_LINK = 0x10 + } reg_key_type; + + /* + The nk-record can be treated as a combination of tree-record and + key-record of the win 95 registry. + */ + typedef struct { + reg_key_type type; + NTTIME last_change; + uint32 uk1; + uint32 parent_offset; + uint32 num_subkeys; + uint32 uk2; + uint32 subkeys_offset; + uint32 uk3; + uint32 num_values; + uint32 values_offset; + uint32 sk_offset; + uint32 clsnam_offset; + uint32 unk4[5]; + uint16 name_length; + uint16 clsname_length; + [charset(DOS)] uint8 key_name[name_length]; + } nk_block; + + /* sk (? Security Key ?) is the ACL of the registry. */ + typedef struct { + uint16 uk1; + uint32 prev_offset; + uint32 next_offset; + uint32 ref_cnt; + uint32 rec_size; + uint8 sec_desc[rec_size]; + } sk_block; + + typedef struct { + uint32 offset_nk; + uint32 base37; /* base37 of key name */ + } lh_hash; + + typedef struct { + uint16 key_count; + lh_hash hashes[key_count]; + } lh_block; + + typedef struct { + uint16 key_count; + uint32 offset_nk[key_count]; + } li_block; + + typedef struct { + uint16 key_count; + uint32 offset[key_count]; /* li/lh offset */ + } ri_block; + + /* The vk-record consists information to a single value (value key). */ + typedef struct { + uint16 name_length; + uint32 data_length; /* If top-bit set, offset contains the data */ + uint32 data_offset; + uint32 data_type; + uint16 flag; /* =1, has name, else no name (=Default). */ + uint16 unk1; + [charset(DOS)] uint8 data_name[name_length]; + } vk_block; + + typedef struct { + uint32 nk_off; + uint8 hash[4]; + } hash_record; + + /* + The lf-record is the counterpart to the RGKN-record (the + hash-function) + */ + typedef struct { + uint16 key_count; + hash_record hr[key_count]; /* Array of hash records, depending on key_count */ + } lf_block; +} -- cgit From 02b3abec25ed0b303906c5dae9dd527171762d9a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 3 Sep 2005 17:17:30 +0000 Subject: r10007: Merge data_blk and data_len member of registry_value into a DATA_BLOB. Fix handling of REG_DWORD in the LDB backend. Fix a couple of warnings (This used to be commit 709fdc7ebf5a77cfb50359fad978884777decc3b) --- source4/lib/registry/TODO | 2 ++ source4/lib/registry/common/reg_interface.c | 10 ++++----- source4/lib/registry/common/reg_util.c | 34 ++++++++++------------------- source4/lib/registry/reg_backend_ldb.c | 34 ++++++++++++++--------------- source4/lib/registry/reg_backend_nt4.c | 30 ++++++++++++------------- source4/lib/registry/reg_backend_rpc.c | 9 ++++---- source4/lib/registry/reg_backend_w95.c | 5 ++--- source4/lib/registry/regf.idl | 22 ++++++++++--------- source4/lib/registry/tools/regdiff.c | 2 +- source4/lib/registry/tools/regpatch.c | 8 ++++--- source4/lib/registry/tools/regshell.c | 2 +- 11 files changed, 75 insertions(+), 83 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/TODO b/source4/lib/registry/TODO index 1dea9d2650..3f48d031e1 100644 --- a/source4/lib/registry/TODO +++ b/source4/lib/registry/TODO @@ -31,3 +31,5 @@ gregedit.c: - support for editing values / adding values / deleting values - support for adding/deleting keys - support for security descriptors + +- pass parsed paths around rather then strings (i.e. just a list of strings) diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 2abe90f2d1..7f745143e6 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -252,7 +252,7 @@ WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *key, return WERR_OK; } -WERROR reg_key_num_subkeys(struct registry_key *key, int *count) +WERROR reg_key_num_subkeys(struct registry_key *key, uint32_t *count) { if(!key) return WERR_INVALID_PARAM; @@ -277,7 +277,7 @@ WERROR reg_key_num_subkeys(struct registry_key *key, int *count) return WERR_NOT_SUPPORTED; } -WERROR reg_key_num_values(struct registry_key *key, int *count) +WERROR reg_key_num_values(struct registry_key *key, uint32_t *count) { if(!key) return WERR_INVALID_PARAM; @@ -416,11 +416,11 @@ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, struct registry_key *parent, const return WERR_OK; } -WERROR reg_val_set(struct registry_key *key, const char *value, uint32_t type, void *data, int len) +WERROR reg_val_set(struct registry_key *key, const char *value, uint32_t type, DATA_BLOB data) { /* A 'real' set function has preference */ if (key->hive->functions->set_value) - return key->hive->functions->set_value(key, value, type, data, len); + return key->hive->functions->set_value(key, value, type, data); DEBUG(1, ("Backend '%s' doesn't support method set_value\n", key->hive->functions->name)); return WERR_NOT_SUPPORTED; @@ -501,7 +501,7 @@ WERROR reg_key_valuesizes(struct registry_key *key, uint32_t *max_valnamelen, ui if (value->name) { *max_valnamelen = MAX(*max_valnamelen, strlen(value->name)); } - *max_valbufsize = MAX(*max_valbufsize, value->data_len); + *max_valbufsize = MAX(*max_valbufsize, value->data.length); } i++; diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index 65f1167832..a0d4db6f57 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -48,35 +48,25 @@ const char *str_regtype(int type) char *reg_val_data_string(TALLOC_CTX *mem_ctx, struct registry_value *v) { - char *asciip; char *ret = NULL; - int i; - if(v->data_len == 0) return talloc_strdup(mem_ctx, ""); + if(v->data.length == 0) return talloc_strdup(mem_ctx, ""); switch (v->data_type) { case REG_EXPAND_SZ: case REG_SZ: - convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, v->data_blk, v->data_len, (void **)&ret); + convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, v->data.data, v->data.length, (void **)&ret); return ret; case REG_BINARY: - ret = talloc_array_size(mem_ctx, 3, v->data_len+1); - asciip = ret; - for (i=0; idata_len; i++) { - int str_rem = v->data_len * 3 - (asciip - ret); - asciip += snprintf(asciip, str_rem, "%02x", *(uint8_t *)(((char *)v->data_blk)+i)); - if (i < v->data_len && str_rem > 0) - *asciip = ' '; asciip++; - } - *asciip = '\0'; + ret = data_blob_hex_string(mem_ctx, &v->data); return ret; case REG_DWORD: - if (*(int *)v->data_blk == 0) + if (*(int *)v->data.data == 0) return talloc_strdup(mem_ctx, "0"); - return talloc_asprintf(mem_ctx, "0x%x", *(int *)v->data_blk); + return talloc_asprintf(mem_ctx, "0x%x", *(int *)v->data.data); case REG_MULTI_SZ: /* FIXME */ @@ -117,17 +107,17 @@ BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *da { case REG_SZ: case REG_EXPAND_SZ: - (*value)->data_len = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, data_str, strlen(data_str), &(*value)->data_blk); + (*value)->data.length = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, data_str, strlen(data_str), (void **)&(*value)->data.data); break; - case REG_DWORD: - (*value)->data_len = sizeof(uint32_t); - (*value)->data_blk = talloc(mem_ctx, uint32_t); - *((uint32_t *)(*value)->data_blk) = strtol(data_str, NULL, 0); + + case REG_DWORD: { + uint32_t tmp = strtol(data_str, NULL, 0); + (*value)->data = data_blob_talloc(mem_ctx, &tmp, 4); + } break; case REG_NONE: - (*value)->data_len = 0; - (*value)->data_blk = NULL; + ZERO_STRUCT((*value)->data); break; default: diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 76ad1facc1..f51c02a286 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -38,7 +38,7 @@ static int ldb_free_hive (void *_hive) return 0; } -static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, char **name, uint32_t *type, void **data, int *len) +static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, char **name, uint32_t *type, DATA_BLOB *data) { const struct ldb_val *val; *name = talloc_strdup(mem_ctx, ldb_msg_find_string(msg, "value", NULL)); @@ -49,23 +49,22 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, c { case REG_SZ: case REG_EXPAND_SZ: - *len = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, val->data, val->length, data); + data->length = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, val->data, val->length, (void **)&data->data); break; - case REG_DWORD: - *len = 4; - *data = talloc(mem_ctx, uint32_t); - SIVAL(*data, 0, strtol(val->data, NULL, 0)); + case REG_DWORD: { + uint32_t tmp = strtoul((char *)val->data, NULL, 0); + *data = data_blob_talloc(mem_ctx, &tmp, 4); + } break; default: - *data = talloc_memdup(mem_ctx, val->data, val->length); - *len = val->length; + *data = data_blob_talloc(mem_ctx, val->data, val->length); break; } } -static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, const char *name, uint32_t type, void *data, int len) +static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, const char *name, uint32_t type, DATA_BLOB data) { struct ldb_val val; struct ldb_message *msg = talloc_zero(mem_ctx, struct ldb_message); @@ -76,16 +75,15 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, TALLOC_CT switch (type) { case REG_SZ: case REG_EXPAND_SZ: - val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8, data, len, &val.data); + val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8, (void *)data.data, data.length, (void **)&val.data); ldb_msg_add_value(ctx, msg, "data", &val); break; + case REG_DWORD: - ldb_msg_add_string(ctx, msg, "data", talloc_asprintf(mem_ctx, "0x%x", IVAL(data, 0))); + ldb_msg_add_string(ctx, msg, "data", talloc_asprintf(mem_ctx, "0x%x", IVAL(data.data, 0))); break; default: - val.length = len; - val.data = data; - ldb_msg_add_value(ctx, msg, "data", &val); + ldb_msg_add_value(ctx, msg, "data", &data); } @@ -177,7 +175,7 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, *subkey = talloc(mem_ctx, struct registry_key); talloc_set_destructor(*subkey, reg_close_ldb_key); - (*subkey)->name = talloc_strdup(mem_ctx, el->values[0].data); + (*subkey)->name = talloc_strdup(mem_ctx, (char *)el->values[0].data); (*subkey)->backend_data = newkd = talloc_zero(*subkey, struct ldb_key_data); (*subkey)->last_mod = 0; /* TODO: we need to add this to the ldb backend properly */ @@ -205,7 +203,7 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, i *value = talloc(mem_ctx, struct registry_value); - reg_ldb_unpack_value(mem_ctx, kd->values[idx], &(*value)->name, &(*value)->data_type, &(*value)->data_blk, &(*value)->data_len); + reg_ldb_unpack_value(mem_ctx, kd->values[idx], &(*value)->name, &(*value)->data_type, &(*value)->data); return WERR_OK; } @@ -333,7 +331,7 @@ static WERROR ldb_del_value (struct registry_key *key, const char *child) return WERR_OK; } -static WERROR ldb_set_value (struct registry_key *parent, const char *name, uint32_t type, void *data, int len) +static WERROR ldb_set_value (struct registry_key *parent, const char *name, uint32_t type, DATA_BLOB data) { struct ldb_context *ctx = parent->hive->backend_data; struct ldb_message *msg; @@ -341,7 +339,7 @@ static WERROR ldb_set_value (struct registry_key *parent, const char *name, uint int ret; TALLOC_CTX *mem_ctx = talloc_init("ldb_set_value"); - msg = reg_ldb_pack_value(ctx, mem_ctx, name, type, data, len); + msg = reg_ldb_pack_value(ctx, mem_ctx, name, type, data); msg->dn = ldb_dn_build_child(msg, "value", name, kd->dn); diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index e07534884c..06c0d78c85 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -624,7 +624,7 @@ static KEY_SEC_DESC *nt_create_init_sec(struct registry_hive *h) static REGF_HDR *nt_get_regf_hdr(struct registry_hive *h) { REGF *regf = h->backend_data; - SMB_REG_ASSERT(regf); + SMB_ASSERT(regf); if (!regf->base) { /* Try to mmap etc the file */ @@ -650,7 +650,7 @@ static REGF_HDR *nt_get_regf_hdr(struct registry_hive *h) * header */ - SMB_REG_ASSERT(regf->base != NULL); + SMB_ASSERT(regf->base != NULL); return (REGF_HDR *)regf->base; } @@ -828,7 +828,7 @@ static KEY_SEC_DESC *process_sk(struct registry_hive *regf, SK_HDR *sk_hdr, int /* Here, we have an item in the map that has been reserved, or tmp==NULL. */ - SMB_REG_ASSERT(tmp == NULL || (tmp && tmp->state != SEC_DESC_NON)); + SMB_ASSERT(tmp == NULL || (tmp && tmp->state != SEC_DESC_NON)); /* * Now, allocate a KEY_SEC_DESC, and parse the structure here, and add the @@ -870,10 +870,10 @@ static KEY_SEC_DESC *process_sk(struct registry_hive *regf, SK_HDR *sk_hdr, int sk_prev_off = IVAL(&sk_hdr->prev_off,0); tmp->prev = lookup_create_sec_key(regf, regf->sk_map, sk_prev_off); - SMB_REG_ASSERT(tmp->prev != NULL); + SMB_ASSERT(tmp->prev != NULL); sk_next_off = IVAL(&sk_hdr->next_off,0); tmp->next = lookup_create_sec_key(regf, regf->sk_map, sk_next_off); - SMB_REG_ASSERT(tmp->next != NULL); + SMB_ASSERT(tmp->next != NULL); return tmp; } @@ -934,9 +934,7 @@ static WERROR vk_to_val(TALLOC_CTX *mem_ctx, struct registry_key *parent, VK_HDR memcpy(dtmp, &dat_off, dat_len); } - - tmp->data_blk = dtmp; - tmp->data_len = dat_len; + tmp->data = data_blob_talloc(mem_ctx, dtmp, dat_len); } *value = tmp; @@ -968,14 +966,14 @@ static WERROR lf_verify(struct registry_hive *h, LF_HDR *lf_hdr, int size) return WERR_OK; } -static WERROR lf_num_entries(struct registry_hive *h, LF_HDR *lf_hdr, int size, int *count) +static WERROR lf_num_entries(struct registry_hive *h, LF_HDR *lf_hdr, int size, uint32_t *count) { WERROR error; error = lf_verify(h, lf_hdr, size); if(!W_ERROR_IS_OK(error)) return error; - SMB_REG_ASSERT(size < 0); + SMB_ASSERT(size < 0); *count = SVAL(&lf_hdr->key_count,0); DEBUG(2, ("Key Count: %u\n", *count)); @@ -1004,7 +1002,7 @@ static WERROR lf_get_entry(TALLOC_CTX *mem_ctx, struct registry_key *parent, LF_ error = lf_verify(parent->hive, lf_hdr, size); if(!W_ERROR_IS_OK(error)) return error; - SMB_REG_ASSERT(size < 0); + SMB_ASSERT(size < 0); count = SVAL(&lf_hdr->key_count,0); DEBUG(2, ("Key Count: %u\n", count)); @@ -1035,7 +1033,7 @@ static WERROR nk_to_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, NK_HDR *nk return WERR_INVALID_PARAM; } - SMB_REG_ASSERT(size < 0); + SMB_ASSERT(size < 0); namlen = SVAL(&nk_hdr->nam_len,0); clsname_len = SVAL(&nk_hdr->clsnam_len,0); @@ -1059,7 +1057,7 @@ static WERROR nk_to_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, NK_HDR *nk /* Fish out the key name and process the LF list */ - SMB_REG_ASSERT(namlen < sizeof(key_name)); + SMB_ASSERT(namlen < sizeof(key_name)); strncpy(key_name, nk_hdr->key_nam, namlen); key_name[namlen] = '\0'; @@ -1194,7 +1192,7 @@ static void *nt_alloc_regf_space(struct registry_hive *h, int size, uint_t *off) if (!regf || !size || !off) return NULL; - SMB_REG_ASSERT(regf->blk_head != NULL); + SMB_ASSERT(regf->blk_head != NULL); /* * round up size to include header and then to 8-byte boundary @@ -1653,7 +1651,7 @@ static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) } -static WERROR nt_num_subkeys(struct registry_key *k, int *num) +static WERROR nt_num_subkeys(struct registry_key *k, uint32_t *num) { REGF *regf = k->hive->backend_data; LF_HDR *lf_hdr; @@ -1670,7 +1668,7 @@ static WERROR nt_num_subkeys(struct registry_key *k, int *num) return lf_num_entries(k->hive, lf_hdr, BLK_SIZE(lf_hdr), num); } -static WERROR nt_num_values(struct registry_key *k, int *count) +static WERROR nt_num_values(struct registry_key *k, uint32_t *count) { NK_HDR *nk_hdr = k->backend_data; *count = IVAL(&nk_hdr->val_cnt,0); diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 44de3bcd77..a00accc6be 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -204,8 +204,7 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *p *value = talloc(mem_ctx, struct registry_value); (*value)->name = talloc_strdup(mem_ctx, r.out.name->name); (*value)->data_type = type; - (*value)->data_len = *r.out.length; - (*value)->data_blk = talloc_memdup(mem_ctx, r.out.value, *r.out.length); + (*value)->data = data_blob_talloc(mem_ctx, r.out.value, *r.out.length); return WERR_OK; } @@ -318,7 +317,8 @@ static WERROR rpc_del_key(struct registry_key *parent, const char *name) return r.out.result; } -static WERROR rpc_num_values(struct registry_key *key, int *count) { +static WERROR rpc_num_values(struct registry_key *key, uint32_t *count) +{ struct rpc_key_data *mykeydata = key->backend_data; WERROR error; @@ -331,7 +331,8 @@ static WERROR rpc_num_values(struct registry_key *key, int *count) { return WERR_OK; } -static WERROR rpc_num_subkeys(struct registry_key *key, int *count) { +static WERROR rpc_num_subkeys(struct registry_key *key, uint32_t *count) +{ struct rpc_key_data *mykeydata = key->backend_data; WERROR error; diff --git a/source4/lib/registry/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95.c index 45b6105801..03460052da 100644 --- a/source4/lib/registry/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95.c @@ -303,7 +303,7 @@ static WERROR w95_get_subkey_by_index (TALLOC_CTX *mem_ctx, struct registry_key return WERR_NO_MORE_ITEMS; } -static WERROR w95_num_values(struct registry_key *k, int *count) +static WERROR w95_num_values(struct registry_key *k, uint32_t *count) { RGKN_KEY *rgkn_key = k->backend_data; RGDB_KEY *rgdb_key = LOCN_RGDB_KEY((CREG *)k->hive->backend_data, rgkn_key->id.rgdb, rgkn_key->id.id); @@ -335,8 +335,7 @@ static WERROR w95_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, i *value = talloc(mem_ctx, struct registry_value); (*value)->name = talloc_strndup(mem_ctx, (char *)curval+sizeof(RGDB_VALUE), curval->name_len); - (*value)->data_len = curval->data_len; - (*value)->data_blk = talloc_memdup(mem_ctx, (char *)curval+sizeof(RGDB_VALUE)+curval->name_len, curval->data_len); + (*value)->data = data_blob_talloc(mem_ctx, curval+sizeof(RGDB_VALUE)+curval->name_len, curval->data_len); (*value)->data_type = curval->type; return WERR_OK; diff --git a/source4/lib/registry/regf.idl b/source4/lib/registry/regf.idl index 8bef15c79e..03f63debc8 100644 --- a/source4/lib/registry/regf.idl +++ b/source4/lib/registry/regf.idl @@ -13,17 +13,18 @@ interface regf { - typedef struct { - uint32 major; - uint32 minor; - uint32 release; - uint32 build; - } regf_version; - - /* 1.3.0.1 for WinNT 4 + /* + * Registry version number + * 1.3.0.1 for WinNT 4 * 1.5.0.1 for WinXP */ + typedef struct { + [value(1)] uint32 major; + [value(3)] uint32 minor; + [value(0)] uint32 release; + [value(1)] uint32 build; + } regf_version; /* "regf" is obviously the abbreviation for "Registry file". "regf" is the @@ -70,7 +71,7 @@ interface regf typedef enum { REG_ROOT_KEY = 0x20, - REG_SUB_KEY = 0x2C, + REG_SUB_KEY = 0x2C, REG_SYM_LINK = 0x10 } reg_key_type; @@ -90,7 +91,7 @@ interface regf uint32 num_values; uint32 values_offset; uint32 sk_offset; - uint32 clsnam_offset; + uint32 clsname_offset; uint32 unk4[5]; uint16 name_length; uint16 clsname_length; @@ -112,6 +113,7 @@ interface regf uint32 base37; /* base37 of key name */ } lh_hash; + /* Subkey listing with hash of first 4 characters */ typedef struct { uint16 key_count; lh_hash hashes[key_count]; diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index a9d189c033..307ec3793e 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -72,7 +72,7 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(mem_ctx, newkey, i, &v1)); i++) { error2 = reg_key_get_value_by_name(mem_ctx, oldkey, v1->name, &v2); - if ((W_ERROR_IS_OK(error2) && (v2->data_len != v1->data_len || memcmp(v1->data_blk, v2->data_blk, v1->data_len))) + if ((W_ERROR_IS_OK(error2) && data_blob_equal(&v1->data, &v2->data)) || W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { fprintf(out, "\"%s\"=%s:%s\n", v1->name, str_regtype(v1->data_type), reg_val_data_string(mem_ctx, v1)); } diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index c2f01ce5b4..5f7d4376d4 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -704,9 +704,11 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd DEBUG(0, ("Error removing value '%s'\n", val->name)); } modified = True; - } - else { - if(!W_ERROR_IS_OK(reg_val_set(tmp, val->name, val->type, val->val, strlen(val->val)))) { + } else { + DATA_BLOB blob; + blob.data = (uint8_t *)val->val; + blob.length = strlen(val->val); + if(!W_ERROR_IS_OK(reg_val_set(tmp, val->name, val->type, blob))) { DEBUG(0, ("Error adding new value '%s'\n", val->name)); continue; } diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 108cc17336..496b9dc7e5 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -80,7 +80,7 @@ static struct registry_key *cmd_set(TALLOC_CTX *mem_ctx, struct registry_context } 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); + WERROR error = reg_val_set(cur, argv[1], val->data_type, val->data); if (!W_ERROR_IS_OK(error)) { fprintf(stderr, "Error setting value: %s\n", win_errstr(error)); return NULL; -- cgit From 40cbd4625ae7f9799238594faa4f8cc54ead72e4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 3 Sep 2005 22:58:04 +0000 Subject: r10015: Change the NT4 registry backend to use the IDL-generate parse functions. (This used to be commit 0ad46ef804c0654e927f9c14ea93c45f9e3c718c) --- source4/lib/registry/config.mk | 10 + source4/lib/registry/reg_backend_nt4.c | 1815 ++++---------------------------- source4/lib/registry/regf.idl | 61 +- 3 files changed, 257 insertions(+), 1629 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index c533e17ea9..a1bb62f7df 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -7,9 +7,19 @@ INIT_FUNCTION = registry_nt4_init SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ lib/registry/reg_backend_nt4.o +REQUIRED_SUBSYSTEMS = TDR_REGF # End MODULE registry_nt4 ################################################ +[SUBSYSTEM::TDR_REGF] +REQUIRED_SUBSYSTEMS = TDR +NOPROTO = YES +INIT_OBJ_FILES = lib/registry/tdr_regf.o + +lib/registry/tdr_regf.c: lib/registry/regf.idl + @echo "Compiling lib/registry/regf.idl" + @./pidl/pidl --header --outputdir=lib/registry --parse --tdr-header --tdr-parser -- lib/registry/regf.idl + ################################################ # Start MODULE registry_w95 [MODULE::registry_w95] diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index 06c0d78c85..e0f5ccd08c 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -1,7 +1,7 @@ /* - Samba Unix/Linux SMB client utility libeditreg.c - Copyright (C) 2002 Richard Sharpe, rsharpe@richardsharpe.com - Copyright (C) 2003-2005 Jelmer Vernooij, jelmer@samba.org + Samba CIFS implementation + Registry backend for REGF files + Copyright (C) 2005 Jelmer Vernooij, jelmer@samba.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,1720 +17,331 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/************************************************************************* - - A utility to edit a Windows NT/2K etc registry file. - - Many of the ideas in here come from other people and software. - I first looked in Wine in misc/registry.c and was also influenced by - http://www.wednesday.demon.co.uk/dosreg.html - - Which seems to contain comments from someone else. I reproduce them here - incase the site above disappears. It actually comes from - http://home.eunet.no/~pnordahl/ntpasswd/WinReg.txt. - - The goal here is to read the registry into memory, manipulate it, and then - write it out if it was changed by any actions of the user. - -The windows NT registry has 2 different blocks, where one can occur many -times... - -the "regf"-Block -================ - -"regf" is obviously the abbreviation for "Registry file". "regf" is the -signature of the header-block which is always 4kb in size, although only -the first 64 bytes seem to be used and a checksum is calculated over -the first 0x200 bytes only! - -Offset Size Contents -0x00000000 D-Word ID: ASCII-"regf" = 0x66676572 -0x00000004 D-Word ???? //see struct REG_HANDLE -0x00000008 D-Word ???? Always the same value as at 0x00000004 -0x0000000C Q-Word last modify date in WinNT date-format -0x00000014 D-Word 1 -0x00000018 D-Word 3 -0x0000001C D-Word 0 -0x00000020 D-Word 1 -0x00000024 D-Word Offset of 1st key record -0x00000028 D-Word Size of the data-blocks (Filesize-4kb) -0x0000002C D-Word 1 -0x000001FC D-Word Sum of all D-Words from 0x00000000 to -0x000001FB //XOR of all words. Nigel - -I have analyzed more registry files (from multiple machines running -NT 4.0 german version) and could not find an explanation for the values -marked with ???? the rest of the first 4kb page is not important... - -the "hbin"-Block -================ -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- -management looks like a C-compiler heap management to me... - -hbin-Header -=========== -Offset Size Contents -0x0000 D-Word ID: ASCII-"hbin" = 0x6E696268 -0x0004 D-Word Offset from the 1st hbin-Block -0x0008 D-Word Offset to the next hbin-Block -0x001C D-Word Block-size - -The values in 0x0008 and 0x001C should be the same, so I don't know -if they are correct or swapped... - -From offset 0x0020 inside a hbin-block data is stored with the following -format: - -Offset Size Contents -0x0000 D-Word Data-block size //this size must be a -multiple of 8. Nigel -0x0004 ???? Data - -If the size field is negative (bit 31 set), the corresponding block -is free and has a size of -blocksize! - -That does not seem to be true. All block lengths seem to be negative! -(Richard Sharpe) - -The data is stored as one record per block. Block size is a multiple -of 4 and the last block reaches the next hbin-block, leaving no room. - -(That also seems incorrect, in that the block size if a multiple of 8. -That is, the block, including the 4 byte header, is always a multiple of -8 bytes. Richard Sharpe.) - -Records in the hbin-blocks -========================== - -nk-Record - - The nk-record can be treated as a combination of tree-record and - key-record of the win 95 registry. - -lf-Record - - The lf-record is the counterpart to the RGKN-record (the - hash-function) - -vk-Record - - The vk-record consists information to a single value (value key). - -sk-Record - - sk (? Security Key ?) is the ACL of the registry. - -Value-Lists - - The value-lists contain information about which values are inside a - sub-key and don't have a header. - -Datas - - The datas of the registry are (like the value-list) stored without a - header. - -All offset-values are relative to the first hbin-block and point to the -block-size field of the record-entry. to get the file offset, you have to add -the header size (4kb) and the size field (4 bytes)... - -the nk-Record -============= -Offset Size Contents -0x0000 Word ID: ASCII-"nk" = 0x6B6E -0x0002 Word for the root-key: 0x2C, otherwise 0x20 //key symbolic links 0x10. Nigel -0x0004 Q-Word write-date/time in windows nt notation -0x0010 D-Word Offset of Owner/Parent key -0x0014 D-Word number of sub-Keys -0x001C D-Word Offset of the sub-key lf-Records -0x0024 D-Word number of values -0x0028 D-Word Offset of the Value-List -0x002C D-Word Offset of the sk-Record - -0x0030 D-Word Offset of the Class-Name //see NK structure for the use of these fields. Nigel -0x0044 D-Word Unused (data-trash) //some kind of run time index. Does not appear to be important. Nigel -0x0048 Word name-length -0x004A Word class-name length -0x004C ???? key-name - -the Value-List -============== -Offset Size Contents -0x0000 D-Word Offset 1st Value -0x0004 D-Word Offset 2nd Value -0x???? D-Word Offset nth Value - -To determine the number of values, you have to look at the owner-nk-record! - -The vk-Record -============= -Offset Size Contents -0x0000 Word ID: ASCII-"vk" = 0x6B76 -0x0002 Word name length -0x0004 D-Word length of the data //if top bit is set when offset contains data. Nigel -0x0008 D-Word Offset of Data -0x000C D-Word Type of value -0x0010 Word Flag -0x0012 Word Unused (data-trash) -0x0014 ???? Name - -If bit 0 of the flag-word is set, a name is present, otherwise the value has no name (=default) - -If the data-size is lower 5, the data-offset value is used to store the data itself! - -The data-types -============== -Wert Beteutung -0x0001 RegSZ: character string (in UNICODE!) -0x0002 ExpandSZ: string with "%var%" expanding (UNICODE!) -0x0003 RegBin: raw-binary value -0x0004 RegDWord: Dword -0x0007 RegMultiSZ: multiple strings, seperated with 0 - (UNICODE!) - -The "lf"-record -=============== -Offset Size Contents -0x0000 Word ID: ASCII-"lf" = 0x666C -0x0002 Word number of keys -0x0004 ???? Hash-Records - -Hash-Record -=========== -Offset Size Contents -0x0000 D-Word Offset of corresponding "nk"-Record -0x0004 D-Word ASCII: the first 4 characters of the key-name, padded with 0's. Case sensitiv! - -Keep in mind, that the value at 0x0004 is used for checking the data-consistency! If you change the -key-name you have to change the hash-value too! - -//These hashrecords must be sorted low to high within the lf record. Nigel. - -The "sk"-block -============== -(due to the complexity of the SAM-info, not clear jet) -(This is just a self-relative security descriptor in the data. R Sharpe.) - - -Offset Size Contents -0x0000 Word ID: ASCII-"sk" = 0x6B73 -0x0002 Word Unused -0x0004 D-Word Offset of previous "sk"-Record -0x0008 D-Word Offset of next "sk"-Record -0x000C D-Word usage-counter -0x0010 D-Word Size of "sk"-record in bytes -???? //standard self -relative security desciptor. Nigel -???? ???? Security and auditing settings... -???? - -The usage counter counts the number of references to this -"sk"-record. You can use one "sk"-record for the entire registry! - -Windows nt date/time format -=========================== -The time-format is a 64-bit integer which is incremented every -0,0000001 seconds by 1 (I don't know how accurate it realy is!) -It starts with 0 at the 1st of january 1601 0:00! All values are -stored in GMT time! The time-zone is important to get the real -time! - -Common values for win95 and win-nt -================================== -Offset values marking an "end of list", are either 0 or -1 (0xFFFFFFFF). -If a value has no name (length=0, flag(bit 0)=0), it is treated as the -"Default" entry... -If a value has no data (length=0), it is displayed as empty. - -simplyfied win-3.?? registry: -============================= - -+-----------+ -| next rec. |---+ +----->+------------+ -| first sub | | | | Usage cnt. | -| name | | +-->+------------+ | | length | -| value | | | | next rec. | | | text |------->+-------+ -+-----------+ | | | name rec. |--+ +------------+ | xxxxx | - +------------+ | | value rec. |-------->+------------+ +-------+ - v | +------------+ | Usage cnt. | -+-----------+ | | length | -| next rec. | | | text |------->+-------+ -| first sub |------+ +------------+ | xxxxx | -| name | +-------+ -| value | -+-----------+ - -Greatly simplyfied structure of the nt-registry: -================================================ - -+---------------------------------------------------------------+ -| | -v | -+---------+ +---------->+-----------+ +----->+---------+ | -| "nk" | | | lf-rec. | | | nk-rec. | | -| ID | | | # of keys | | | parent |---+ -| Date | | | 1st key |--+ | .... | -| parent | | +-----------+ +---------+ -| suk-keys|-----+ -| values |--------------------->+----------+ -| SK-rec. |---------------+ | 1. value |--> +----------+ -| class |--+ | +----------+ | vk-rec. | -+---------+ | | | .... | - v | | data |--> +-------+ - +------------+ | +----------+ | xxxxx | - | Class name | | +-------+ - +------------+ | - v - +---------+ +---------+ - +----->| next sk |--->| Next sk |--+ - | +---| prev sk |<---| prev sk | | - | | | .... | | ... | | - | | +---------+ +---------+ | - | | ^ | - | | | | - | +--------------------+ | - +----------------------------------+ - ---------------------------------------------------------------------------- - -Hope this helps.... (Although it was "fun" for me to uncover this things, - it took me several sleepless nights ;) - - B.D. - -*************************************************************************/ - #include "includes.h" #include "registry.h" #include "system/filesys.h" -#include "system/shmem.h" - -#define REG_KEY_LIST_SIZE 10 -#define FLAG_HAS_NAME 0x01 -/*FIXME*/ +#include "lib/registry/tdr_regf.h" /* - * Structures for dealing with the on-disk format of the registry + * Read HBIN blocks into memory */ -const char *def_owner_sid_str = NULL; - -/* - * These definitions are for the in-memory registry structure. - * It is a tree structure that mimics what you see with tools like regedit - */ - - -/* - * Definition of a Key. It has a name, classname, date/time last modified, - * sub-keys, values, and a security descriptor - */ - -#define REG_ROOT_KEY 1 -#define REG_SUB_KEY 2 -#define REG_SYM_LINK 3 - -/* - * All of the structures below actually have a four-byte length before them - * which always seems to be negative. The following macro retrieves that - * size as an integer - */ - -#define BLK_SIZE(b) ((int)*(int *)(((int *)b)-1)) - -typedef struct sk_struct SK_HDR; -/* - * This structure keeps track of the output format of the registry - */ -#define REG_OUTBLK_HDR 1 -#define REG_OUTBLK_HBIN 2 - -typedef struct regf_block { - uint32_t REGF_ID; /* regf */ - uint32_t update_counter1; - uint32_t update_counter2; - uint32_t tim1, tim2; - uint32_t uk3; /* 1 */ - uint32_t uk4; /* 3 */ - uint32_t uk5; /* 0 */ - uint32_t uk6; /* 1 */ - uint32_t first_key; /* offset */ - uint32_t dblk_size; - uint32_t uk7; /* 1 */ - wchar_t filename[64]; - uint32_t unused[83]; - uint32_t chksum; /* Checksum of first 0x200 bytes */ -} REGF_HDR; - -typedef struct hbin_sub_struct { - uint32_t dblocksize; - char data[1]; -} HBIN_SUB_HDR; - -typedef struct hbin_struct { - uint32_t HBIN_ID; /* hbin */ - uint32_t off_from_first; - uint32_t off_to_next; - uint32_t uk1; - uint32_t uk2; - uint32_t uk3; - uint32_t uk4; - uint32_t blk_size; - HBIN_SUB_HDR hbin_sub_hdr; -} HBIN_HDR; - -typedef struct nk_struct { - uint16_t NK_ID; - uint16_t type; - uint32_t t1, t2; - uint32_t uk1; - uint32_t own_off; - uint32_t subk_num; - uint32_t uk2; - uint32_t lf_off; - uint32_t uk3; - uint32_t val_cnt; - uint32_t val_off; - uint32_t sk_off; - uint32_t clsnam_off; - uint32_t unk4[4]; - uint32_t unk5; - uint16_t nam_len; - uint16_t clsnam_len; - char key_nam[1]; /* Actual length determined by nam_len */ -} NK_HDR; - -struct sk_struct { - uint16_t SK_ID; - uint16_t uk1; - uint32_t prev_off; - uint32_t next_off; - uint32_t ref_cnt; - uint32_t rec_size; - char sec_desc[1]; +struct regf_data { + DATA_BLOB data; + struct hbin_block **hbins; }; -typedef struct key_sec_desc_s { - struct key_sec_desc_s *prev, *next; - int ref_cnt; - int state; - int offset; - SK_HDR *sk_hdr; /* This means we must keep the registry in memory */ - struct security_descriptor *sec_desc; -} KEY_SEC_DESC; - -/* A map of sk offsets in the regf to KEY_SEC_DESCs for quick lookup etc */ -typedef struct sk_map_s { - int sk_off; - KEY_SEC_DESC *key_sec_desc; -} SK_MAP; - -typedef struct vk_struct { - uint16_t VK_ID; - uint16_t nam_len; - uint32_t dat_len; /* If top-bit set, offset contains the data */ - uint32_t dat_off; - uint32_t dat_type; - uint16_t flag; /* =1, has name, else no name (=Default). */ - uint16_t unk1; - char dat_name[1]; /* Name starts here ... */ -} VK_HDR; - -typedef uint32_t VL_TYPE[1]; /* Value list is an array of vk rec offsets */ - -typedef struct hash_struct { - uint32_t nk_off; - char hash[4]; -} HASH_REC; - - -typedef struct lf_struct { - uint16_t LF_ID; - uint16_t key_count; - struct hash_struct hr[1]; /* Array of hash records, depending on key_count */} LF_HDR; - - - /* - * This structure keeps track of the output format of the registry + * Validate a regf header + * For now, do nothing, but we should check the checksum */ -#define REG_OUTBLK_HDR 1 -#define REG_OUTBLK_HBIN 2 - -typedef struct hbin_blk_s { - int type, size; - struct hbin_blk_s *next; - char *data; /* The data block */ - uint_t file_offset; /* Offset in file */ - uint_t free_space; /* Amount of free space in block */ - uint_t fsp_off; /* Start of free space in block */ - int complete, stored; -} HBIN_BLK; - -typedef struct regf_struct_s { - int reg_type; - int fd; - struct stat sbuf; - char *base; - BOOL modified; - NTTIME last_mod_time; - NK_HDR *first_key; - int sk_count, sk_map_size; - SK_MAP *sk_map; - const char *owner_sid_str; - 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 - */ - HBIN_BLK *blk_head, *blk_tail, *free_space; -} REGF; - -static uint32_t str_to_dword(const char *a) { +static uint32_t regf_hdr_checksum(const uint8_t *buffer) +{ + uint32_t checksum = 0, x; int i; - unsigned long ret = 0; - for(i = strlen(a)-1; i >= 0; i--) { - ret = ret * 0x100 + a[i]; + + for (i = 0; i < 0x01FB; i+= 4) { + x = IVAL(buffer, i); + checksum ^= x; } - return ret; -} - -#if 0 -/* - * Create an ACE - */ -static BOOL nt_create_ace(SEC_ACE *ace, int type, int flags, uint32_t perms, const char *sid) -{ - DOM_SID s; - SEC_ACCESS access; - access.mask = perms; - if(!string_to_sid(&s, sid))return False; - init_sec_ace(ace, &s, type, access, flags); - return True; + return checksum; } -/* - * Create a default ACL - */ -static SEC_ACL *nt_create_default_acl(struct registry_hive *regf) -{ - SEC_ACE aces[8]; - - if(!nt_create_ace(&aces[0], 0x00, 0x0, 0xF003F, regf->owner_sid_str)) return NULL; - if(!nt_create_ace(&aces[1], 0x00, 0x0, 0xF003F, "S-1-5-18")) return NULL; - if(!nt_create_ace(&aces[2], 0x00, 0x0, 0xF003F, "S-1-5-32-544")) return NULL; - if(!nt_create_ace(&aces[3], 0x00, 0x0, 0x20019, "S-1-5-12")) return NULL; - if(!nt_create_ace(&aces[4], 0x00, 0x0B, GENERIC_RIGHT_ALL_ACCESS, regf->owner_sid_str)) return NULL; - if(!nt_create_ace(&aces[5], 0x00, 0x0B, 0x10000000, "S-1-5-18")) return NULL; - if(!nt_create_ace(&aces[6], 0x00, 0x0B, 0x10000000, "S-1-5-32-544")) return NULL; - if(!nt_create_ace(&aces[7], 0x00, 0x0B, 0x80000000, "S-1-5-12")) return NULL; - - return make_sec_acl(regf->mem_ctx, 2, 8, aces); -} - -/* - * Create a default security descriptor. We pull in things from env - * if need be - */ -static SEC_DESC *nt_create_def_sec_desc(struct registry_hive *regf) -{ - SEC_DESC *tmp; - - tmp = malloc_p(SEC_DESC); - - tmp->revision = 1; - tmp->type = SEC_DESC_SELF_RELATIVE | SEC_DESC_DACL_PRESENT; - if (!string_to_sid(tmp->owner_sid, "S-1-5-32-544")) goto error; - if (!string_to_sid(tmp->grp_sid, "S-1-5-18")) goto error; - tmp->sacl = NULL; - tmp->dacl = nt_create_default_acl(regf); - - return tmp; - - error: - if (tmp) nt_delete_sec_desc(tmp); - return NULL; -} - -/* - * We will implement inheritence that is based on what the parent's SEC_DESC - * says, but the Owner and Group SIDs can be overwridden from the command line - * and additional ACEs can be applied from the command line etc. - */ -static KEY_SEC_DESC *nt_inherit_security(struct registry_key *key) +static DATA_BLOB regf_get_data(const struct regf_data *data, uint32_t offset) { - - if (!key) return NULL; - return key->security; -} - -/* - * Create an initial security descriptor and init other structures, if needed - * We assume that the initial security stuff is empty ... - */ -static KEY_SEC_DESC *nt_create_init_sec(struct registry_hive *h) -{ - REGF *regf = h->backend_data; - KEY_SEC_DESC *tsec = NULL; - - tsec = malloc_p(KEY_SEC_DESC); - - tsec->ref_cnt = 1; - tsec->state = SEC_DESC_NBK; - tsec->offset = 0; - - tsec->sec_desc = regf->def_sec_desc; - - return tsec; + int i; + DATA_BLOB ret; + ret.data = NULL; + ret.length = 0; + + for (i = 0; data->hbins[i]; i++) { + if (offset >= data->hbins[i]->offset_from_first && + offset < data->hbins[i]->offset_from_first+ + data->hbins[i]->offset_to_next) + break; + } + + if (data->hbins[i] == NULL) { + DEBUG(1, ("Can't find HBIN containing 0x%4x\n", offset)); + return ret; + } + + ret.length = IVAL(data->hbins[i]->data, + offset - data->hbins[i]->offset_from_first - 0x20); + if (ret.length & 0x80000000) { + /* absolute value */ + ret.length = (ret.length ^ 0xffffffff) + 1; + } + ret.data = data->hbins[i]->data + + (offset - data->hbins[i]->offset_from_first - 0x20) + 4; + + return ret; } -#endif -/* - * Get the starting record for NT Registry file - */ -/* - * Where we keep all the regf stuff for one registry. - * This is the structure that we use to tie the in memory tree etc - * together. By keeping separate structs, we can operate on different - * registries at the same time. - * Currently, the SK_MAP is an array of mapping structure. - * Since we only need this on input and output, we fill in the structure - * as we go on input. On output, we know how many SK items we have, so - * we can allocate the structure as we need to. - * If you add stuff here that is dynamically allocated, add the - * appropriate free statements below. - */ - -#define REG_HANDLE_REGTYPE_NONE 0 -#define REG_HANDLE_REGTYPE_NT 1 -#define REG_HANDLE_REGTYPE_W9X 2 - -#define TTTONTTIME(r, t1, t2) (r)->last_mod_time = (t1) | (((uint64_t)(t2)) << 32) - -#define REGF_HDR_BLKSIZ 0x1000 - -#define OFF(f) ((f) + REGF_HDR_BLKSIZ + 4) -#define LOCN(base, f) ((base) + OFF(f)) - -/* Get the header of the registry. Return a pointer to the structure - * If the mmap'd area has not been allocated, then mmap the input file - */ -static REGF_HDR *nt_get_regf_hdr(struct registry_hive *h) +static WERROR regf_num_subkeys (struct registry_key *key, uint32_t *count) { - REGF *regf = h->backend_data; - SMB_ASSERT(regf); - - if (!regf->base) { /* Try to mmap etc the file */ + struct nk_block *nk = key->backend_data; - if ((regf->fd = open(h->location, O_RDONLY, 0000)) <0) { - return NULL; /* What about errors? */ - } - - if (fstat(regf->fd, ®f->sbuf) < 0) { - return NULL; - } - - regf->base = mmap(0, regf->sbuf.st_size, PROT_READ, MAP_SHARED, regf->fd, 0); - - if ((int)regf->base == 1) { - DEBUG(0,("Could not mmap file: %s, %s\n", h->location, - strerror(errno))); - return NULL; - } - } - - /* - * At this point, regf->base != NULL, and we should be able to read the - * header - */ - - SMB_ASSERT(regf->base != NULL); - - return (REGF_HDR *)regf->base; -} - -/* - * Validate a regf header - * For now, do nothing, but we should check the checksum - */ -static int valid_regf_hdr(REGF_HDR *regf_hdr) -{ - if (!regf_hdr) return 0; - - return 1; -} - -#if 0 - -/* - * Process an SK header ... - * Every time we see a new one, add it to the map. Otherwise, just look it up. - * We will do a simple linear search for the moment, since many KEYs have the - * same security descriptor. - * We allocate the map in increments of 10 entries. - */ - -/* - * Create a new entry in the map, and increase the size of the map if needed - */ -static SK_MAP *alloc_sk_map_entry(struct registry_hive *h, KEY_SEC_DESC *tmp, int sk_off) -{ - REGF *regf = h->backend_data; - if (!regf->sk_map) { /* Allocate a block of 10 */ - regf->sk_map = malloc_array_p(SK_MAP, 10); - regf->sk_map_size = 10; - regf->sk_count = 1; - (regf->sk_map)[0].sk_off = sk_off; - (regf->sk_map)[0].key_sec_desc = tmp; - } - else { /* Simply allocate a new slot, unless we have to expand the list */ - int ndx = regf->sk_count; - if (regf->sk_count >= regf->sk_map_size) { - regf->sk_map = (SK_MAP *)realloc(regf->sk_map, - (regf->sk_map_size + 10)*sizeof(SK_MAP)); - if (!regf->sk_map) { - free(tmp); - return NULL; - } - /* - * ndx already points at the first entry of the new block - */ - regf->sk_map_size += 10; - } - (regf->sk_map)[ndx].sk_off = sk_off; - (regf->sk_map)[ndx].key_sec_desc = tmp; - regf->sk_count++; - } - return regf->sk_map; + *count = nk->num_subkeys; + + return WERR_OK; } -/* - * Search for a KEY_SEC_DESC in the sk_map, but don't create one if not - * found - */ -KEY_SEC_DESC *lookup_sec_key(SK_MAP *sk_map, int count, int sk_off) +static WERROR regf_num_values (struct registry_key *key, uint32_t *count) { - int i; + struct nk_block *nk = key->backend_data; - if (!sk_map) return NULL; - - for (i = 0; i < count; i++) { - - if (sk_map[i].sk_off == sk_off) - return sk_map[i].key_sec_desc; - - } - - return NULL; + *count = nk->num_values; + return WERR_OK; } -/* - * Allocate a KEY_SEC_DESC if we can't find one in the map - */ -static KEY_SEC_DESC *lookup_create_sec_key(struct registry_hive *h, SK_MAP *sk_map, int sk_off) +static struct registry_key *regf_get_key (TALLOC_CTX *ctx, struct regf_data *regf, uint32_t offset) { - REGF *regf = h->backend_data; - KEY_SEC_DESC *tmp = lookup_sec_key(regf->sk_map, regf->sk_count, sk_off); + DATA_BLOB data = regf_get_data(regf, offset); + struct tdr_pull *pull; + struct registry_key *ret; + struct nk_block *nk; - if (tmp) { - return tmp; - } - else { /* Allocate a new one */ - tmp = malloc_p(KEY_SEC_DESC); - memset(tmp, 0, sizeof(KEY_SEC_DESC)); /* Neatly sets offset to 0 */ - tmp->state = SEC_DESC_RES; - if (!alloc_sk_map_entry(h, tmp, sk_off)) { - return NULL; - } - return tmp; - } -} - -static SEC_DESC *process_sec_desc(struct registry_hive *regf, SEC_DESC *sec_desc) -{ - SEC_DESC *tmp = NULL; - - tmp = malloc_p(SEC_DESC); - - tmp->revision = SVAL(&sec_desc->revision,0); - tmp->type = SVAL(&sec_desc->type,0); - DEBUG(2, ("SEC_DESC Rev: %0X, Type: %0X\n", tmp->revision, tmp->type)); - DEBUGADD(2, ("SEC_DESC Owner Off: %0X\n", IVAL(&sec_desc->off_owner_sid,0))); - DEBUGADD(2, ("SEC_DESC Group Off: %0X\n", IVAL(&sec_desc->off_grp_sid,0))); - DEBUGADD(2, ("SEC_DESC DACL Off: %0X\n", IVAL(&sec_desc->off_dacl,0))); - tmp->owner_sid = sid_dup_talloc(regf->mem_ctx, (DOM_SID *)((char *)sec_desc + IVAL(&sec_desc->off_owner_sid,0))); - if (!tmp->owner_sid) { - free(tmp); + if (data.data == NULL) { + DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset)); return NULL; } - tmp->grp_sid = sid_dup_talloc(regf->mem_ctx, (DOM_SID *)((char *)sec_desc + IVAL(&sec_desc->off_grp_sid,0))); - if (!tmp->grp_sid) { - free(tmp); - return NULL; - } - - /* Now pick up the SACL and DACL */ - - DEBUG(0, ("%d, %d\n", IVAL(&sec_desc->off_sacl,0), IVAL(&sec_desc->off_dacl,0))); - - if (sec_desc->off_sacl) - tmp->sacl = dup_sec_acl(regf->mem_ctx, (SEC_ACL *)((char *)sec_desc + IVAL(&sec_desc->off_sacl,0))); - else - tmp->sacl = NULL; - - if (sec_desc->off_dacl) - tmp->dacl = dup_sec_acl(regf->mem_ctx, (SEC_ACL *)((char *)sec_desc + IVAL(&sec_desc->off_dacl,0))); - else - tmp->dacl = NULL; - - return tmp; -} -static KEY_SEC_DESC *process_sk(struct registry_hive *regf, SK_HDR *sk_hdr, int sk_off, int size) -{ - KEY_SEC_DESC *tmp = NULL; - int sk_next_off, sk_prev_off, sk_size; - SEC_DESC *sec_desc; - - if (!sk_hdr) return NULL; + ret = talloc_zero(ctx, struct registry_key); + pull = talloc_zero(ret, struct tdr_pull); + pull->data = data; + nk = talloc(ret, struct nk_block); - if (SVAL(&sk_hdr->SK_ID,0) != str_to_dword("sk")) { - DEBUG(0, ("Unrecognized SK Header ID: %08X, %s\n", (int)sk_hdr, - regf->regfile_name)); + if (NT_STATUS_IS_ERR(tdr_pull_nk_block(pull, nk))) { + DEBUG(1, ("Error parsing 'nk' record\n")); + talloc_free(ret); return NULL; } - if (-size < (sk_size = IVAL(&sk_hdr->rec_size,0))) { - DEBUG(0, ("Incorrect SK record size: %d vs %d. %s\n", - -size, sk_size, regf->regfile_name)); + if (strcmp(nk->header, "nk") != 0) { + DEBUG(0, ("Expected nk record, got %s\n", nk->header)); + talloc_free(ret); return NULL; } - /* - * Now, we need to look up the SK Record in the map, and return it - * Since the map contains the SK_OFF mapped to KEY_SEC_DESC, we can - * use that - */ - - if (regf->sk_map && - ((tmp = lookup_sec_key(regf->sk_map, regf->sk_count, sk_off)) != NULL) - && (tmp->state == SEC_DESC_OCU)) { - tmp->ref_cnt++; - return tmp; - } - - /* Here, we have an item in the map that has been reserved, or tmp==NULL. */ - - SMB_ASSERT(tmp == NULL || (tmp && tmp->state != SEC_DESC_NON)); - - /* - * Now, allocate a KEY_SEC_DESC, and parse the structure here, and add the - * new KEY_SEC_DESC to the mapping structure, since the offset supplied is - * the actual offset of structure. The same offset will be used by - * all future references to this structure - * We could put all this unpleasantness in a function. - */ - - if (!tmp) { - tmp = malloc_p(KEY_SEC_DESC); - memset(tmp, 0, sizeof(KEY_SEC_DESC)); - - /* - * Allocate an entry in the SK_MAP ... - * We don't need to free tmp, because that is done for us if the - * sm_map entry can't be expanded when we need more space in the map. - */ - - if (!alloc_sk_map_entry(regf, tmp, sk_off)) { - return NULL; - } - } - - tmp->ref_cnt++; - tmp->state = SEC_DESC_OCU; - - /* - * Now, process the actual sec desc and plug the values in - */ + ret->name = talloc_steal(ret, nk->key_name); + ret->last_mod = nk->last_change; + ret->class_name = NULL; /* FIXME: get somehow using clsname_offset */ + ret->backend_data = nk; - sec_desc = (SEC_DESC *)&sk_hdr->sec_desc[0]; - tmp->sec_desc = process_sec_desc(regf, sec_desc); - - /* - * Now forward and back links. Here we allocate an entry in the sk_map - * if it does not exist, and mark it reserved - */ - - sk_prev_off = IVAL(&sk_hdr->prev_off,0); - tmp->prev = lookup_create_sec_key(regf, regf->sk_map, sk_prev_off); - SMB_ASSERT(tmp->prev != NULL); - sk_next_off = IVAL(&sk_hdr->next_off,0); - tmp->next = lookup_create_sec_key(regf, regf->sk_map, sk_next_off); - SMB_ASSERT(tmp->next != NULL); - - return tmp; + return ret; } -#endif -/* - * Process a VK header and return a value - */ -static WERROR vk_to_val(TALLOC_CTX *mem_ctx, struct registry_key *parent, VK_HDR *vk_hdr, int size, struct registry_value **value) +static WERROR regf_get_value (TALLOC_CTX *ctx, struct registry_key *key, int idx, struct registry_value **ret) { - REGF *regf = parent->hive->backend_data; - int nam_len, dat_len, flag, dat_type, dat_off, vk_id; - struct registry_value *tmp = NULL; - - if (!vk_hdr) return WERR_INVALID_PARAM; - - if ((vk_id = SVAL(&vk_hdr->VK_ID,0)) != str_to_dword("vk")) { - DEBUG(0, ("Unrecognized VK header ID: %0X, block: %0X, %s\n", - vk_id, (int)vk_hdr, parent->hive->location)); + struct nk_block *nk = key->backend_data; + struct vk_block *vk; + struct tdr_pull *pull; + uint32_t vk_offset; + DATA_BLOB data; + + if (idx >= nk->num_values) + return WERR_NO_MORE_ITEMS; + + data = regf_get_data(key->hive->backend_data, nk->values_offset); + if (!data.data) { + DEBUG(0, ("Unable to find value list\n")); return WERR_GENERAL_FAILURE; } - nam_len = SVAL(&vk_hdr->nam_len,0); - flag = SVAL(&vk_hdr->flag,0); - dat_type = IVAL(&vk_hdr->dat_type,0); - dat_len = IVAL(&vk_hdr->dat_len,0); /* If top bit, offset contains data */ - dat_off = IVAL(&vk_hdr->dat_off,0); - - tmp = talloc(mem_ctx, struct registry_value); - tmp->data_type = dat_type; - - if (flag & FLAG_HAS_NAME) { - tmp->name = talloc_strndup(mem_ctx, vk_hdr->dat_name, nam_len); - } else { - tmp->name = NULL; + if (data.length < nk->num_values * 4) { + DEBUG(1, ("Value counts mismatch\n")); } - /* - * Allocate space and copy the data as a BLOB - */ - - if (dat_len&0x7FFFFFFF) { - - char *dtmp = talloc_size(mem_ctx, dat_len&0x7FFFFFFF); + vk_offset = IVAL(data.data, idx * 4); - if ((dat_len&0x80000000) == 0) { /* The data is pointed to by the offset */ - char *dat_ptr = LOCN(regf->base, dat_off); - memcpy(dtmp, dat_ptr, dat_len); - } - else { /* The data is in the offset or type */ - /* - * FIXME. - * Some registry files seem to have weird fields. If top bit is set, - * but len is 0, the type seems to be the value ... - * Not sure how to handle this last type for the moment ... - */ - dat_len = dat_len & 0x7FFFFFFF; - memcpy(dtmp, &dat_off, dat_len); - } - - tmp->data = data_blob_talloc(mem_ctx, dtmp, dat_len); + data = regf_get_data(key->hive->backend_data, vk_offset); + if (!data.data) { + DEBUG(0, ("Unable to find value\n")); + return WERR_GENERAL_FAILURE; } - *value = tmp; - return WERR_OK; -} + *ret = talloc_zero(ctx, struct registry_value); + if (!(*ret)) + return WERR_NOMEM; -#if 0 /* unused */ + vk = talloc(*ret, struct vk_block); + if (!vk) + return WERR_NOMEM; + + pull = talloc_zero(*ret, struct tdr_pull); + pull->data = data; -static BOOL vl_verify(VL_TYPE vl, int count, int size) -{ - if(!vl) return False; - if (-size < (count+1)*sizeof(int)){ - DEBUG(0, ("Error in VL header format. Size less than space required. %d\n", -size)); - return False; + if (NT_STATUS_IS_ERR(tdr_pull_vk_block(pull, vk))) { + DEBUG(0, ("Error parsing vk block\n")); + return WERR_GENERAL_FAILURE; } - return True; -} - -#endif -static WERROR lf_verify(struct registry_hive *h, LF_HDR *lf_hdr, int size) -{ - int lf_id; - if ((lf_id = SVAL(&lf_hdr->LF_ID,0)) != str_to_dword("lf")) { - DEBUG(0, ("Unrecognized LF Header format: %0X, Block: %0X, %s.\n", - lf_id, (int)lf_hdr, h->location)); - return WERR_INVALID_PARAM; + (*ret)->name = talloc_steal(*ret, vk->data_name); + (*ret)->data_type = vk->data_type; + if (vk->data_length & 0x80000000) { + vk->data_length &= ~0x80000000; + (*ret)->data.data = (uint8_t *)&vk->data_offset; + (*ret)->data.length = vk->data_length; + } else { + (*ret)->data = regf_get_data(key->hive->backend_data, vk->data_offset); } - return WERR_OK; -} - -static WERROR lf_num_entries(struct registry_hive *h, LF_HDR *lf_hdr, int size, uint32_t *count) -{ - WERROR error; - - error = lf_verify(h, lf_hdr, size); - if(!W_ERROR_IS_OK(error)) return error; - - SMB_ASSERT(size < 0); - - *count = SVAL(&lf_hdr->key_count,0); - DEBUG(2, ("Key Count: %u\n", *count)); - if (*count <= 0) return WERR_INVALID_PARAM; + if ((*ret)->data.length < vk->data_length) { + DEBUG(1, ("Read data less then indicated data length!\n")); + } + return WERR_OK; } - -static WERROR nk_to_key(TALLOC_CTX *, struct registry_hive *regf, NK_HDR *nk_hdr, int size, struct registry_key *parent, struct registry_key **); - - - -/* - * Process an LF Header and return a list of sub-keys - */ -static WERROR lf_get_entry(TALLOC_CTX *mem_ctx, struct registry_key *parent, LF_HDR *lf_hdr, int size, int n, struct registry_key **key) +static WERROR regf_get_subkey (TALLOC_CTX *ctx, struct registry_key *key, int idx, struct registry_key **ret) { - REGF *regf = parent->hive->backend_data; - int count, nk_off; - NK_HDR *nk_hdr; - WERROR error; - - if (!lf_hdr) return WERR_INVALID_PARAM; - - error = lf_verify(parent->hive, lf_hdr, size); - if(!W_ERROR_IS_OK(error)) return error; - - SMB_ASSERT(size < 0); + DATA_BLOB data; + struct nk_block *nk = key->backend_data; + uint32_t key_off; - count = SVAL(&lf_hdr->key_count,0); - DEBUG(2, ("Key Count: %u\n", count)); - if (count <= 0) return WERR_GENERAL_FAILURE; - if (n >= count) return WERR_NO_MORE_ITEMS; + if (idx >= nk->num_subkeys) + return WERR_NO_MORE_ITEMS; - nk_off = IVAL(&lf_hdr->hr[n].nk_off,0); - DEBUG(2, ("NK Offset: %0X\n", nk_off)); - nk_hdr = (NK_HDR *)LOCN(regf->base, nk_off); - return nk_to_key(mem_ctx, parent->hive, nk_hdr, BLK_SIZE(nk_hdr), parent, key); -} - -static WERROR nk_to_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, NK_HDR *nk_hdr, int size, struct registry_key *parent, struct registry_key **key) -{ - REGF *regf = h->backend_data; - struct registry_key *tmp = NULL, *own; - int namlen, clsname_len, sk_off, own_off; - uint_t nk_id; - SK_HDR *sk_hdr; - int type; - char key_name[1024]; - - if (!nk_hdr) return WERR_INVALID_PARAM; - - if ((nk_id = SVAL(&nk_hdr->NK_ID,0)) != str_to_dword("nk")) { - DEBUG(0, ("Unrecognized NK Header format: %08X, Block: %0X. %s\n", - nk_id, (int)nk_hdr, parent->hive->location)); - return WERR_INVALID_PARAM; - } - - SMB_ASSERT(size < 0); - - namlen = SVAL(&nk_hdr->nam_len,0); - clsname_len = SVAL(&nk_hdr->clsnam_len,0); - - /* - * The value of -size should be ge - * (sizeof(NK_HDR) - 1 + namlen) - * The -1 accounts for the fact that we included the first byte of - * the name in the structure. clsname_len is the length of the thing - * pointed to by clsnam_off - */ - - if (-size < (sizeof(NK_HDR) - 1 + namlen)) { - DEBUG(0, ("Incorrect NK_HDR size: %d, %0X\n", -size, (int)nk_hdr)); - DEBUG(0, ("Sizeof NK_HDR: %d, name_len %d, clsname_len %d\n", - (int)sizeof(NK_HDR), namlen, clsname_len)); + data = regf_get_data(key->hive->backend_data, nk->subkeys_offset); + if (!data.data) { + DEBUG(0, ("Unable to find subkey list\n")); return WERR_GENERAL_FAILURE; } - DEBUG(2, ("NK HDR: Name len: %d, class name len: %d\n", namlen, clsname_len)); + if (!strncmp((char *)data.data, "li", 2)) { + DEBUG(4, ("Subkeys in LI list\n")); + SMB_ASSERT(0); + } else if (!strncmp((char *)data.data, "lf", 2)) { + struct lf_block lf; + struct tdr_pull *pull = talloc_zero(ctx, struct tdr_pull); - /* Fish out the key name and process the LF list */ + DEBUG(10, ("Subkeys in LF list\n")); + pull->data = data; - SMB_ASSERT(namlen < sizeof(key_name)); + if (NT_STATUS_IS_ERR(tdr_pull_lf_block(pull, &lf))) { + DEBUG(0, ("Error parsing LF list\n")); + return WERR_GENERAL_FAILURE; + } - strncpy(key_name, nk_hdr->key_nam, namlen); - key_name[namlen] = '\0'; + if (lf.key_count != nk->num_subkeys) { + DEBUG(0, ("Subkey counts don't match\n")); + return WERR_GENERAL_FAILURE; + } - type = (SVAL(&nk_hdr->type,0)==0x2C?REG_ROOT_KEY:REG_SUB_KEY); - if(type == REG_ROOT_KEY && parent) { - DEBUG(0,("Root key encountered below root level!\n")); + key_off = lf.hr[idx].nk_off; + + talloc_free(pull); + } else if (!strncmp((char *)data.data, "ri", 2)) { + DEBUG(4, ("Subkeys in RI list\n")); + SMB_ASSERT(0); + } else if (!strncmp((char *)data.data, "lh", 2)) { + DEBUG(4, ("Subkeys in LH list\n")); + SMB_ASSERT(0); + } else { + DEBUG(0, ("Unknown type for subkey list (0x%04x): %c%c\n", nk->subkeys_offset, data.data[0], data.data[1])); return WERR_GENERAL_FAILURE; } - tmp = talloc(mem_ctx, struct registry_key); - tmp->name = talloc_strdup(mem_ctx, key_name); - tmp->backend_data = nk_hdr; - - DEBUG(2, ("Key name: %s\n", key_name)); - - /* - * Fish out the class name, it is in UNICODE, while the key name is - * ASCII :-) - */ - - if (clsname_len) { /* Just print in Ascii for now */ - void *clsnamep; - int clsnam_off; - - clsnam_off = IVAL(&nk_hdr->clsnam_off,0); - clsnamep = LOCN(regf->base, clsnam_off); - DEBUG(2, ("Class Name Offset: %0X\n", clsnam_off)); - - pull_ucs2_talloc(mem_ctx, &tmp->class_name, clsnamep); - - DEBUGADD(2,(" Class Name: %s\n", tmp->class_name)); - - } - - /* - * Process the owner offset ... - */ - - own_off = IVAL(&nk_hdr->own_off,0); - own = (struct registry_key *)LOCN(regf->base, own_off); - DEBUG(2, ("Owner Offset: %0X\n", own_off)); - - DEBUGADD(2, (" Owner locn: %0X, Our locn: %0X\n", - (uint_t)own, (uint_t)nk_hdr)); + *ret = regf_get_key (ctx, key->hive->backend_data, key_off); - /* - * We should verify that the owner field is correct ... - * for now, we don't worry ... - */ - - /* - * Also handle the SK header ... - */ - - sk_off = IVAL(&nk_hdr->sk_off,0); - sk_hdr = (SK_HDR *)LOCN(regf->base, sk_off); - DEBUG(2, ("SK Offset: %0X\n", sk_off)); - - if (sk_off != -1) { - -#if 0 - tmp->security = process_sk(regf, sk_hdr, sk_off, BLK_SIZE(sk_hdr)); -#endif - - } - - *key = tmp; return WERR_OK; } -#if 0 /* unused */ - -/* - * Allocate a new hbin block, set up the header for the block etc - */ -static HBIN_BLK *nt_create_hbin_blk(struct registry_hive *h, int size) -{ - REGF *regf = h->backend_data; - HBIN_BLK *tmp; - HBIN_HDR *hdr; - - if (!regf || !size) return NULL; - - /* Round size up to multiple of REGF_HDR_BLKSIZ */ - - size = (size + (REGF_HDR_BLKSIZ - 1)) & ~(REGF_HDR_BLKSIZ - 1); - - tmp = malloc_p(HBIN_BLK); - memset(tmp, 0, sizeof(HBIN_BLK)); - - tmp->data = malloc(size); - - memset(tmp->data, 0, size); /* Make it pristine */ - - tmp->size = size; - /*FIXMEtmp->file_offset = regf->blk_tail->file_offset + regf->blk_tail->size;*/ - - tmp->free_space = size - (sizeof(HBIN_HDR) - sizeof(HBIN_SUB_HDR)); - tmp->fsp_off = size - tmp->free_space; - - /* - * Now, build the header in the data block - */ - hdr = (HBIN_HDR *)tmp->data; - hdr->HBIN_ID = str_to_dword("hbin"); - hdr->off_from_first = tmp->file_offset - REGF_HDR_BLKSIZ; - hdr->off_to_next = tmp->size; - hdr->blk_size = tmp->size; - - /* - * Now link it in - */ - - regf->blk_tail->next = tmp; - regf->blk_tail = tmp; - if (!regf->free_space) regf->free_space = tmp; - - return tmp; -} - -/* - * Allocate a unit of space ... and return a pointer as function param - * and the block's offset as a side effect - */ -static void *nt_alloc_regf_space(struct registry_hive *h, int size, uint_t *off) -{ - REGF *regf = h->backend_data; - int tmp = 0; - void *ret = NULL; - HBIN_BLK *blk; - - if (!regf || !size || !off) return NULL; - - SMB_ASSERT(regf->blk_head != NULL); - - /* - * round up size to include header and then to 8-byte boundary - */ - size = (size + 4 + 7) & ~7; - - /* - * Check if there is space, if none, grab a block - */ - if (!regf->free_space) { - if (!nt_create_hbin_blk(h, REGF_HDR_BLKSIZ)) - return NULL; - } - - /* - * Now, chain down the list of blocks looking for free space - */ - - for (blk = regf->free_space; blk != NULL; blk = blk->next) { - if (blk->free_space <= size) { - tmp = blk->file_offset + blk->fsp_off - REGF_HDR_BLKSIZ; - ret = blk->data + blk->fsp_off; - blk->free_space -= size; - blk->fsp_off += size; - - /* Insert the header */ - ((HBIN_SUB_HDR *)ret)->dblocksize = -size; - - /* - * Fix up the free space ptr - * If it is NULL, we fix it up next time - */ - - if (!blk->free_space) - regf->free_space = blk->next; - - *off = tmp; - return (((char *)ret)+4);/* The pointer needs to be to the data struct */ - } - } - - /* - * If we got here, we need to add another block, which might be - * larger than one block -- deal with that later - */ - if (nt_create_hbin_blk(h, REGF_HDR_BLKSIZ)) { - blk = regf->free_space; - tmp = blk->file_offset + blk->fsp_off - REGF_HDR_BLKSIZ; - ret = blk->data + blk->fsp_off; - blk->free_space -= size; - blk->fsp_off += size; - - /* Insert the header */ - ((HBIN_SUB_HDR *)ret)->dblocksize = -size; - - /* - * Fix up the free space ptr - * If it is NULL, we fix it up next time - */ - - if (!blk->free_space) - regf->free_space = blk->next; - - *off = tmp; - return (((char *)ret) + 4);/* The pointer needs to be to the data struct */ - } - - return NULL; -} - -/* - * Store a SID at the location provided - */ -static int nt_store_SID(struct registry_hive *regf, DOM_SID *sid, uint8_t *locn) +static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) { + struct regf_data *regf; + struct regf_hdr *regf_hdr; + struct tdr_pull *pull; int i; - uint8_t *p = locn; - - if (!regf || !sid || !locn) return 0; - - *p = sid->sid_rev_num; p++; - *p = sid->num_auths; p++; - - for (i=0; i < 6; i++) { - *p = sid->id_auth[i]; p++; - } - - for (i=0; i < sid->num_auths; i++) { - SIVAL(p, 0, sid->sub_auths[i]); p+=4; - } - - return p - locn; - -} - -static int nt_store_ace(struct registry_hive *regf, SEC_ACE *ace, uint8_t *locn) -{ - int size = 0; - SEC_ACE *reg_ace = (SEC_ACE *)locn; - uint8_t *p; - - if (!regf || !ace || !locn) return 0; - - reg_ace->type = ace->type; - reg_ace->flags = ace->flags; - - /* Deal with the length when we have stored the SID */ - - p = (uint8_t *)®_ace->info.mask; - - SIVAL(p, 0, ace->info.mask); p += 4; - - size = nt_store_SID(regf, &ace->trustee, p); - - size += 8; /* Size of the fixed header */ - - p = (uint8_t *)®_ace->size; - - SSVAL(p, 0, size); - - return size; -} - -/* - * Store an ACL at the location provided - */ -static int nt_store_acl(struct registry_hive *regf, SEC_ACL *acl, uint8_t *locn) { - int size = 0, i; - uint8_t *p = locn, *s; - - if (!regf || !acl || !locn) return 0; - - /* - * Now store the header and then the ACEs ... - */ - - SSVAL(p, 0, acl->revision); - - p += 2; s = p; /* Save this for the size field */ - - p += 2; - - SIVAL(p, 0, acl->num_aces); - - p += 4; - - for (i = 0; i < acl->num_aces; i++) { - size = nt_store_ace(regf, &acl->ace[i], p); - p += size; - } - - size = s - locn; - SSVAL(s, 0, size); - return size; -} - -/* - * Flatten and store the Sec Desc - * Windows lays out the DACL first, but since there is no SACL, it might be - * that first, then the owner, then the group SID. So, we do it that way - * too. - */ -static uint_t nt_store_sec_desc(struct registry_hive *regf, SEC_DESC *sd, char *locn) -{ - SEC_DESC *rsd = (SEC_DESC *)locn; - uint_t size = 0, off = 0; - - if (!regf || !sd || !locn) return 0; - - /* - * Now, fill in the first two fields, then lay out the various fields - * as needed - */ - - rsd->revision = SEC_DESC_REVISION; - rsd->type = SEC_DESC_DACL_PRESENT | SEC_DESC_SELF_RELATIVE; - - off = 4 * sizeof(uint32_t) + 4; - - if (sd->sacl){ - size = nt_store_acl(regf, sd->sacl, (char *)(locn + off)); - rsd->off_sacl = off; - } - else - rsd->off_sacl = 0; - - off += size; - - if (sd->dacl) { - rsd->off_dacl = off; - size = nt_store_acl(regf, sd->dacl, (char *)(locn + off)); - } - else { - rsd->off_dacl = 0; - } - off += size; - - /* Now the owner and group SIDs */ - - if (sd->owner_sid) { - rsd->off_owner_sid = off; - size = nt_store_SID(regf, sd->owner_sid, (char *)(locn + off)); - } - else { - rsd->off_owner_sid = 0; - } - - off += size; - - if (sd->grp_sid) { - rsd->off_grp_sid = off; - size = nt_store_SID(regf, sd->grp_sid, (char *)(locn + off)); - } - else { - rsd->off_grp_sid = 0; - } - - off += size; - - return size; -} - -/* - * Store the security information - * - * If it has already been stored, just get its offset from record - * otherwise, store it and record its offset - */ -static uint_t nt_store_security(struct registry_hive *regf, KEY_SEC_DESC *sec) -{ - int size = 0; - uint_t sk_off; - SK_HDR *sk_hdr; - - if (sec->offset) return sec->offset; - - /* - * OK, we don't have this one in the file yet. We must compute the - * size taken by the security descriptor as a self-relative SD, which - * means making one pass over each structure and figuring it out - */ - -/* FIXME size = sec_desc_size(sec->sec_desc); */ - - /* Allocate that much space */ - - sk_hdr = nt_alloc_regf_space(regf, size, &sk_off); - sec->sk_hdr = sk_hdr; - - if (!sk_hdr) return 0; - - /* Now, lay out the sec_desc in the space provided */ - - sk_hdr->SK_ID = str_to_dword("sk"); - - /* - * We can't deal with the next and prev offset in the SK_HDRs until the - * whole tree has been stored, then we can go and deal with them - */ - - sk_hdr->ref_cnt = sec->ref_cnt; - sk_hdr->rec_size = size; /* Is this correct */ - - /* Now, lay out the sec_desc */ - - if (!nt_store_sec_desc(regf, sec->sec_desc, (char *)&sk_hdr->sec_desc)) - return 0; - - return sk_off; - -} - -/* - * Store a KEY in the file ... - * - * We store this depth first, and defer storing the lf struct until - * all the sub-keys have been stored. - * - * We store the NK hdr, any SK header, class name, and VK structure, then - * recurse down the LF structures ... - * - * We return the offset of the NK struct - * FIXME, FIXME, FIXME: Convert to using SIVAL and SSVAL ... - */ -static int nt_store_reg_key(struct registry_hive *regf, struct registry_key *key) -{ - NK_HDR *nk_hdr; - uint_t nk_off, sk_off, size; - - if (!regf || !key) return 0; - - size = sizeof(NK_HDR) + strlen(key->name) - 1; - nk_hdr = nt_alloc_regf_space(regf, size, &nk_off); - if (!nk_hdr) goto error; - - key->offset = nk_off; /* We will need this later */ - - /* - * Now fill in each field etc ... - */ - - nk_hdr->NK_ID = str_to_dword("nk"); - if (key->type == REG_ROOT_KEY) - nk_hdr->type = 0x2C; - else - nk_hdr->type = 0x20; - - /* FIXME: Fill in the time of last update */ - - if (key->type != REG_ROOT_KEY) - nk_hdr->own_off = key->owner->offset; - - if (key->sub_keys) - nk_hdr->subk_num = key->sub_keys->key_count; - - /* - * Now, process the Sec Desc and then store its offset - */ - - sk_off = nt_store_security(regf, key->security); - nk_hdr->sk_off = sk_off; - - /* - * Then, store the val list and store its offset - */ - if (key->values) { - nk_hdr->val_cnt = key->values->val_count; - nk_hdr->val_off = nt_store_val_list(regf, key->values); - } - else { - nk_hdr->val_off = -1; - nk_hdr->val_cnt = 0; - } - - /* - * Finally, store the subkeys, and their offsets - */ - -error: - return 0; -} - -/* - * Store the registry header ... - * We actually create the registry header block and link it to the chain - * of output blocks. - */ -static REGF_HDR *nt_get_reg_header(struct registry_hive *h) { - REGF *regf = h->backend_data; - HBIN_BLK *tmp = NULL; - - tmp = malloc_p(HBIN_BLK); - - memset(tmp, 0, sizeof(HBIN_BLK)); - tmp->type = REG_OUTBLK_HDR; - tmp->size = REGF_HDR_BLKSIZ; - tmp->data = malloc(REGF_HDR_BLKSIZ); - if (!tmp->data) goto error; - - memset(tmp->data, 0, REGF_HDR_BLKSIZ); /* Make it pristine, unlike Windows */ - regf->blk_head = regf->blk_tail = tmp; - - return (REGF_HDR *)tmp->data; - -error: - if (tmp) free(tmp); - return NULL; -} - -#endif - -static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) -{ - REGF *regf; - REGF_HDR *regf_hdr; - uint_t regf_id, hbin_id; - HBIN_HDR *hbin_hdr; - - regf = (REGF *)talloc(h, REGF); - memset(regf, 0, sizeof(REGF)); - regf->owner_sid_str = NULL; /* FIXME: Fill in */ + regf = (struct regf_data *)talloc_zero(h, struct regf_data); h->backend_data = regf; DEBUG(5, ("Attempting to load registry file\n")); /* Get the header */ - if ((regf_hdr = nt_get_regf_hdr(h)) == NULL) { - DEBUG(0, ("Unable to get header\n")); + regf->data.data = (uint8_t *)file_load(h->location, ®f->data.length, regf); + if (regf->data.data == NULL) { + DEBUG(0,("Could not load file: %s, %s\n", h->location, + strerror(errno))); return WERR_GENERAL_FAILURE; } - /* Now process that header and start to read the rest in */ + pull = talloc_zero(regf, struct tdr_pull); + if (!pull) + return WERR_NOMEM; - if ((regf_id = IVAL(®f_hdr->REGF_ID,0)) != str_to_dword("regf")) { - DEBUG(0, ("Unrecognized NT registry header id: %0X, %s\n", - regf_id, h->location)); - return WERR_GENERAL_FAILURE; - } + pull->data = regf->data; - /* - * Validate the header ... - */ - if (!valid_regf_hdr(regf_hdr)) { - DEBUG(0, ("Registry file header does not validate: %s\n", - h->location)); + regf_hdr = talloc(regf, struct regf_hdr); + if (NT_STATUS_IS_ERR(tdr_pull_regf_hdr(pull, regf_hdr))) { return WERR_GENERAL_FAILURE; } - /* Update the last mod date, and then go get the first NK record and on */ - - TTTONTTIME(regf, IVAL(®f_hdr->tim1,0), IVAL(®f_hdr->tim2,0)); - - /* - * The hbin hdr seems to be just uninteresting garbage. Check that - * it is there, but that is all. - */ + if (strcmp(regf_hdr->REGF_ID, "regf") != 0) { + DEBUG(0, ("Unrecognized NT registry header id: %s, %s\n", + regf_hdr->REGF_ID, h->location)); + } - hbin_hdr = (HBIN_HDR *)(regf->base + REGF_HDR_BLKSIZ); - - if ((hbin_id = IVAL(&hbin_hdr->HBIN_ID,0)) != str_to_dword("hbin")) { - DEBUG(0, ("Unrecognized registry hbin hdr ID: %0X, %s\n", - hbin_id, h->location)); - return WERR_GENERAL_FAILURE; - } + DEBUG(1, ("Registry '%s' read. Version %d.%d.%d.%d\n", + regf_hdr->description, regf_hdr->version.major, + regf_hdr->version.minor, regf_hdr->version.release, + regf_hdr->version.build)); /* - * Get a pointer to the first key from the hreg_hdr + * Validate the header ... */ + if (regf_hdr_checksum(regf->data.data) != regf_hdr->chksum) { + DEBUG(0, ("Registry file checksum error: %s: %d,%d\n", + h->location, regf_hdr->chksum, regf_hdr_checksum(regf->data.data))); + return WERR_GENERAL_FAILURE; + } - DEBUG(2, ("First Key: %0X\n", - IVAL(®f_hdr->first_key, 0))); - - regf->first_key = (NK_HDR *)LOCN(regf->base, IVAL(®f_hdr->first_key,0)); - DEBUGADD(2, ("First Key Offset: %0X\n", - IVAL(®f_hdr->first_key, 0))); - - DEBUGADD(2, ("Data Block Size: %d\n", - IVAL(®f_hdr->dblk_size, 0))); - - DEBUGADD(2, ("Offset to next hbin block: %0X\n", - IVAL(&hbin_hdr->off_to_next, 0))); + pull->offset = 0x1000; - DEBUGADD(2, ("HBIN block size: %0X\n", - IVAL(&hbin_hdr->blk_size, 0))); + i = 0; + /* Read in all hbin blocks */ + regf->hbins = talloc_array(regf, struct hbin_block *, 1); + regf->hbins[0] = NULL; - /* - * Unmap the registry file, as we might want to read in another - * tree etc. - */ + while (pull->offset < pull->data.length) { + struct hbin_block *hbin = talloc(regf->hbins, struct hbin_block); - h->backend_data = regf; + if (NT_STATUS_IS_ERR(tdr_pull_hbin_block(pull, hbin))) { + DEBUG(0, ("[%d] Error parsing HBIN block\n", i)); + return WERR_FOOBAR; + } - return nk_to_key(h, h, ((REGF *)h->backend_data)->first_key, BLK_SIZE(((REGF *)h->backend_data)->first_key), NULL, key); -} + if (strcmp(hbin->HBIN_ID, "hbin") != 0) { + DEBUG(0, ("[%d] Expected 'hbin', got '%s'\n", i, hbin->HBIN_ID)); + return WERR_FOOBAR; + } + regf->hbins[i] = hbin; + i++; + regf->hbins = talloc_realloc(regf, regf->hbins, struct hbin_block *, i+2); + regf->hbins[i] = NULL; + } -static WERROR nt_num_subkeys(struct registry_key *k, uint32_t *num) -{ - REGF *regf = k->hive->backend_data; - LF_HDR *lf_hdr; - int lf_off; - NK_HDR *nk_hdr = k->backend_data; - lf_off = IVAL(&nk_hdr->lf_off,0); - DEBUG(2, ("SubKey list offset: %0X\n", lf_off)); - if(lf_off == -1) { - *num = 0; - return WERR_OK; - } - lf_hdr = (LF_HDR *)LOCN(regf->base, lf_off); + DEBUG(1, ("%d HBIN blocks read\n", i)); - return lf_num_entries(k->hive, lf_hdr, BLK_SIZE(lf_hdr), num); -} + *key = regf_get_key(h, regf, 0x20); -static WERROR nt_num_values(struct registry_key *k, uint32_t *count) -{ - NK_HDR *nk_hdr = k->backend_data; - *count = IVAL(&nk_hdr->val_cnt,0); return WERR_OK; } -static WERROR nt_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *k, int n, struct registry_value **value) -{ - VL_TYPE *vl; - int val_off, vk_off; - int val_count; - VK_HDR *vk_hdr; - REGF *regf = k->hive->backend_data; - NK_HDR *nk_hdr = k->backend_data; - val_count = IVAL(&nk_hdr->val_cnt,0); - val_off = IVAL(&nk_hdr->val_off,0); - vl = (VL_TYPE *)LOCN(regf->base, val_off); - DEBUG(2, ("Val List Offset: %0X\n", val_off)); - if(n < 0) return WERR_INVALID_PARAM; - if(n >= val_count) return WERR_NO_MORE_ITEMS; - - vk_off = IVAL(&vl[n],0); - vk_hdr = (VK_HDR *)LOCN(regf->base, vk_off); - return vk_to_val(mem_ctx, k, vk_hdr, BLK_SIZE(vk_hdr), value); -} - -static WERROR nt_key_by_index(TALLOC_CTX *mem_ctx, struct registry_key *k, int n, struct registry_key **subkey) -{ - REGF *regf = k->hive->backend_data; - int lf_off; - NK_HDR *nk_hdr = k->backend_data; - LF_HDR *lf_hdr; - lf_off = IVAL(&nk_hdr->lf_off,0); - DEBUG(2, ("SubKey list offset: %0X\n", lf_off)); - - /* - * No more subkeys if lf_off == -1 - */ - - if (lf_off != -1) { - lf_hdr = (LF_HDR *)LOCN(regf->base, lf_off); - return lf_get_entry(mem_ctx, k, lf_hdr, BLK_SIZE(lf_hdr), n, subkey); - } - - return WERR_NO_MORE_ITEMS; -} - static struct hive_operations reg_backend_nt4 = { .name = "nt4", .open_hive = nt_open_hive, - .num_subkeys = nt_num_subkeys, - .num_values = nt_num_values, - .get_subkey_by_index = nt_key_by_index, - .get_value_by_index = nt_value_by_index, - - /* TODO: - .add_key - .add_value - .del_key - .del_value - .update_value - */ + .num_subkeys = regf_num_subkeys, + .num_values = regf_num_values, + .get_subkey_by_index = regf_get_subkey, + .get_value_by_index = regf_get_value, }; NTSTATUS registry_nt4_init(void) diff --git a/source4/lib/registry/regf.idl b/source4/lib/registry/regf.idl index 03f63debc8..760183c01d 100644 --- a/source4/lib/registry/regf.idl +++ b/source4/lib/registry/regf.idl @@ -13,13 +13,15 @@ interface regf { + const int REGF_OFFSET_NONE = 0xffffffff; + /* * Registry version number * 1.3.0.1 for WinNT 4 * 1.5.0.1 for WinXP */ - typedef struct { + typedef [noprint] struct { [value(1)] uint32 major; [value(3)] uint32 minor; [value(0)] uint32 release; @@ -33,7 +35,7 @@ interface regf the first 0x200 bytes only! */ - typedef [public] struct { + typedef [public,noprint] struct { [charset(DOS)] uint8 REGF_ID[4]; /* 'regf' */ uint32 update_counter1; uint32 update_counter2; @@ -53,23 +55,21 @@ interface regf This block is always a multiple of 4kb in size. */ - typedef [public] struct { + typedef [public,noprint] struct { [charset(DOS)] uint8 HBIN_ID[4]; /* hbin */ - uint32 off_from_first; /* Offset from 1st hbin-Block */ - uint32 off_to_next; /* Offset to the next hbin-Block */ + uint32 offset_from_first; /* Offset from 1st hbin-Block */ + uint32 offset_to_next; /* Offset to the next hbin-Block */ uint32 unknown[2]; NTTIME last_change; - uint32 block_size; /* Block size */ - uint8 data[block_size]; /* Filled with hbin_data blocks */ + uint32 block_size; /* Block size (including the header!) */ + uint8 data[offset_to_next-0x20]; + /* data is filled with: + uint32 length + uint8_t data[length] + */ } hbin_block; - typedef struct { - uint32 length; - [charset(DOS)] uint8 header[2]; /* li, lh, ri, nk, vk, sk, lf or \0\0 */ - uint8 data[length-2]; - } hbin_data; - - typedef enum { + typedef [base_type(uint16),noprint] enum { REG_ROOT_KEY = 0x20, REG_SUB_KEY = 0x2C, REG_SYM_LINK = 0x10 @@ -79,7 +79,8 @@ interface regf The nk-record can be treated as a combination of tree-record and key-record of the win 95 registry. */ - typedef struct { + typedef [public,noprint] struct { + [charset(DOS)] uint8 header[2]; reg_key_type type; NTTIME last_change; uint32 uk1; @@ -87,19 +88,20 @@ interface regf uint32 num_subkeys; uint32 uk2; uint32 subkeys_offset; - uint32 uk3; + uint32 unknown_offset; uint32 num_values; - uint32 values_offset; + uint32 values_offset; /* Points to a list of offsets of vk-records */ uint32 sk_offset; uint32 clsname_offset; - uint32 unk4[5]; + uint32 unk3[5]; uint16 name_length; uint16 clsname_length; [charset(DOS)] uint8 key_name[name_length]; } nk_block; /* sk (? Security Key ?) is the ACL of the registry. */ - typedef struct { + typedef [noprint,nopush,nopull] struct { + [charset(DOS)] uint8 header[2]; uint16 uk1; uint32 prev_offset; uint32 next_offset; @@ -108,39 +110,43 @@ interface regf uint8 sec_desc[rec_size]; } sk_block; - typedef struct { + typedef [noprint,nopush,nopull] struct { uint32 offset_nk; uint32 base37; /* base37 of key name */ } lh_hash; /* Subkey listing with hash of first 4 characters */ - typedef struct { + typedef [noprint,nopush,nopull] struct { + [charset(DOS)] uint8 header[2]; uint16 key_count; lh_hash hashes[key_count]; } lh_block; - typedef struct { + typedef [noprint,nopush,nopull] struct { + [charset(DOS)] uint8 header[2]; uint16 key_count; uint32 offset_nk[key_count]; } li_block; - typedef struct { + typedef [noprint,nopush,nopull] struct { + [charset(DOS)] uint8 header[2]; uint16 key_count; uint32 offset[key_count]; /* li/lh offset */ } ri_block; /* The vk-record consists information to a single value (value key). */ - typedef struct { + typedef [public,noprint] struct { + [charset(DOS)] uint8 header[2]; uint16 name_length; uint32 data_length; /* If top-bit set, offset contains the data */ uint32 data_offset; uint32 data_type; uint16 flag; /* =1, has name, else no name (=Default). */ uint16 unk1; - [charset(DOS)] uint8 data_name[name_length]; + [charset(DOS)] uint8 data_name[name_length]; } vk_block; - typedef struct { + typedef [noprint] struct { uint32 nk_off; uint8 hash[4]; } hash_record; @@ -149,7 +155,8 @@ interface regf The lf-record is the counterpart to the RGKN-record (the hash-function) */ - typedef struct { + typedef [public,noprint] struct { + [charset(DOS)] uint8 header[2]; uint16 key_count; hash_record hr[key_count]; /* Array of hash records, depending on key_count */ } lf_block; -- cgit From eac7fe4ebc6eb819fe3721051751e60b12e95684 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 3 Sep 2005 23:23:14 +0000 Subject: r10016: Support reading security descriptors on keys. (This used to be commit b349e902c7b0140cd94e241ba9f81c83fa54f603) --- source4/lib/registry/common/reg_interface.c | 9 ++++++ source4/lib/registry/reg_backend_nt4.c | 47 +++++++++++++++++++++++++++++ source4/lib/registry/regf.idl | 4 +-- source4/lib/registry/tools/regtree.c | 9 +++++- 4 files changed, 66 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 7f745143e6..5297b1b3cf 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -427,6 +427,15 @@ WERROR reg_val_set(struct registry_key *key, const char *value, uint32_t type, D } +WERROR reg_get_sec_desc(TALLOC_CTX *ctx, struct registry_key *key, struct security_descriptor **secdesc) +{ + /* A 'real' set function has preference */ + if (key->hive->functions->key_get_sec_desc) + return key->hive->functions->key_get_sec_desc(ctx, key, secdesc); + + DEBUG(1, ("Backend '%s' doesn't support method get_sec_desc\n", key->hive->functions->name)); + return WERR_NOT_SUPPORTED; +} WERROR reg_del_value(struct registry_key *key, const char *valname) { diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index e0f5ccd08c..b1c0d201f0 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -21,6 +21,7 @@ #include "registry.h" #include "system/filesys.h" #include "lib/registry/tdr_regf.h" +#include "librpc/gen_ndr/ndr_security.h" /* * Read HBIN blocks into memory @@ -251,6 +252,51 @@ static WERROR regf_get_subkey (TALLOC_CTX *ctx, struct registry_key *key, int id return WERR_OK; } +static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, struct registry_key *key, struct security_descriptor **sd) +{ + struct nk_block *nk = key->backend_data; + struct tdr_pull *tdr; + struct sk_block sk; + DATA_BLOB data; + + data = regf_get_data(key->hive->backend_data, nk->sk_offset); + if (!data.data) { + DEBUG(0, ("Unable to find security descriptor\n")); + return WERR_GENERAL_FAILURE; + } + + tdr = talloc_zero(ctx, struct tdr_pull); + if (!tdr) + return WERR_NOMEM; + + tdr->data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_sk_block(tdr, &sk))) { + DEBUG(0, ("Error parsing SK block\n")); + return WERR_GENERAL_FAILURE; + } + + if (strcmp(sk.header, "sk") != 0) { + DEBUG(0, ("Expected 'sk', got '%s'\n", sk.header)); + return WERR_GENERAL_FAILURE; + } + + *sd = talloc(ctx, struct security_descriptor); + if (!*sd) + return WERR_NOMEM; + + data.data = sk.sec_desc; + data.length = sk.rec_size; + if (NT_STATUS_IS_ERR(ndr_pull_struct_blob(&data, ctx, *sd, (ndr_pull_flags_fn_t)ndr_pull_security_descriptor))) { + DEBUG(0, ("Error parsing security descriptor\n")); + return WERR_GENERAL_FAILURE; + } + + talloc_free(tdr); + + return WERR_OK; +} + static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) { struct regf_data *regf; @@ -342,6 +388,7 @@ static struct hive_operations reg_backend_nt4 = { .num_values = regf_num_values, .get_subkey_by_index = regf_get_subkey, .get_value_by_index = regf_get_value, + .key_get_sec_desc = regf_get_sec_desc, }; NTSTATUS registry_nt4_init(void) diff --git a/source4/lib/registry/regf.idl b/source4/lib/registry/regf.idl index 760183c01d..3b0a66fc54 100644 --- a/source4/lib/registry/regf.idl +++ b/source4/lib/registry/regf.idl @@ -100,9 +100,9 @@ interface regf } nk_block; /* sk (? Security Key ?) is the ACL of the registry. */ - typedef [noprint,nopush,nopull] struct { + typedef [noprint,public] struct { [charset(DOS)] uint8 header[2]; - uint16 uk1; + uint16 tag; uint32 prev_offset; uint32 next_offset; uint32 ref_cnt; diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 2385123b7f..38dffed85d 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -28,6 +28,7 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) { struct registry_key *subkey; struct registry_value *value; + struct security_descriptor *sec_desc; WERROR error; int i; TALLOC_CTX *mem_ctx; @@ -68,9 +69,15 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) DEBUG(0, ("Error occured while fetching values for '%s': %s\n", p->path, win_errstr(error))); } } + + mem_ctx = talloc_init("sec_desc"); + if (NT_STATUS_IS_ERR(reg_get_sec_desc(mem_ctx, p, &sec_desc))) { + DEBUG(0, ("Error getting security descriptor\n")); + } + talloc_free(mem_ctx); } - int main(int argc, char **argv) +int main(int argc, char **argv) { int opt, i; const char *backend = NULL; -- cgit From 23e6e07b280983b2ccdf60deac3c32584af16140 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 4 Sep 2005 02:09:32 +0000 Subject: r10020: Support for malloc / realloc / free in HBIN blocks Initial support for adding keys (still broken though) (This used to be commit ff8d3a27c1b9bb37de39e7d7b974702b2b8c4437) --- source4/lib/registry/common/reg_interface.c | 5 + source4/lib/registry/reg_backend_nt4.c | 340 ++++++++++++++++++++++++++-- source4/lib/registry/regf.idl | 13 +- 3 files changed, 333 insertions(+), 25 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 5297b1b3cf..ddd4ecbe93 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -409,6 +409,11 @@ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, struct registry_key *parent, const error = parent->hive->functions->add_key(mem_ctx, parent, name, access_mask, desc, newkey); if(!W_ERROR_IS_OK(error)) return error; + + if (!*newkey) { + DEBUG(0, ("Backend returned WERR_OK, but didn't specify key!\n")); + return WERR_GENERAL_FAILURE; + } (*newkey)->hive = parent->hive; (*newkey)->backend_data = talloc_asprintf(mem_ctx, "%s\\%s", parent->path, name); diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index b1c0d201f0..46057bcd63 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -20,6 +20,7 @@ #include "includes.h" #include "registry.h" #include "system/filesys.h" +#include "system/time.h" #include "lib/registry/tdr_regf.h" #include "librpc/gen_ndr/ndr_security.h" @@ -32,6 +33,23 @@ struct regf_data { struct hbin_block **hbins; }; +static struct hbin_block *hbin_by_offset (const struct regf_data *data, uint32_t offset, uint32_t *rel_offset) +{ + int i; + + for (i = 0; data->hbins[i]; i++) { + if (offset >= data->hbins[i]->offset_from_first && + offset < data->hbins[i]->offset_from_first+ + data->hbins[i]->offset_to_next) { + if (rel_offset) + *rel_offset = offset - data->hbins[i]->offset_from_first - 0x20; + return data->hbins[i]; + } + } + + return NULL; +} + /* * Validate a regf header * For now, do nothing, but we should check the checksum @@ -49,37 +67,216 @@ static uint32_t regf_hdr_checksum(const uint8_t *buffer) return checksum; } -static DATA_BLOB regf_get_data(const struct regf_data *data, uint32_t offset) +static DATA_BLOB hbin_get_data(const struct regf_data *data, uint32_t offset) { - int i; DATA_BLOB ret; + struct hbin_block *hbin; + uint32_t rel_offset; ret.data = NULL; ret.length = 0; - - for (i = 0; data->hbins[i]; i++) { - if (offset >= data->hbins[i]->offset_from_first && - offset < data->hbins[i]->offset_from_first+ - data->hbins[i]->offset_to_next) - break; - } - if (data->hbins[i] == NULL) { + hbin = hbin_by_offset(data, offset, &rel_offset); + + if (hbin == NULL) { DEBUG(1, ("Can't find HBIN containing 0x%4x\n", offset)); return ret; } - ret.length = IVAL(data->hbins[i]->data, - offset - data->hbins[i]->offset_from_first - 0x20); + ret.length = IVAL(hbin->data, rel_offset); if (ret.length & 0x80000000) { /* absolute value */ ret.length = (ret.length ^ 0xffffffff) + 1; } - ret.data = data->hbins[i]->data + - (offset - data->hbins[i]->offset_from_first - 0x20) + 4; + ret.length -= 4; /* 4 bytes for the length... */ + ret.data = hbin->data + + (offset - hbin->offset_from_first - 0x20) + 4; + + return ret; +} + +/* Allocate some new data */ +static DATA_BLOB hbin_alloc (struct regf_data *data, uint32_t size, uint32_t *offset) +{ + DATA_BLOB ret; + uint32_t rel_offset = -1; /* Relative offset ! */ + struct hbin_block *hbin = NULL; + int i; + + size += 4; /* Need to include uint32 for the length */ + + /* Allocate as a multiple of 8 */ + size = (size + 7) & ~7; + + ret.data = NULL; + ret.length = 0; + + if (size == 0) + return ret; + + for (i = 0; (hbin = data->hbins[i]); i++) { + int j; + uint32_t my_size; + for (j = 0; j < hbin->offset_to_next-0x20; j+= my_size) { + my_size = IVAL(hbin->data, j); + uint32_t header = IVAL(hbin->data, j + 4); + + if (my_size % 8 != 0) { + DEBUG(0, ("Encountered non-aligned block!\n")); + } + + if (my_size & 0x80000000) { /* Used... */ + my_size = (my_size ^ 0xffffffff) + 1; + } else if (my_size == size) { /* exact match */ + rel_offset = j; + break; + } else if (my_size > size) { /* data will remain */ + rel_offset = j; + SIVAL(hbin->data, rel_offset+size, my_size-size); + break; + } + + if (header == 0xffffffff && + hbin->offset_to_next-rel_offset >= size) { + rel_offset = j; + /* Mark new free block size */ + SIVAL(hbin->data, rel_offset+size,hbin->offset_to_next - rel_offset - size - 0x20); + SIVAL(hbin->data, rel_offset+size+0x4, 0xffffffff); + break; + } + + if (header == 0xffffffff) { + break; + } + } + + if (rel_offset != -1) + break; + } + /* No space available in previous hbins, + * allocate new one */ + if (data->hbins[i] == NULL) { + data->hbins = talloc_realloc(data, data->hbins, struct hbin_block *, i+2); + hbin = talloc(data->hbins, struct hbin_block); + data->hbins[i] = hbin; + data->hbins[i+1] = NULL; + + hbin->HBIN_ID = talloc_strdup(hbin, "hbin"); + hbin->offset_from_first = (i == 0?0:data->hbins[i-1]->offset_from_first+data->hbins[i-1]->offset_to_next); + hbin->offset_to_next = 0x1000; + hbin->unknown[0] = 0; + hbin->unknown[0] = 0; + unix_to_nt_time(&hbin->last_change, time(NULL)); + hbin->block_size = hbin->offset_to_next; + hbin->data = talloc_zero_array(hbin, uint8_t, hbin->block_size - 0x20); + + rel_offset = 0x0; + SIVAL(hbin->data, size, hbin->block_size - size - 0x20); + SIVAL(hbin->data, size + 0x4, 0xffffffff); + } + + /* Set size and mark as used */ + SIVAL(hbin->data, rel_offset, size & 0x80000000); + + ret.data = hbin->data + rel_offset + 0x4; /* Skip past length */ + ret.length = size - 0x4; + if (offset) + *offset = hbin->offset_from_first + rel_offset + 0x20; + return ret; } +/* Store a data blob. Return the offset at which it was stored */ +static uint32_t hbin_store (struct regf_data *data, DATA_BLOB blob) +{ + uint32_t ret; + DATA_BLOB dest = hbin_alloc(data, blob.length, &ret); + + memcpy(dest.data, blob.data, blob.length); + + return ret; +} + + +/* Free existing data */ +static void hbin_free (struct regf_data *data, uint32_t offset) +{ + uint32_t size; + uint32_t rel_offset; + struct hbin_block *hbin = hbin_by_offset(data, offset, &rel_offset); + + if (hbin == NULL) + return; + + /* Get original size */ + size = IVAL(hbin->data, rel_offset); + + if (!(size & 0x80000000)) { + DEBUG(1, ("Trying to free already freed block\n")); + return; + } + + /* Mark block as free */ + SIVAL(hbin->data, rel_offset, (size ^ 0xffffffff) + 1); +} + +/* Store a data blob data was already stored, but hsa changed in size + * Will try to save it at the current location if possible, otherwise + * does a free + store */ +static uint32_t hbin_store_resize (struct regf_data *data, uint32_t orig_offset, DATA_BLOB blob) +{ + uint32_t rel_offset; + struct hbin_block *hbin = hbin_by_offset(data, orig_offset, &rel_offset); + uint32_t orig_size; + uint32_t needed_size; + uint32_t possible_size; + int i; + + if (!hbin) + return hbin_store(data, blob); + + /* Get original size */ + orig_size = IVAL(hbin->data, rel_offset); + + /* Fits into current allocated block */ + if (orig_size - 4 >= blob.length) { + memcpy(hbin->data + rel_offset + 0x4, blob.data, blob.length); + return orig_offset; + } + + needed_size = blob.length + 4; /* Add uint32 containing length */ + needed_size = (needed_size + 7) & ~7; /* Align */ + + possible_size = orig_size; + + /* Check if it can be combined with the next few free records */ + for (i = rel_offset; + i < hbin->offset_to_next - 0x20; + i = rel_offset + possible_size) { + uint32_t header; + if (IVAL(hbin->data, i) & 0x80000000) /* Used */ + break; + + header = IVAL(hbin->data, i + 4); + if (header == 0xffffffff) { + possible_size = hbin->offset_to_next - 0x20 - rel_offset; + } else { + possible_size += IVAL(hbin->data, i); + } + + if (possible_size >= blob.length) { + SIVAL(hbin->data, rel_offset, possible_size); + memcpy(hbin->data + rel_offset + 0x4, blob.data, blob.length); + return orig_offset; + } + + if (header == 0xffffffff) + break; + } + + hbin_free(data, orig_offset); + return hbin_store(data, blob); +} static WERROR regf_num_subkeys (struct registry_key *key, uint32_t *count) { @@ -101,7 +298,7 @@ static WERROR regf_num_values (struct registry_key *key, uint32_t *count) static struct registry_key *regf_get_key (TALLOC_CTX *ctx, struct regf_data *regf, uint32_t offset) { - DATA_BLOB data = regf_get_data(regf, offset); + DATA_BLOB data = hbin_get_data(regf, offset); struct tdr_pull *pull; struct registry_key *ret; struct nk_block *nk; @@ -147,7 +344,7 @@ static WERROR regf_get_value (TALLOC_CTX *ctx, struct registry_key *key, int idx if (idx >= nk->num_values) return WERR_NO_MORE_ITEMS; - data = regf_get_data(key->hive->backend_data, nk->values_offset); + data = hbin_get_data(key->hive->backend_data, nk->values_offset); if (!data.data) { DEBUG(0, ("Unable to find value list\n")); return WERR_GENERAL_FAILURE; @@ -159,7 +356,7 @@ static WERROR regf_get_value (TALLOC_CTX *ctx, struct registry_key *key, int idx vk_offset = IVAL(data.data, idx * 4); - data = regf_get_data(key->hive->backend_data, vk_offset); + data = hbin_get_data(key->hive->backend_data, vk_offset); if (!data.data) { DEBUG(0, ("Unable to find value\n")); return WERR_GENERAL_FAILURE; @@ -188,7 +385,7 @@ static WERROR regf_get_value (TALLOC_CTX *ctx, struct registry_key *key, int idx (*ret)->data.data = (uint8_t *)&vk->data_offset; (*ret)->data.length = vk->data_length; } else { - (*ret)->data = regf_get_data(key->hive->backend_data, vk->data_offset); + (*ret)->data = hbin_get_data(key->hive->backend_data, vk->data_offset); } if ((*ret)->data.length < vk->data_length) { @@ -207,7 +404,7 @@ static WERROR regf_get_subkey (TALLOC_CTX *ctx, struct registry_key *key, int id if (idx >= nk->num_subkeys) return WERR_NO_MORE_ITEMS; - data = regf_get_data(key->hive->backend_data, nk->subkeys_offset); + data = hbin_get_data(key->hive->backend_data, nk->subkeys_offset); if (!data.data) { DEBUG(0, ("Unable to find subkey list\n")); return WERR_GENERAL_FAILURE; @@ -259,7 +456,7 @@ static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, struct registry_key *key, struc struct sk_block sk; DATA_BLOB data; - data = regf_get_data(key->hive->backend_data, nk->sk_offset); + data = hbin_get_data(key->hive->backend_data, nk->sk_offset); if (!data.data) { DEBUG(0, ("Unable to find security descriptor\n")); return WERR_GENERAL_FAILURE; @@ -297,6 +494,108 @@ static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, struct registry_key *key, struc return WERR_OK; } +static uint32_t lf_add_entry (struct regf_data *regf, uint32_t list_offset, const char *name, uint32_t key_offset) +{ + uint32_t ret; + struct lf_block lf; + struct tdr_pull *pull = NULL; + struct tdr_push *push; + + /* Add to subkeys list */ + if (list_offset == -1) { /* Need to create subkeys list */ + lf.header = "lf"; + lf.key_count = 0; + lf.hr = NULL; + } else { + DATA_BLOB data; + pull = talloc(regf, struct tdr_pull); + + data = hbin_get_data(regf, list_offset); + if (!data.data) { + DEBUG(0, ("Can't get subkeys list\n")); + talloc_free(pull); + return -1; + } + + if (NT_STATUS_IS_ERR(tdr_pull_lf_block(pull, &lf))) { + DEBUG(0, ("Unable to parse lf list\n")); + talloc_free(pull); + return -1; + } + } + + lf.hr = talloc_realloc(pull, lf.hr, struct hash_record, lf.key_count+1); + lf.hr[lf.key_count].nk_off = key_offset; + lf.hr[lf.key_count].hash = name; + + push = talloc_zero(regf, struct tdr_push); + + if (NT_STATUS_IS_ERR(tdr_push_lf_block(push, &lf))) { + DEBUG(0, ("Error storing lf block\n")); + return -1; + } + + ret = hbin_store_resize (regf, list_offset, push->data); + + talloc_free(push); + talloc_free(pull); + + return ret; +} + +static WERROR regf_add_key (TALLOC_CTX *ctx, struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *sec_desc, struct registry_key **ret) +{ + struct nk_block *parent_nk = parent->backend_data, nk; + DATA_BLOB data; + struct tdr_push *push; + uint32_t offset; + + nk.header = "nk"; + nk.type = REG_SUB_KEY; + unix_to_nt_time(&nk.last_change, time(NULL)); + nk.uk1 = 0; + nk.parent_offset = 0; /* FIXME */ + nk.num_subkeys = 0; + nk.uk2 = 0; + nk.subkeys_offset = -1; + nk.unknown_offset = -1; + nk.num_values = 0; + nk.sk_offset = 0; + memset(nk.unk3, 0, 5); + nk.clsname_offset = -1; + nk.clsname_length = 0; + nk.key_name = name; + + push = talloc_zero(ctx, struct tdr_push); + if (NT_STATUS_IS_ERR(tdr_push_nk_block(push, &nk))) { + DEBUG(0, ("Error storing 'nk' block\n")); + return WERR_GENERAL_FAILURE; + } + + offset = hbin_store(parent->hive->backend_data, push->data); + + parent_nk->subkeys_offset = lf_add_entry(parent->hive->backend_data, parent_nk->subkeys_offset, name, nk.parent_offset); + + parent_nk->num_subkeys++; + + ZERO_STRUCTP(push); + + if (NT_STATUS_IS_ERR(tdr_push_nk_block(push, parent_nk))) { + DEBUG(0, ("Error storing parent 'nk' block\n")); + return WERR_GENERAL_FAILURE; + } + + data = hbin_get_data(parent->hive->backend_data, nk.parent_offset); + memcpy(data.data, push->data.data, push->data.length); + + talloc_free(push); + + /* FIXME: Set sec desc ! */ + + *ret = regf_get_key(ctx, parent->hive->backend_data, offset); + return WERR_OK; +} + static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) { struct regf_data *regf; @@ -389,6 +688,7 @@ static struct hive_operations reg_backend_nt4 = { .get_subkey_by_index = regf_get_subkey, .get_value_by_index = regf_get_value, .key_get_sec_desc = regf_get_sec_desc, + .add_key = regf_add_key, }; NTSTATUS registry_nt4_init(void) diff --git a/source4/lib/registry/regf.idl b/source4/lib/registry/regf.idl index 3b0a66fc54..85a879cc36 100644 --- a/source4/lib/registry/regf.idl +++ b/source4/lib/registry/regf.idl @@ -64,8 +64,11 @@ interface regf uint32 block_size; /* Block size (including the header!) */ uint8 data[offset_to_next-0x20]; /* data is filled with: - uint32 length - uint8_t data[length] + uint32 length; + Negative if in used, positive otherwise + Always a multiple of 8 + uint8_t data[length]; + Free space marker if 0xffffffff */ } hbin_block; @@ -94,7 +97,7 @@ interface regf uint32 sk_offset; uint32 clsname_offset; uint32 unk3[5]; - uint16 name_length; + [value(strlen(key_name))] uint16 name_length; uint16 clsname_length; [charset(DOS)] uint8 key_name[name_length]; } nk_block; @@ -137,7 +140,7 @@ interface regf /* The vk-record consists information to a single value (value key). */ typedef [public,noprint] struct { [charset(DOS)] uint8 header[2]; - uint16 name_length; + [value(strlen(data_name))] uint16 name_length; uint32 data_length; /* If top-bit set, offset contains the data */ uint32 data_offset; uint32 data_type; @@ -148,7 +151,7 @@ interface regf typedef [noprint] struct { uint32 nk_off; - uint8 hash[4]; + [charset(DOS)] uint8 hash[4]; } hash_record; /* -- cgit From 4729c3db26f719cd936825d91b2514df7ac0e61b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 4 Sep 2005 13:13:47 +0000 Subject: r10025: Add some utility functions for storing/loading tdr encoded data (This used to be commit bcd433bfc1450317b75e22942dee1c42bb24ae79) --- source4/lib/registry/reg_backend_nt4.c | 171 +++++++++++++++------------------ 1 file changed, 79 insertions(+), 92 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index 46057bcd63..cf67abb322 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -31,6 +31,7 @@ struct regf_data { DATA_BLOB data; struct hbin_block **hbins; + struct regf_hdr *header; }; static struct hbin_block *hbin_by_offset (const struct regf_data *data, uint32_t offset, uint32_t *rel_offset) @@ -67,7 +68,7 @@ static uint32_t regf_hdr_checksum(const uint8_t *buffer) return checksum; } -static DATA_BLOB hbin_get_data(const struct regf_data *data, uint32_t offset) +static DATA_BLOB hbin_get(const struct regf_data *data, uint32_t offset) { DATA_BLOB ret; struct hbin_block *hbin; @@ -94,6 +95,31 @@ static DATA_BLOB hbin_get_data(const struct regf_data *data, uint32_t offset) return ret; } +static BOOL hbin_get_tdr (struct regf_data *regf, uint32_t offset, tdr_pull_fn_t pull_fn, void *p) +{ + DATA_BLOB data; + struct tdr_pull *pull; + + data = hbin_get(regf, offset); + if (!data.data) { + DEBUG(1, ("Unable to get data at 0x%04x\n", offset)); + return False; + } + + pull = talloc_zero(regf, struct tdr_pull); + pull->data = data; + + if (NT_STATUS_IS_ERR(pull_fn(pull, p))) { + DEBUG(1, ("Error parsing record at 0x%04x using tdr\n", offset)); + talloc_free(pull); + return False; + } + + /* FIXME: Free pull ! */ + + return True; +} + /* Allocate some new data */ static DATA_BLOB hbin_alloc (struct regf_data *data, uint32_t size, uint32_t *offset) { @@ -197,6 +223,23 @@ static uint32_t hbin_store (struct regf_data *data, DATA_BLOB blob) return ret; } +static uint32_t hbin_store_tdr (struct regf_data *data, tdr_push_fn_t push_fn, void *p) +{ + struct tdr_push *push = talloc_zero(data, struct tdr_push); + uint32_t ret; + + if (NT_STATUS_IS_ERR(push_fn(push, p))) { + DEBUG(0, ("Error during push\n")); + return -1; + } + + ret = hbin_store(data, push->data); + + talloc_free(push); + + return ret; +} + /* Free existing data */ static void hbin_free (struct regf_data *data, uint32_t offset) @@ -278,6 +321,23 @@ static uint32_t hbin_store_resize (struct regf_data *data, uint32_t orig_offset, return hbin_store(data, blob); } +static uint32_t hbin_store_tdr_resize (struct regf_data *regf, tdr_push_fn_t push_fn, uint32_t orig_offset, void *p) +{ + struct tdr_push *push = talloc_zero(regf, struct tdr_push); + uint32_t ret; + + if (NT_STATUS_IS_ERR(push_fn(push, p))) { + DEBUG(0, ("Error during push\n")); + return -1; + } + + ret = hbin_store_resize(regf, orig_offset, push->data); + + talloc_free(push); + + return ret; +} + static WERROR regf_num_subkeys (struct registry_key *key, uint32_t *count) { struct nk_block *nk = key->backend_data; @@ -298,24 +358,13 @@ static WERROR regf_num_values (struct registry_key *key, uint32_t *count) static struct registry_key *regf_get_key (TALLOC_CTX *ctx, struct regf_data *regf, uint32_t offset) { - DATA_BLOB data = hbin_get_data(regf, offset); - struct tdr_pull *pull; struct registry_key *ret; struct nk_block *nk; - if (data.data == NULL) { - DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset)); - return NULL; - } - ret = talloc_zero(ctx, struct registry_key); - pull = talloc_zero(ret, struct tdr_pull); - pull->data = data; nk = talloc(ret, struct nk_block); - - if (NT_STATUS_IS_ERR(tdr_pull_nk_block(pull, nk))) { - DEBUG(1, ("Error parsing 'nk' record\n")); - talloc_free(ret); + if (!hbin_get_tdr(regf, offset, (tdr_pull_fn_t)tdr_pull_nk_block, nk)) { + DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset)); return NULL; } @@ -337,14 +386,14 @@ static WERROR regf_get_value (TALLOC_CTX *ctx, struct registry_key *key, int idx { struct nk_block *nk = key->backend_data; struct vk_block *vk; - struct tdr_pull *pull; + struct regf_data *regf = key->hive->backend_data; uint32_t vk_offset; DATA_BLOB data; if (idx >= nk->num_values) return WERR_NO_MORE_ITEMS; - data = hbin_get_data(key->hive->backend_data, nk->values_offset); + data = hbin_get(regf, nk->values_offset); if (!data.data) { DEBUG(0, ("Unable to find value list\n")); return WERR_GENERAL_FAILURE; @@ -356,12 +405,6 @@ static WERROR regf_get_value (TALLOC_CTX *ctx, struct registry_key *key, int idx vk_offset = IVAL(data.data, idx * 4); - data = hbin_get_data(key->hive->backend_data, vk_offset); - if (!data.data) { - DEBUG(0, ("Unable to find value\n")); - return WERR_GENERAL_FAILURE; - } - *ret = talloc_zero(ctx, struct registry_value); if (!(*ret)) return WERR_NOMEM; @@ -370,11 +413,8 @@ static WERROR regf_get_value (TALLOC_CTX *ctx, struct registry_key *key, int idx if (!vk) return WERR_NOMEM; - pull = talloc_zero(*ret, struct tdr_pull); - pull->data = data; - - if (NT_STATUS_IS_ERR(tdr_pull_vk_block(pull, vk))) { - DEBUG(0, ("Error parsing vk block\n")); + if (!hbin_get_tdr(regf, vk_offset, (tdr_pull_fn_t)tdr_pull_vk_block, vk)) { + DEBUG(0, ("Unable to get VK block at %d\n", vk_offset)); return WERR_GENERAL_FAILURE; } @@ -385,7 +425,7 @@ static WERROR regf_get_value (TALLOC_CTX *ctx, struct registry_key *key, int idx (*ret)->data.data = (uint8_t *)&vk->data_offset; (*ret)->data.length = vk->data_length; } else { - (*ret)->data = hbin_get_data(key->hive->backend_data, vk->data_offset); + (*ret)->data = hbin_get(regf, vk->data_offset); } if ((*ret)->data.length < vk->data_length) { @@ -404,7 +444,7 @@ static WERROR regf_get_subkey (TALLOC_CTX *ctx, struct registry_key *key, int id if (idx >= nk->num_subkeys) return WERR_NO_MORE_ITEMS; - data = hbin_get_data(key->hive->backend_data, nk->subkeys_offset); + data = hbin_get(key->hive->backend_data, nk->subkeys_offset); if (!data.data) { DEBUG(0, ("Unable to find subkey list\n")); return WERR_GENERAL_FAILURE; @@ -452,27 +492,15 @@ static WERROR regf_get_subkey (TALLOC_CTX *ctx, struct registry_key *key, int id static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, struct registry_key *key, struct security_descriptor **sd) { struct nk_block *nk = key->backend_data; - struct tdr_pull *tdr; struct sk_block sk; + struct regf_data *regf = key->hive->backend_data; DATA_BLOB data; - data = hbin_get_data(key->hive->backend_data, nk->sk_offset); - if (!data.data) { + if (!hbin_get_tdr(regf, nk->sk_offset, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find security descriptor\n")); return WERR_GENERAL_FAILURE; } - - tdr = talloc_zero(ctx, struct tdr_pull); - if (!tdr) - return WERR_NOMEM; - - tdr->data = data; - - if (NT_STATUS_IS_ERR(tdr_pull_sk_block(tdr, &sk))) { - DEBUG(0, ("Error parsing SK block\n")); - return WERR_GENERAL_FAILURE; - } - + if (strcmp(sk.header, "sk") != 0) { DEBUG(0, ("Expected 'sk', got '%s'\n", sk.header)); return WERR_GENERAL_FAILURE; @@ -489,8 +517,6 @@ static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, struct registry_key *key, struc return WERR_GENERAL_FAILURE; } - talloc_free(tdr); - return WERR_OK; } @@ -498,8 +524,6 @@ static uint32_t lf_add_entry (struct regf_data *regf, uint32_t list_offset, cons { uint32_t ret; struct lf_block lf; - struct tdr_pull *pull = NULL; - struct tdr_push *push; /* Add to subkeys list */ if (list_offset == -1) { /* Need to create subkeys list */ @@ -507,38 +531,17 @@ static uint32_t lf_add_entry (struct regf_data *regf, uint32_t list_offset, cons lf.key_count = 0; lf.hr = NULL; } else { - DATA_BLOB data; - pull = talloc(regf, struct tdr_pull); - - data = hbin_get_data(regf, list_offset); - if (!data.data) { + if (!hbin_get_tdr(regf, list_offset, (tdr_pull_fn_t)tdr_pull_lf_block, &lf)) { DEBUG(0, ("Can't get subkeys list\n")); - talloc_free(pull); - return -1; - } - - if (NT_STATUS_IS_ERR(tdr_pull_lf_block(pull, &lf))) { - DEBUG(0, ("Unable to parse lf list\n")); - talloc_free(pull); return -1; } } - lf.hr = talloc_realloc(pull, lf.hr, struct hash_record, lf.key_count+1); + lf.hr = talloc_realloc(regf, lf.hr, struct hash_record, lf.key_count+1); lf.hr[lf.key_count].nk_off = key_offset; lf.hr[lf.key_count].hash = name; - push = talloc_zero(regf, struct tdr_push); - - if (NT_STATUS_IS_ERR(tdr_push_lf_block(push, &lf))) { - DEBUG(0, ("Error storing lf block\n")); - return -1; - } - - ret = hbin_store_resize (regf, list_offset, push->data); - - talloc_free(push); - talloc_free(pull); + ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t)tdr_push_lf_block, list_offset, &lf); return ret; } @@ -546,8 +549,6 @@ static uint32_t lf_add_entry (struct regf_data *regf, uint32_t list_offset, cons static WERROR regf_add_key (TALLOC_CTX *ctx, struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *sec_desc, struct registry_key **ret) { struct nk_block *parent_nk = parent->backend_data, nk; - DATA_BLOB data; - struct tdr_push *push; uint32_t offset; nk.header = "nk"; @@ -566,29 +567,13 @@ static WERROR regf_add_key (TALLOC_CTX *ctx, struct registry_key *parent, const nk.clsname_length = 0; nk.key_name = name; - push = talloc_zero(ctx, struct tdr_push); - if (NT_STATUS_IS_ERR(tdr_push_nk_block(push, &nk))) { - DEBUG(0, ("Error storing 'nk' block\n")); - return WERR_GENERAL_FAILURE; - } - - offset = hbin_store(parent->hive->backend_data, push->data); + offset = hbin_store_tdr(parent->hive->backend_data, (tdr_push_fn_t) tdr_push_nk_block, &nk); parent_nk->subkeys_offset = lf_add_entry(parent->hive->backend_data, parent_nk->subkeys_offset, name, nk.parent_offset); parent_nk->num_subkeys++; - ZERO_STRUCTP(push); - - if (NT_STATUS_IS_ERR(tdr_push_nk_block(push, parent_nk))) { - DEBUG(0, ("Error storing parent 'nk' block\n")); - return WERR_GENERAL_FAILURE; - } - - data = hbin_get_data(parent->hive->backend_data, nk.parent_offset); - memcpy(data.data, push->data.data, push->data.length); - - talloc_free(push); + hbin_store_tdr_resize(parent->hive->backend_data, (tdr_push_fn_t) tdr_push_nk_block, nk.parent_offset, parent_nk); /* FIXME: Set sec desc ! */ @@ -628,6 +613,8 @@ static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) return WERR_GENERAL_FAILURE; } + regf->header = regf_hdr; + if (strcmp(regf_hdr->REGF_ID, "regf") != 0) { DEBUG(0, ("Unrecognized NT registry header id: %s, %s\n", regf_hdr->REGF_ID, h->location)); -- cgit From ff7342a4ad1cc1ac8571c86466c197b6a8fa6b41 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 4 Sep 2005 14:47:19 +0000 Subject: r10026: Move registry header file to lib/registry Add support for showing security descriptor in regshell Add support for saving files in NT4 registry backend (This used to be commit 47cecd4726e6568f1aafb404646d2664f630a9bb) --- source4/lib/registry/common/reg_interface.c | 2 +- source4/lib/registry/common/reg_util.c | 2 +- source4/lib/registry/reg_backend_nt4.c | 32 ++++++- source4/lib/registry/registry.h | 136 ++++++++++++++++++++++++++++ source4/lib/registry/tools/regdiff.c | 2 +- source4/lib/registry/tools/regpatch.c | 2 +- source4/lib/registry/tools/regshell.c | 16 +++- source4/lib/registry/tools/regtree.c | 2 +- 8 files changed, 186 insertions(+), 8 deletions(-) create mode 100644 source4/lib/registry/registry.h (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index ddd4ecbe93..74f158b027 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -20,7 +20,7 @@ #include "includes.h" #include "dlinklist.h" -#include "registry.h" +#include "lib/registry/registry.h" /* List of available backends */ static struct reg_init_function_entry *backends = NULL; diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index a0d4db6f57..ae30839cca 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -19,7 +19,7 @@ */ #include "includes.h" -#include "registry.h" +#include "lib/registry/registry.h" #include "librpc/gen_ndr/winreg.h" static const struct { diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index cf67abb322..4fc458dee4 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -376,7 +376,11 @@ static struct registry_key *regf_get_key (TALLOC_CTX *ctx, struct regf_data *reg ret->name = talloc_steal(ret, nk->key_name); ret->last_mod = nk->last_change; - ret->class_name = NULL; /* FIXME: get somehow using clsname_offset */ + + if (nk->clsname_offset != -1) { + DATA_BLOB data = hbin_get(regf, nk->clsname_offset); + ret->class_name = talloc_strndup(ret, (char*)data.data, nk->clsname_length); + } ret->backend_data = nk; return ret; @@ -581,6 +585,30 @@ static WERROR regf_add_key (TALLOC_CTX *ctx, struct registry_key *parent, const return WERR_OK; } +static WERROR regf_set_value (struct registry_key *key, const char *name, uint32_t type, DATA_BLOB data) +{ + /* FIXME */ + + return WERR_NOT_SUPPORTED; +} + +static WERROR regf_save(struct registry_hive *hive, const char *location) +{ + struct regf_data *regf = hive->backend_data; + struct tdr_push *push = talloc_zero(regf, struct tdr_push); + int i; + + tdr_push_regf_hdr(push, regf->header); + + for (i = 0; regf->hbins[i]; i++) { + tdr_push_hbin_block(push, regf->hbins[i]); + } + + file_save(location, push->data.data, push->data.length); + + return WERR_OK; +} + static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) { struct regf_data *regf; @@ -676,6 +704,8 @@ static struct hive_operations reg_backend_nt4 = { .get_value_by_index = regf_get_value, .key_get_sec_desc = regf_get_sec_desc, .add_key = regf_add_key, + .set_value = regf_set_value, + .save_hive = regf_save, }; NTSTATUS registry_nt4_init(void) diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h new file mode 100644 index 0000000000..f9e8a7698c --- /dev/null +++ b/source4/lib/registry/registry.h @@ -0,0 +1,136 @@ +/* + Unix SMB/CIFS implementation. + Registry interface + Copyright (C) Gerald Carter 2002. + Copyright (C) Jelmer Vernooij 2003-2004. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _REGISTRY_H /* _REGISTRY_H */ +#define _REGISTRY_H + +/* Handles for the predefined keys */ +#define HKEY_CLASSES_ROOT 0x80000000 +#define HKEY_CURRENT_USER 0x80000001 +#define HKEY_LOCAL_MACHINE 0x80000002 +#define HKEY_USERS 0x80000003 +#define HKEY_PERFORMANCE_DATA 0x80000004 +#define HKEY_CURRENT_CONFIG 0x80000005 +#define HKEY_DYN_DATA 0x80000006 +#define HKEY_PERFORMANCE_TEXT 0x80000050 +#define HKEY_PERFORMANCE_NLSTEXT 0x80000060 + +#define REG_DELETE -1 + +/* + * The general idea here is that every backend provides a 'hive'. Combining + * various hives gives you a complete registry like windows has + */ + +#define REGISTRY_INTERFACE_VERSION 1 + +/* structure to store the registry handles */ +struct registry_key { + char *name; /* Name of the key */ + const char *path; /* Full path to the key */ + char *class_name; /* Name of key class */ + NTTIME last_mod; /* Time last modified */ + struct registry_hive *hive; + void *backend_data; +}; + +struct registry_value { + char *name; + unsigned int data_type; + DATA_BLOB data; +}; + +/* FIXME */ +typedef void (*key_notification_function) (void); +typedef void (*value_notification_function) (void); + +/* + * Container for function pointers to enumeration routines + * for virtual registry view + * + * Backends can provide : + * - just one hive (example: nt4, w95) + * - several hives (example: rpc). + * + * Backends should always do case-insensitive compares + * (everything is case-insensitive but case-preserving, + * just like the FS) + */ + +struct hive_operations { + const char *name; + + /* Implement this one */ + WERROR (*open_hive) (struct registry_hive *, struct registry_key **); + WERROR (*save_hive) (struct registry_hive *, const char *location); + + /* Or this one */ + WERROR (*open_key) (TALLOC_CTX *, struct registry_key *, const char *name, struct registry_key **); + + WERROR (*num_subkeys) (struct registry_key *, uint32_t *count); + WERROR (*num_values) (struct registry_key *, uint32_t *count); + WERROR (*get_subkey_by_index) (TALLOC_CTX *, struct registry_key *, int idx, struct registry_key **); + + /* Can not contain more then one level */ + WERROR (*get_subkey_by_name) (TALLOC_CTX *, struct registry_key *, const char *name, struct registry_key **); + WERROR (*get_value_by_index) (TALLOC_CTX *, struct registry_key *, int idx, struct registry_value **); + + /* Can not contain more then one level */ + 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 *, 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, struct security_descriptor *, struct registry_key **); + WERROR (*del_key)(struct registry_key *, const char *name); + WERROR (*flush_key) (struct registry_key *); + + /* Value management */ + WERROR (*set_value)(struct registry_key *, const char *name, uint32_t type, DATA_BLOB data); + WERROR (*del_value)(struct registry_key *, const char *valname); +}; + +struct registry_hive { + const struct hive_operations *functions; + struct registry_key *root; + void *backend_data; + const char *location; +}; + +/* Handle to a full registry + * contains zero or more hives */ +struct registry_context { + void *backend_data; + WERROR (*get_predefined_key) (struct registry_context *, uint32_t hkey, struct registry_key **); +}; + +struct reg_init_function_entry { + const struct hive_operations *hive_functions; + struct reg_init_function_entry *prev, *next; +}; + +#endif /* _REGISTRY_H */ diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 307ec3793e..3d8201330e 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -21,7 +21,7 @@ #include "includes.h" #include "dynconfig.h" -#include "registry.h" +#include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" static void writediff(struct registry_key *oldkey, struct registry_key *newkey, FILE *out) diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 5f7d4376d4..887f53df37 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -22,7 +22,7 @@ #include "includes.h" #include "dynconfig.h" -#include "registry.h" +#include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" #include "system/filesys.h" #include "librpc/gen_ndr/winreg.h" diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 496b9dc7e5..08da5ae2fd 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -21,9 +21,10 @@ #include "includes.h" #include "dynconfig.h" -#include "registry.h" +#include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" #include "system/time.h" +#include "librpc/gen_ndr/ndr_security.h" /* * ck/cd - change key @@ -33,19 +34,30 @@ * mkkey/mkdir - make key * ch - change hive * info - show key info + * save - save hive * help * exit */ static struct registry_key *cmd_info(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) { + struct security_descriptor *sec_desc = NULL; time_t last_mod; + WERROR error; + printf("Name: %s\n", cur->name); printf("Full path: %s\n", cur->path); printf("Key Class: %s\n", cur->class_name); last_mod = nt_time_to_unix(cur->last_mod); printf("Time Last Modified: %s\n", ctime(&last_mod)); - /* FIXME: Security info */ + + error = reg_get_sec_desc(mem_ctx, cur, &sec_desc); + if (!W_ERROR_IS_OK(error)) { + printf("Error getting security descriptor\n"); + } else { + ndr_print_debug((ndr_print_fn_t)ndr_print_security_descriptor, "Security", sec_desc); + } + talloc_free(sec_desc); return cur; } diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 38dffed85d..c24e66412f 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -21,7 +21,7 @@ #include "includes.h" #include "dynconfig.h" -#include "registry.h" +#include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" static void print_tree(int l, struct registry_key *p, int fullpath, int novals) -- cgit From a487b6c19c28100041ceb2b7a5798c236983509c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 4 Sep 2005 17:26:23 +0000 Subject: r10028: More registry fixes. Remove save_hive() function (there is a flush_key function already). Fixes for the allocation mechanism in the REGF backend (This used to be commit 499d03bc90382bcd33c8c3a1577a58d2c76e5129) --- source4/lib/registry/reg_backend_nt4.c | 152 ++++++++++++++++++++++++--------- source4/lib/registry/registry.h | 4 +- 2 files changed, 115 insertions(+), 41 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index 4fc458dee4..4a3576f85e 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -24,12 +24,17 @@ #include "lib/registry/tdr_regf.h" #include "librpc/gen_ndr/ndr_security.h" +/* TODO: + * - Return error codes that make more sense + * - Locking + */ + /* * Read HBIN blocks into memory */ struct regf_data { - DATA_BLOB data; + int fd; struct hbin_block **hbins; struct regf_hdr *header; }; @@ -79,15 +84,19 @@ static DATA_BLOB hbin_get(const struct regf_data *data, uint32_t offset) hbin = hbin_by_offset(data, offset, &rel_offset); if (hbin == NULL) { - DEBUG(1, ("Can't find HBIN containing 0x%4x\n", offset)); + DEBUG(1, ("Can't find HBIN containing 0x%04x\n", offset)); return ret; } ret.length = IVAL(hbin->data, rel_offset); - if (ret.length & 0x80000000) { - /* absolute value */ - ret.length = (ret.length ^ 0xffffffff) + 1; + if (!(ret.length & 0x80000000)) { + DEBUG(0, ("Trying to use dirty block at 0x%04x\n", offset)); + return ret; } + + /* remove high bit */ + ret.length = (ret.length ^ 0xffffffff) + 1; + ret.length -= 4; /* 4 bytes for the length... */ ret.data = hbin->data + (offset - hbin->offset_from_first - 0x20) + 4; @@ -128,6 +137,9 @@ static DATA_BLOB hbin_alloc (struct regf_data *data, uint32_t size, uint32_t *of struct hbin_block *hbin = NULL; int i; + if (size == 0) + return ret; + size += 4; /* Need to include uint32 for the length */ /* Allocate as a multiple of 8 */ @@ -136,9 +148,6 @@ static DATA_BLOB hbin_alloc (struct regf_data *data, uint32_t size, uint32_t *of ret.data = NULL; ret.length = 0; - if (size == 0) - return ret; - for (i = 0; (hbin = data->hbins[i]); i++) { int j; uint32_t my_size; @@ -146,6 +155,11 @@ static DATA_BLOB hbin_alloc (struct regf_data *data, uint32_t size, uint32_t *of my_size = IVAL(hbin->data, j); uint32_t header = IVAL(hbin->data, j + 4); + if (my_size == 0x0) { + DEBUG(0, ("Invalid zero-length block! File is corrupt.\n")); + return ret; + } + if (my_size % 8 != 0) { DEBUG(0, ("Encountered non-aligned block!\n")); } @@ -154,16 +168,20 @@ static DATA_BLOB hbin_alloc (struct regf_data *data, uint32_t size, uint32_t *of my_size = (my_size ^ 0xffffffff) + 1; } else if (my_size == size) { /* exact match */ rel_offset = j; + DEBUG(4, ("Found free block of exact size %d in middle of HBIN\n", size)); break; } else if (my_size > size) { /* data will remain */ rel_offset = j; SIVAL(hbin->data, rel_offset+size, my_size-size); + DEBUG(4, ("Found free block of size %d (needing %d) in middle of HBIN\n", my_size, size)); break; } if (header == 0xffffffff && hbin->offset_to_next-rel_offset >= size) { rel_offset = j; + + DEBUG(4, ("Found free block of size %d at end of HBIN\n", size)); /* Mark new free block size */ SIVAL(hbin->data, rel_offset+size,hbin->offset_to_next - rel_offset - size - 0x20); SIVAL(hbin->data, rel_offset+size+0x4, 0xffffffff); @@ -182,6 +200,7 @@ static DATA_BLOB hbin_alloc (struct regf_data *data, uint32_t size, uint32_t *of /* No space available in previous hbins, * allocate new one */ if (data->hbins[i] == NULL) { + DEBUG(4, ("No space available in other HBINs for block of size %d, allocating new HBIN\n", size)); data->hbins = talloc_realloc(data, data->hbins, struct hbin_block *, i+2); hbin = talloc(data->hbins, struct hbin_block); data->hbins[i] = hbin; @@ -202,12 +221,16 @@ static DATA_BLOB hbin_alloc (struct regf_data *data, uint32_t size, uint32_t *of } /* Set size and mark as used */ - SIVAL(hbin->data, rel_offset, size & 0x80000000); + SIVAL(hbin->data, rel_offset, size | 0x80000000); ret.data = hbin->data + rel_offset + 0x4; /* Skip past length */ ret.length = size - 0x4; - if (offset) + if (offset) { + uint32_t new_rel_offset; *offset = hbin->offset_from_first + rel_offset + 0x20; + SMB_ASSERT(hbin_by_offset(data, *offset, &new_rel_offset) == hbin); + SMB_ASSERT(new_rel_offset == rel_offset); + } return ret; } @@ -246,7 +269,11 @@ static void hbin_free (struct regf_data *data, uint32_t offset) { uint32_t size; uint32_t rel_offset; - struct hbin_block *hbin = hbin_by_offset(data, offset, &rel_offset); + struct hbin_block *hbin; + + SMB_ASSERT (offset > 0); + + hbin = hbin_by_offset(data, offset, &rel_offset); if (hbin == NULL) return; @@ -255,12 +282,12 @@ static void hbin_free (struct regf_data *data, uint32_t offset) size = IVAL(hbin->data, rel_offset); if (!(size & 0x80000000)) { - DEBUG(1, ("Trying to free already freed block\n")); + DEBUG(1, ("Trying to free already freed block at 0x%04x\n", offset)); return; } /* Mark block as free */ - SIVAL(hbin->data, rel_offset, (size ^ 0xffffffff) + 1); + SIVAL(hbin->data, rel_offset, size &~ 0x80000000); } /* Store a data blob data was already stored, but hsa changed in size @@ -270,41 +297,48 @@ static uint32_t hbin_store_resize (struct regf_data *data, uint32_t orig_offset, { uint32_t rel_offset; struct hbin_block *hbin = hbin_by_offset(data, orig_offset, &rel_offset); + uint32_t my_size; uint32_t orig_size; uint32_t needed_size; uint32_t possible_size; int i; + SMB_ASSERT(orig_offset > 0); + if (!hbin) return hbin_store(data, blob); /* Get original size */ orig_size = IVAL(hbin->data, rel_offset); + needed_size = blob.length + 4; /* Add uint32 containing length */ + needed_size = (needed_size + 7) & ~7; /* Align */ + /* Fits into current allocated block */ - if (orig_size - 4 >= blob.length) { + if (orig_size >= needed_size) { memcpy(hbin->data + rel_offset + 0x4, blob.data, blob.length); return orig_offset; } - needed_size = blob.length + 4; /* Add uint32 containing length */ - needed_size = (needed_size + 7) & ~7; /* Align */ - possible_size = orig_size; /* Check if it can be combined with the next few free records */ for (i = rel_offset; i < hbin->offset_to_next - 0x20; - i = rel_offset + possible_size) { + i += my_size) { uint32_t header; if (IVAL(hbin->data, i) & 0x80000000) /* Used */ break; + my_size = IVAL(hbin->data, i); header = IVAL(hbin->data, i + 4); if (header == 0xffffffff) { possible_size = hbin->offset_to_next - 0x20 - rel_offset; + } else if (my_size == 0x0) { + DEBUG(0, ("Invalid zero-length block! File is corrupt.\n")); + break; } else { - possible_size += IVAL(hbin->data, i); + possible_size += my_size; } if (possible_size >= blob.length) { @@ -425,7 +459,7 @@ static WERROR regf_get_value (TALLOC_CTX *ctx, struct registry_key *key, int idx (*ret)->name = talloc_steal(*ret, vk->data_name); (*ret)->data_type = vk->data_type; if (vk->data_length & 0x80000000) { - vk->data_length &= ~0x80000000; + vk->data_length &=~0x80000000; (*ret)->data.data = (uint8_t *)&vk->data_offset; (*ret)->data.length = vk->data_length; } else { @@ -493,6 +527,13 @@ static WERROR regf_get_subkey (TALLOC_CTX *ctx, struct registry_key *key, int id return WERR_OK; } + +static WERROR regf_set_sec_desc (struct registry_key *key, struct security_descriptor *sec_desc) +{ + /* FIXME */ + return WERR_NOT_SUPPORTED; +} + static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, struct registry_key *key, struct security_descriptor **sd) { struct nk_block *nk = key->backend_data; @@ -543,16 +584,39 @@ static uint32_t lf_add_entry (struct regf_data *regf, uint32_t list_offset, cons lf.hr = talloc_realloc(regf, lf.hr, struct hash_record, lf.key_count+1); lf.hr[lf.key_count].nk_off = key_offset; - lf.hr[lf.key_count].hash = name; + lf.hr[lf.key_count].hash = talloc_strndup(regf, name, 4); + lf.key_count++; ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t)tdr_push_lf_block, list_offset, &lf); return ret; } +static WERROR regf_del_value (struct registry_key *parent, const char *name) +{ + /* FIXME */ + return WERR_NOT_SUPPORTED; +} + + +static WERROR regf_del_key (struct registry_key *parent, const char *name) +{ + struct nk_block *nk = parent->backend_data; + + SMB_ASSERT(nk); + + if (nk->subkeys_offset == -1) + return WERR_BADFILE; + + /* FIXME */ + + return WERR_NOT_SUPPORTED; +} + static WERROR regf_add_key (TALLOC_CTX *ctx, struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *sec_desc, struct registry_key **ret) { struct nk_block *parent_nk = parent->backend_data, nk; + struct regf_data *regf = parent->hive->backend_data; uint32_t offset; nk.header = "nk"; @@ -571,17 +635,17 @@ static WERROR regf_add_key (TALLOC_CTX *ctx, struct registry_key *parent, const nk.clsname_length = 0; nk.key_name = name; - offset = hbin_store_tdr(parent->hive->backend_data, (tdr_push_fn_t) tdr_push_nk_block, &nk); + offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_nk_block, &nk); - parent_nk->subkeys_offset = lf_add_entry(parent->hive->backend_data, parent_nk->subkeys_offset, name, nk.parent_offset); + parent_nk->subkeys_offset = lf_add_entry(regf, parent_nk->subkeys_offset, name, nk.parent_offset); parent_nk->num_subkeys++; - hbin_store_tdr_resize(parent->hive->backend_data, (tdr_push_fn_t) tdr_push_nk_block, nk.parent_offset, parent_nk); + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, nk.parent_offset, parent_nk); - /* FIXME: Set sec desc ! */ + *ret = regf_get_key(ctx, regf, offset); - *ret = regf_get_key(ctx, parent->hive->backend_data, offset); + /* FIXME: Set sec desc ! */ return WERR_OK; } @@ -592,19 +656,20 @@ static WERROR regf_set_value (struct registry_key *key, const char *name, uint32 return WERR_NOT_SUPPORTED; } -static WERROR regf_save(struct registry_hive *hive, const char *location) +static WERROR regf_save_hbin(struct registry_hive *hive, struct hbin_block *hbin) { struct regf_data *regf = hive->backend_data; - struct tdr_push *push = talloc_zero(regf, struct tdr_push); - int i; - tdr_push_regf_hdr(push, regf->header); - - for (i = 0; regf->hbins[i]; i++) { - tdr_push_hbin_block(push, regf->hbins[i]); + /* go to right offset */ + if (lseek(regf->fd, SEEK_SET, regf->header->data_offset + hbin->offset_from_first) == -1) { + DEBUG(0, ("Error lseeking in regf file\n")); + return WERR_GENERAL_FAILURE; } - file_save(location, push->data.data, push->data.length); + if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, (tdr_push_fn_t)tdr_push_hbin_block, hbin))) { + DEBUG(0, ("Error writing HBIN block\n")); + return WERR_GENERAL_FAILURE; + } return WERR_OK; } @@ -622,9 +687,9 @@ static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) DEBUG(5, ("Attempting to load registry file\n")); /* Get the header */ + regf->fd = open(h->location, O_RDWR); - regf->data.data = (uint8_t *)file_load(h->location, ®f->data.length, regf); - if (regf->data.data == NULL) { + if (regf->fd == -1) { DEBUG(0,("Could not load file: %s, %s\n", h->location, strerror(errno))); return WERR_GENERAL_FAILURE; @@ -634,7 +699,12 @@ static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) if (!pull) return WERR_NOMEM; - pull->data = regf->data; + pull->data.data = (uint8_t*)fd_load(regf->fd, &pull->data.length, regf); + + if (pull->data.data == NULL) { + DEBUG(0, ("Error reading data\n")); + return WERR_GENERAL_FAILURE; + } regf_hdr = talloc(regf, struct regf_hdr); if (NT_STATUS_IS_ERR(tdr_pull_regf_hdr(pull, regf_hdr))) { @@ -656,9 +726,9 @@ static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) /* * Validate the header ... */ - if (regf_hdr_checksum(regf->data.data) != regf_hdr->chksum) { + if (regf_hdr_checksum(pull->data.data) != regf_hdr->chksum) { DEBUG(0, ("Registry file checksum error: %s: %d,%d\n", - h->location, regf_hdr->chksum, regf_hdr_checksum(regf->data.data))); + h->location, regf_hdr->chksum, regf_hdr_checksum(pull->data.data))); return WERR_GENERAL_FAILURE; } @@ -703,9 +773,11 @@ static struct hive_operations reg_backend_nt4 = { .get_subkey_by_index = regf_get_subkey, .get_value_by_index = regf_get_value, .key_get_sec_desc = regf_get_sec_desc, + .key_set_sec_desc = regf_set_sec_desc, .add_key = regf_add_key, .set_value = regf_set_value, - .save_hive = regf_save, + .del_key = regf_del_key, + .del_value = regf_del_value, }; NTSTATUS registry_nt4_init(void) diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index f9e8a7698c..e843e1a0be 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -73,6 +73,9 @@ typedef void (*value_notification_function) (void); * Backends should always do case-insensitive compares * (everything is case-insensitive but case-preserving, * just like the FS) + * + * There is no save function as all operations are expected to + * be atomic. */ struct hive_operations { @@ -80,7 +83,6 @@ struct hive_operations { /* Implement this one */ WERROR (*open_hive) (struct registry_hive *, struct registry_key **); - WERROR (*save_hive) (struct registry_hive *, const char *location); /* Or this one */ WERROR (*open_key) (TALLOC_CTX *, struct registry_key *, const char *name, struct registry_key **); -- cgit From a3e0e69196cc5e3420ebb1a83b026ee36cbaab83 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 4 Sep 2005 20:17:21 +0000 Subject: r10030: Add hierarchical memory allocation to TDR's pull functions (This used to be commit 0e358de93a007db921ad5e9a892114122254de39) --- source4/lib/registry/config.mk | 1 - source4/lib/registry/reg_backend_nt4.c | 61 +++++++++++++++------------------- 2 files changed, 27 insertions(+), 35 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index a1bb62f7df..43149f88aa 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -17,7 +17,6 @@ NOPROTO = YES INIT_OBJ_FILES = lib/registry/tdr_regf.o lib/registry/tdr_regf.c: lib/registry/regf.idl - @echo "Compiling lib/registry/regf.idl" @./pidl/pidl --header --outputdir=lib/registry --parse --tdr-header --tdr-parser -- lib/registry/regf.idl ################################################ diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index 4a3576f85e..f31a2f52e7 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -104,28 +104,23 @@ static DATA_BLOB hbin_get(const struct regf_data *data, uint32_t offset) return ret; } -static BOOL hbin_get_tdr (struct regf_data *regf, uint32_t offset, tdr_pull_fn_t pull_fn, void *p) +static BOOL hbin_get_tdr (struct regf_data *regf, uint32_t offset, TALLOC_CTX *ctx, tdr_pull_fn_t pull_fn, void *p) { - DATA_BLOB data; - struct tdr_pull *pull; + struct tdr_pull pull; - data = hbin_get(regf, offset); - if (!data.data) { + ZERO_STRUCT(pull); + + pull.data = hbin_get(regf, offset); + if (!pull.data.data) { DEBUG(1, ("Unable to get data at 0x%04x\n", offset)); return False; } - pull = talloc_zero(regf, struct tdr_pull); - pull->data = data; - - if (NT_STATUS_IS_ERR(pull_fn(pull, p))) { + if (NT_STATUS_IS_ERR(pull_fn(&pull, ctx, p))) { DEBUG(1, ("Error parsing record at 0x%04x using tdr\n", offset)); - talloc_free(pull); return False; } - /* FIXME: Free pull ! */ - return True; } @@ -397,7 +392,7 @@ static struct registry_key *regf_get_key (TALLOC_CTX *ctx, struct regf_data *reg ret = talloc_zero(ctx, struct registry_key); nk = talloc(ret, struct nk_block); - if (!hbin_get_tdr(regf, offset, (tdr_pull_fn_t)tdr_pull_nk_block, nk)) { + if (!hbin_get_tdr(regf, offset, nk, (tdr_pull_fn_t)tdr_pull_nk_block, nk)) { DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset)); return NULL; } @@ -451,7 +446,7 @@ static WERROR regf_get_value (TALLOC_CTX *ctx, struct registry_key *key, int idx if (!vk) return WERR_NOMEM; - if (!hbin_get_tdr(regf, vk_offset, (tdr_pull_fn_t)tdr_pull_vk_block, vk)) { + if (!hbin_get_tdr(regf, vk_offset, vk, (tdr_pull_fn_t)tdr_pull_vk_block, vk)) { DEBUG(0, ("Unable to get VK block at %d\n", vk_offset)); return WERR_GENERAL_FAILURE; } @@ -493,12 +488,13 @@ static WERROR regf_get_subkey (TALLOC_CTX *ctx, struct registry_key *key, int id SMB_ASSERT(0); } else if (!strncmp((char *)data.data, "lf", 2)) { struct lf_block lf; - struct tdr_pull *pull = talloc_zero(ctx, struct tdr_pull); + struct tdr_pull pull; DEBUG(10, ("Subkeys in LF list\n")); - pull->data = data; + ZERO_STRUCT(pull); + pull.data = data; - if (NT_STATUS_IS_ERR(tdr_pull_lf_block(pull, &lf))) { + if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, nk, &lf))) { DEBUG(0, ("Error parsing LF list\n")); return WERR_GENERAL_FAILURE; } @@ -509,8 +505,6 @@ static WERROR regf_get_subkey (TALLOC_CTX *ctx, struct registry_key *key, int id } key_off = lf.hr[idx].nk_off; - - talloc_free(pull); } else if (!strncmp((char *)data.data, "ri", 2)) { DEBUG(4, ("Subkeys in RI list\n")); SMB_ASSERT(0); @@ -541,7 +535,7 @@ static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, struct registry_key *key, struc struct regf_data *regf = key->hive->backend_data; DATA_BLOB data; - if (!hbin_get_tdr(regf, nk->sk_offset, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + if (!hbin_get_tdr(regf, nk->sk_offset, ctx, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find security descriptor\n")); return WERR_GENERAL_FAILURE; } @@ -576,7 +570,7 @@ static uint32_t lf_add_entry (struct regf_data *regf, uint32_t list_offset, cons lf.key_count = 0; lf.hr = NULL; } else { - if (!hbin_get_tdr(regf, list_offset, (tdr_pull_fn_t)tdr_pull_lf_block, &lf)) { + if (!hbin_get_tdr(regf, list_offset, regf, (tdr_pull_fn_t)tdr_pull_lf_block, &lf)) { DEBUG(0, ("Can't get subkeys list\n")); return -1; } @@ -588,6 +582,8 @@ static uint32_t lf_add_entry (struct regf_data *regf, uint32_t list_offset, cons lf.key_count++; ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t)tdr_push_lf_block, list_offset, &lf); + + talloc_free(lf.hr); return ret; } @@ -678,7 +674,7 @@ static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) { struct regf_data *regf; struct regf_hdr *regf_hdr; - struct tdr_pull *pull; + struct tdr_pull pull; int i; regf = (struct regf_data *)talloc_zero(h, struct regf_data); @@ -695,19 +691,16 @@ static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) return WERR_GENERAL_FAILURE; } - pull = talloc_zero(regf, struct tdr_pull); - if (!pull) - return WERR_NOMEM; - - pull->data.data = (uint8_t*)fd_load(regf->fd, &pull->data.length, regf); + ZERO_STRUCT(pull); + pull.data.data = (uint8_t*)fd_load(regf->fd, &pull.data.length, regf); - if (pull->data.data == NULL) { + if (pull.data.data == NULL) { DEBUG(0, ("Error reading data\n")); return WERR_GENERAL_FAILURE; } regf_hdr = talloc(regf, struct regf_hdr); - if (NT_STATUS_IS_ERR(tdr_pull_regf_hdr(pull, regf_hdr))) { + if (NT_STATUS_IS_ERR(tdr_pull_regf_hdr(&pull, regf_hdr, regf_hdr))) { return WERR_GENERAL_FAILURE; } @@ -726,23 +719,23 @@ static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) /* * Validate the header ... */ - if (regf_hdr_checksum(pull->data.data) != regf_hdr->chksum) { + if (regf_hdr_checksum(pull.data.data) != regf_hdr->chksum) { DEBUG(0, ("Registry file checksum error: %s: %d,%d\n", - h->location, regf_hdr->chksum, regf_hdr_checksum(pull->data.data))); + h->location, regf_hdr->chksum, regf_hdr_checksum(pull.data.data))); return WERR_GENERAL_FAILURE; } - pull->offset = 0x1000; + pull.offset = 0x1000; i = 0; /* Read in all hbin blocks */ regf->hbins = talloc_array(regf, struct hbin_block *, 1); regf->hbins[0] = NULL; - while (pull->offset < pull->data.length) { + while (pull.offset < pull.data.length) { struct hbin_block *hbin = talloc(regf->hbins, struct hbin_block); - if (NT_STATUS_IS_ERR(tdr_pull_hbin_block(pull, hbin))) { + if (NT_STATUS_IS_ERR(tdr_pull_hbin_block(&pull, hbin, hbin))) { DEBUG(0, ("[%d] Error parsing HBIN block\n", i)); return WERR_FOOBAR; } -- cgit From e3a1ee4788788307d9bffaca9ee63f2bf4614967 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 5 Sep 2005 20:56:28 +0000 Subject: r10043: Only recompile subsystems that actually need recompilation (This used to be commit de9830979788528754175b17fe45477e6ce9ce9e) --- source4/lib/registry/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 43149f88aa..d0939c720b 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -16,6 +16,7 @@ REQUIRED_SUBSYSTEMS = TDR NOPROTO = YES INIT_OBJ_FILES = lib/registry/tdr_regf.o +lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c lib/registry/tdr_regf.c: lib/registry/regf.idl @./pidl/pidl --header --outputdir=lib/registry --parse --tdr-header --tdr-parser -- lib/registry/regf.idl -- cgit From db400b4a58d834cca165f1fc6ad84e9f5ace280f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 6 Sep 2005 15:44:08 +0000 Subject: r10052: Add 'print' command (This used to be commit d99c9e2817fbbe2a0a34910672c8473889bc6176) --- source4/lib/registry/tools/regshell.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 08da5ae2fd..24979943b3 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -35,6 +35,7 @@ * ch - change hive * info - show key info * save - save hive + * print - print value * help * exit */ @@ -123,6 +124,26 @@ static struct registry_key *cmd_ck(TALLOC_CTX *mem_ctx, struct registry_context return new; } +static struct registry_key *cmd_print(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) +{ + struct registry_value *value; + WERROR error; + + if (argc != 2) { + fprintf(stderr, "Usage: print "); + return NULL; + } + + error = reg_key_get_value_by_name(mem_ctx, cur, argv[1], &value); + if (!W_ERROR_IS_OK(error)) { + fprintf(stderr, "No such value '%s'\n", argv[1]); + return NULL; + } + + printf("%s\n%s\n", str_regtype(value->data_type), reg_val_data_string(mem_ctx, value)); + return NULL; +} + static struct registry_key *cmd_ls(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) { int i; @@ -208,6 +229,7 @@ static struct { {"ck", "cd", "Change current key", cmd_ck }, {"info", "i", "Show detailed information of a key", cmd_info }, {"list", "ls", "List values/keys in current key", cmd_ls }, + {"print", "p", "Print value", cmd_print }, {"mkkey", "mkdir", "Make new key", cmd_mkkey }, {"rmval", "rm", "Remove value", cmd_rmval }, {"rmkey", "rmdir", "Remove key", cmd_rmkey }, -- cgit From c070fd62228a4fb0af0d275edc3d141e44dff389 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 8 Sep 2005 10:35:55 +0000 Subject: r10074: Pass CPP to pidl via environment variables rather then config.pm. This fixes the standalone pidl build (as used for ethereal) (This used to be commit 9c9ebd2214423c58357854f09bd744e13e807d8f) --- source4/lib/registry/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index d0939c720b..4a518321a4 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -18,7 +18,7 @@ INIT_OBJ_FILES = lib/registry/tdr_regf.o lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c lib/registry/tdr_regf.c: lib/registry/regf.idl - @./pidl/pidl --header --outputdir=lib/registry --parse --tdr-header --tdr-parser -- lib/registry/regf.idl + @CPP="$(CPP) $(PERL) pidl/pidl --header --outputdir=lib/registry --parse --tdr-header --tdr-parser -- lib/registry/regf.idl ################################################ # Start MODULE registry_w95 -- cgit From a769fa3467e836c6074314d6a67a2a64a96baa9e Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Thu, 8 Sep 2005 19:58:59 +0000 Subject: r10089: Fix a typo breaking the Makefile generator and therefore - the build. rafal (This used to be commit d6936185d5e4a85b188d5117d7a3b3d6bea2f96b) --- source4/lib/registry/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 4a518321a4..b68046ca69 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -18,7 +18,7 @@ INIT_OBJ_FILES = lib/registry/tdr_regf.o lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c lib/registry/tdr_regf.c: lib/registry/regf.idl - @CPP="$(CPP) $(PERL) pidl/pidl --header --outputdir=lib/registry --parse --tdr-header --tdr-parser -- lib/registry/regf.idl + @CPP="$(CPP)" $(PERL) pidl/pidl --header --outputdir=lib/registry --parse --tdr-header --tdr-parser -- lib/registry/regf.idl ################################################ # Start MODULE registry_w95 -- cgit From 289127b0262246147c370f3261ce94b0e3669969 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 9 Sep 2005 04:22:58 +0000 Subject: r10104: Fix code before declaration. (This used to be commit 05c020181560afd4e6957be29795536e2d83d71e) --- source4/lib/registry/reg_backend_nt4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index f31a2f52e7..e5c0221504 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -147,8 +147,8 @@ static DATA_BLOB hbin_alloc (struct regf_data *data, uint32_t size, uint32_t *of int j; uint32_t my_size; for (j = 0; j < hbin->offset_to_next-0x20; j+= my_size) { - my_size = IVAL(hbin->data, j); uint32_t header = IVAL(hbin->data, j + 4); + my_size = IVAL(hbin->data, j); if (my_size == 0x0) { DEBUG(0, ("Invalid zero-length block! File is corrupt.\n")); -- cgit From 8b5a9537250e2d55a782c40f51fbedafa3d6bee7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 9 Sep 2005 10:59:54 +0000 Subject: r10111: Make pidl by default assume the input file is an IDL file rather then a .pidl file. (This used to be commit d8a31d3048a6421a3d49d3c121bc86d748838b3a) --- source4/lib/registry/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index b68046ca69..4cf73bf66a 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -18,7 +18,7 @@ INIT_OBJ_FILES = lib/registry/tdr_regf.o lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c lib/registry/tdr_regf.c: lib/registry/regf.idl - @CPP="$(CPP)" $(PERL) pidl/pidl --header --outputdir=lib/registry --parse --tdr-header --tdr-parser -- lib/registry/regf.idl + @CPP="$(CPP)" $(PERL) pidl/pidl --header --outputdir=lib/registry --tdr-header --tdr-parser -- lib/registry/regf.idl ################################################ # Start MODULE registry_w95 -- cgit From 5d2c2edc19d471cb2b757c53eeb007f4dd7f9348 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 13 Sep 2005 17:28:18 +0000 Subject: r10207: Add some const (This used to be commit b1ad340b4720e922ae1e332c2a74986b1656358b) --- source4/lib/registry/common/reg_interface.c | 29 +++++++--------- source4/lib/registry/reg_backend_dir.c | 8 ++--- source4/lib/registry/reg_backend_ldb.c | 16 ++++----- source4/lib/registry/reg_backend_nt4.c | 20 +++++------ source4/lib/registry/reg_backend_rpc.c | 18 +++++----- source4/lib/registry/reg_backend_w95.c | 6 ++-- source4/lib/registry/regf.idl | 2 +- source4/lib/registry/registry.h | 53 +++++++++++++++-------------- 8 files changed, 75 insertions(+), 77 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 74f158b027..7a35c97c43 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -237,7 +237,7 @@ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char return WERR_OK; } -WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *key, int idx, struct registry_value **val) +WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *key, int idx, struct registry_value **val) { if(!key) return WERR_INVALID_PARAM; @@ -252,7 +252,7 @@ WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *key, return WERR_OK; } -WERROR reg_key_num_subkeys(struct registry_key *key, uint32_t *count) +WERROR reg_key_num_subkeys(const struct registry_key *key, uint32_t *count) { if(!key) return WERR_INVALID_PARAM; @@ -277,7 +277,7 @@ WERROR reg_key_num_subkeys(struct registry_key *key, uint32_t *count) return WERR_NOT_SUPPORTED; } -WERROR reg_key_num_values(struct registry_key *key, uint32_t *count) +WERROR reg_key_num_values(const struct registry_key *key, uint32_t *count) { if(!key) return WERR_INVALID_PARAM; @@ -303,7 +303,7 @@ WERROR reg_key_num_values(struct registry_key *key, uint32_t *count) 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) +WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *key, int idx, struct registry_key **subkey) { if(!key) return WERR_INVALID_PARAM; @@ -323,7 +323,7 @@ WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key *key return WERR_OK;; } -WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key, const char *name, struct registry_key **subkey) +WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char *name, struct registry_key **subkey) { int i; WERROR error = WERR_OK; @@ -356,7 +356,7 @@ WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key, return WERR_OK; } -WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key, const char *name, struct registry_value **val) +WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char *name, struct registry_value **val) { int i; WERROR error = WERR_OK; @@ -395,7 +395,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, struct security_descriptor *desc, struct registry_key **newkey) +WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, const struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *desc, struct registry_key **newkey) { WERROR error; @@ -432,7 +432,7 @@ WERROR reg_val_set(struct registry_key *key, const char *value, uint32_t type, D } -WERROR reg_get_sec_desc(TALLOC_CTX *ctx, struct registry_key *key, struct security_descriptor **secdesc) +WERROR reg_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, struct security_descriptor **secdesc) { /* A 'real' set function has preference */ if (key->hive->functions->key_get_sec_desc) @@ -442,7 +442,7 @@ WERROR reg_get_sec_desc(TALLOC_CTX *ctx, struct registry_key *key, struct securi return WERR_NOT_SUPPORTED; } -WERROR reg_del_value(struct registry_key *key, const char *valname) +WERROR reg_del_value(const struct registry_key *key, const char *valname) { WERROR ret = WERR_OK; if(!key->hive->functions->del_value) @@ -455,12 +455,7 @@ WERROR reg_del_value(struct registry_key *key, const char *valname) return ret; } -WERROR reg_save (struct registry_context *ctx, const char *location) -{ - return WERR_NOT_SUPPORTED; -} - -WERROR reg_key_flush(struct registry_key *key) +WERROR reg_key_flush(const struct registry_key *key) { if (!key) { return WERR_INVALID_PARAM; @@ -474,7 +469,7 @@ WERROR reg_key_flush(struct registry_key *key) return WERR_OK; } -WERROR reg_key_subkeysizes(struct registry_key *key, uint32_t *max_subkeylen, uint32_t *max_subkeysize) +WERROR reg_key_subkeysizes(const struct registry_key *key, uint32_t *max_subkeylen, uint32_t *max_subkeysize) { int i = 0; struct registry_key *subkey; @@ -499,7 +494,7 @@ WERROR reg_key_subkeysizes(struct registry_key *key, uint32_t *max_subkeylen, ui return WERR_OK; } -WERROR reg_key_valuesizes(struct registry_key *key, uint32_t *max_valnamelen, uint32_t *max_valbufsize) +WERROR reg_key_valuesizes(const struct registry_key *key, uint32_t *max_valnamelen, uint32_t *max_valbufsize) { int i = 0; struct registry_value *value; diff --git a/source4/lib/registry/reg_backend_dir.c b/source4/lib/registry/reg_backend_dir.c index 68f02d1745..da22d8d9ee 100644 --- a/source4/lib/registry/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir.c @@ -23,7 +23,7 @@ #include "system/dir.h" #include "system/filesys.h" -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) +static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx, const struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *desc, struct registry_key **result) { char *path; int ret; @@ -35,7 +35,7 @@ static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, return WERR_INVALID_PARAM; } -static WERROR reg_dir_del_key(struct registry_key *k, const char *name) +static WERROR reg_dir_del_key(const struct registry_key *k, const char *name) { char *child = talloc_asprintf(NULL, "%s/%s", (char *)k->backend_data, name); WERROR ret; @@ -47,7 +47,7 @@ static WERROR reg_dir_del_key(struct registry_key *k, const char *name) return ret; } -static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, struct registry_key *p, const char *name, struct registry_key **subkey) +static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, const struct registry_key *p, const char *name, struct registry_key **subkey) { DIR *d; char *fullpath, *unixpath; @@ -76,7 +76,7 @@ static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, struct registry_key *p, cons return WERR_OK; } -static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_key **key) +static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *k, int idx, struct registry_key **key) { struct dirent *e; char *fullpath = k->backend_data; diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index f51c02a286..469961dfb4 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -112,7 +112,7 @@ static int reg_close_ldb_key (void *data) return 0; } -static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, struct registry_key *from, const char *path, const char *add) +static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const struct registry_key *from, const char *path, const char *add) { TALLOC_CTX *local_ctx; struct ldb_dn *ret = ldb_dn_new(mem_ctx); @@ -153,7 +153,7 @@ static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, struct registry_key * } -static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_key **subkey) +static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, const struct registry_key *k, int idx, struct registry_key **subkey) { struct ldb_context *c = k->hive->backend_data; struct ldb_message_element *el; @@ -184,7 +184,7 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, return WERR_OK; } -static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_value **value) +static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct registry_key *k, int idx, struct registry_value **value) { struct ldb_context *c = k->hive->backend_data; struct ldb_key_data *kd = k->backend_data; @@ -208,7 +208,7 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, i return WERR_OK; } -static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const char *name, struct registry_key **key) +static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct registry_key *h, const char *name, struct registry_key **key) { struct ldb_context *c = h->hive->backend_data; struct ldb_message **msg; @@ -265,7 +265,7 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) return WERR_OK; } -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) +static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, const 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; @@ -293,7 +293,7 @@ static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, struct registry_key *parent, con return WERR_OK; } -static WERROR ldb_del_key (struct registry_key *key, const char *child) +static WERROR ldb_del_key (const struct registry_key *key, const char *child) { int ret; struct ldb_key_data *kd = key->backend_data; @@ -312,7 +312,7 @@ static WERROR ldb_del_key (struct registry_key *key, const char *child) return WERR_OK; } -static WERROR ldb_del_value (struct registry_key *key, const char *child) +static WERROR ldb_del_value (const struct registry_key *key, const char *child) { int ret; struct ldb_key_data *kd = key->backend_data; @@ -331,7 +331,7 @@ static WERROR ldb_del_value (struct registry_key *key, const char *child) return WERR_OK; } -static WERROR ldb_set_value (struct registry_key *parent, const char *name, uint32_t type, DATA_BLOB data) +static WERROR ldb_set_value (const struct registry_key *parent, const char *name, uint32_t type, DATA_BLOB data) { struct ldb_context *ctx = parent->hive->backend_data; struct ldb_message *msg; diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index e5c0221504..4d33f481e6 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -367,7 +367,7 @@ static uint32_t hbin_store_tdr_resize (struct regf_data *regf, tdr_push_fn_t pus return ret; } -static WERROR regf_num_subkeys (struct registry_key *key, uint32_t *count) +static WERROR regf_num_subkeys (const struct registry_key *key, uint32_t *count) { struct nk_block *nk = key->backend_data; @@ -376,7 +376,7 @@ static WERROR regf_num_subkeys (struct registry_key *key, uint32_t *count) return WERR_OK; } -static WERROR regf_num_values (struct registry_key *key, uint32_t *count) +static WERROR regf_num_values (const struct registry_key *key, uint32_t *count) { struct nk_block *nk = key->backend_data; @@ -415,7 +415,7 @@ static struct registry_key *regf_get_key (TALLOC_CTX *ctx, struct regf_data *reg return ret; } -static WERROR regf_get_value (TALLOC_CTX *ctx, struct registry_key *key, int idx, struct registry_value **ret) +static WERROR regf_get_value (TALLOC_CTX *ctx, const struct registry_key *key, int idx, struct registry_value **ret) { struct nk_block *nk = key->backend_data; struct vk_block *vk; @@ -468,7 +468,7 @@ static WERROR regf_get_value (TALLOC_CTX *ctx, struct registry_key *key, int idx return WERR_OK; } -static WERROR regf_get_subkey (TALLOC_CTX *ctx, struct registry_key *key, int idx, struct registry_key **ret) +static WERROR regf_get_subkey (TALLOC_CTX *ctx, const struct registry_key *key, int idx, struct registry_key **ret) { DATA_BLOB data; struct nk_block *nk = key->backend_data; @@ -522,13 +522,13 @@ static WERROR regf_get_subkey (TALLOC_CTX *ctx, struct registry_key *key, int id } -static WERROR regf_set_sec_desc (struct registry_key *key, struct security_descriptor *sec_desc) +static WERROR regf_set_sec_desc (const struct registry_key *key, const struct security_descriptor *sec_desc) { /* FIXME */ return WERR_NOT_SUPPORTED; } -static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, struct registry_key *key, struct security_descriptor **sd) +static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, struct security_descriptor **sd) { struct nk_block *nk = key->backend_data; struct sk_block sk; @@ -588,14 +588,14 @@ static uint32_t lf_add_entry (struct regf_data *regf, uint32_t list_offset, cons return ret; } -static WERROR regf_del_value (struct registry_key *parent, const char *name) +static WERROR regf_del_value (const struct registry_key *parent, const char *name) { /* FIXME */ return WERR_NOT_SUPPORTED; } -static WERROR regf_del_key (struct registry_key *parent, const char *name) +static WERROR regf_del_key (const struct registry_key *parent, const char *name) { struct nk_block *nk = parent->backend_data; @@ -609,7 +609,7 @@ static WERROR regf_del_key (struct registry_key *parent, const char *name) return WERR_NOT_SUPPORTED; } -static WERROR regf_add_key (TALLOC_CTX *ctx, struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *sec_desc, struct registry_key **ret) +static WERROR regf_add_key (TALLOC_CTX *ctx, const struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *sec_desc, struct registry_key **ret) { struct nk_block *parent_nk = parent->backend_data, nk; struct regf_data *regf = parent->hive->backend_data; @@ -645,7 +645,7 @@ static WERROR regf_add_key (TALLOC_CTX *ctx, struct registry_key *parent, const return WERR_OK; } -static WERROR regf_set_value (struct registry_key *key, const char *name, uint32_t type, DATA_BLOB data) +static WERROR regf_set_value (const struct registry_key *key, const char *name, uint32_t type, const DATA_BLOB data) { /* FIXME */ diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index a00accc6be..1e9fff4d7c 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -81,7 +81,7 @@ static struct { { 0, NULL } }; -static WERROR rpc_query_key(struct registry_key *k); +static WERROR rpc_query_key(const struct registry_key *k); static WERROR rpc_get_predefined_key (struct registry_context *ctx, uint32_t hkey_type, struct registry_key **k) { @@ -137,7 +137,7 @@ static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) } #endif -static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const char *name, struct registry_key **key) +static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, const struct registry_key *h, const char *name, struct registry_key **key) { struct rpc_key_data *mykeydata; struct winreg_OpenKey r; @@ -163,7 +163,7 @@ static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const ch return r.out.result; } -static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_value **value) +static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *parent, int n, struct registry_value **value) { struct rpc_key_data *mykeydata = parent->backend_data; WERROR error; @@ -211,7 +211,7 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *p return r.out.result; } -static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_key **subkey) +static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *parent, int n, struct registry_key **subkey) { struct winreg_EnumKey r; struct rpc_key_data *mykeydata = parent->backend_data; @@ -242,7 +242,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, struct security_descriptor *sec, struct registry_key **key) +static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, const 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; @@ -272,7 +272,7 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, cons return r.out.result; } -static WERROR rpc_query_key(struct registry_key *k) +static WERROR rpc_query_key(const struct registry_key *k) { NTSTATUS status; struct winreg_QueryInfoKey r; @@ -300,7 +300,7 @@ static WERROR rpc_query_key(struct registry_key *k) return r.out.result; } -static WERROR rpc_del_key(struct registry_key *parent, const char *name) +static WERROR rpc_del_key(const struct registry_key *parent, const char *name) { NTSTATUS status; struct rpc_key_data *mykeydata = parent->backend_data; @@ -317,7 +317,7 @@ static WERROR rpc_del_key(struct registry_key *parent, const char *name) return r.out.result; } -static WERROR rpc_num_values(struct registry_key *key, uint32_t *count) +static WERROR rpc_num_values(const struct registry_key *key, uint32_t *count) { struct rpc_key_data *mykeydata = key->backend_data; WERROR error; @@ -331,7 +331,7 @@ static WERROR rpc_num_values(struct registry_key *key, uint32_t *count) return WERR_OK; } -static WERROR rpc_num_subkeys(struct registry_key *key, uint32_t *count) +static WERROR rpc_num_subkeys(const struct registry_key *key, uint32_t *count) { struct rpc_key_data *mykeydata = key->backend_data; WERROR error; diff --git a/source4/lib/registry/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95.c index 03460052da..d5ce0e33f8 100644 --- a/source4/lib/registry/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95.c @@ -267,7 +267,7 @@ static WERROR w95_open_reg (struct registry_hive *h, struct registry_key **root) return WERR_OK; } -static WERROR w95_get_subkey_by_index (TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_key **key) +static WERROR w95_get_subkey_by_index (TALLOC_CTX *mem_ctx, const struct registry_key *parent, int n, struct registry_key **key) { CREG *creg = parent->hive->backend_data; RGKN_KEY *rgkn_key = parent->backend_data; @@ -303,7 +303,7 @@ static WERROR w95_get_subkey_by_index (TALLOC_CTX *mem_ctx, struct registry_key return WERR_NO_MORE_ITEMS; } -static WERROR w95_num_values(struct registry_key *k, uint32_t *count) +static WERROR w95_num_values(const struct registry_key *k, uint32_t *count) { RGKN_KEY *rgkn_key = k->backend_data; RGDB_KEY *rgdb_key = LOCN_RGDB_KEY((CREG *)k->hive->backend_data, rgkn_key->id.rgdb, rgkn_key->id.id); @@ -315,7 +315,7 @@ static WERROR w95_num_values(struct registry_key *k, uint32_t *count) return WERR_OK; } -static WERROR w95_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_value **value) +static WERROR w95_get_value_by_id(TALLOC_CTX *mem_ctx, const struct registry_key *k, int idx, struct registry_value **value) { RGKN_KEY *rgkn_key = k->backend_data; DWORD i; diff --git a/source4/lib/registry/regf.idl b/source4/lib/registry/regf.idl index 85a879cc36..dcb1df039b 100644 --- a/source4/lib/registry/regf.idl +++ b/source4/lib/registry/regf.idl @@ -51,7 +51,7 @@ interface regf } regf_hdr; /* - hbin probably means hive-bin (what bin stands for I don't know) + hbin probably means hive-bin (i.e. hive-container) This block is always a multiple of 4kb in size. */ diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index e843e1a0be..69f3606736 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -43,24 +43,26 @@ #define REGISTRY_INTERFACE_VERSION 1 /* structure to store the registry handles */ -struct registry_key { - char *name; /* Name of the key */ - const char *path; /* Full path to the key */ - char *class_name; /* Name of key class */ - NTTIME last_mod; /* Time last modified */ +struct registry_key +{ + char *name; + const char *path; + char *class_name; + NTTIME last_mod; struct registry_hive *hive; void *backend_data; }; -struct registry_value { +struct registry_value +{ char *name; unsigned int data_type; DATA_BLOB data; }; /* FIXME */ -typedef void (*key_notification_function) (void); -typedef void (*value_notification_function) (void); +typedef void (*reg_key_notification_function) (void); +typedef void (*reg_value_notification_function) (void); /* * Container for function pointers to enumeration routines @@ -85,38 +87,39 @@ struct hive_operations { WERROR (*open_hive) (struct registry_hive *, struct registry_key **); /* Or this one */ - WERROR (*open_key) (TALLOC_CTX *, struct registry_key *, const char *name, struct registry_key **); + WERROR (*open_key) (TALLOC_CTX *, const struct registry_key *, const char *name, struct registry_key **); - WERROR (*num_subkeys) (struct registry_key *, uint32_t *count); - WERROR (*num_values) (struct registry_key *, uint32_t *count); - WERROR (*get_subkey_by_index) (TALLOC_CTX *, struct registry_key *, int idx, struct registry_key **); + WERROR (*num_subkeys) (const struct registry_key *, uint32_t *count); + WERROR (*num_values) (const struct registry_key *, uint32_t *count); + WERROR (*get_subkey_by_index) (TALLOC_CTX *, const struct registry_key *, int idx, struct registry_key **); /* Can not contain more then one level */ - WERROR (*get_subkey_by_name) (TALLOC_CTX *, struct registry_key *, const char *name, struct registry_key **); - WERROR (*get_value_by_index) (TALLOC_CTX *, struct registry_key *, int idx, struct registry_value **); + WERROR (*get_subkey_by_name) (TALLOC_CTX *, const struct registry_key *, const char *name, struct registry_key **); + WERROR (*get_value_by_index) (TALLOC_CTX *, const struct registry_key *, int idx, struct registry_value **); /* Can not contain more then one level */ - WERROR (*get_value_by_name) (TALLOC_CTX *, struct registry_key *, const char *name, struct registry_value **); + WERROR (*get_value_by_name) (TALLOC_CTX *, const struct registry_key *, const char *name, struct registry_value **); /* Security control */ - WERROR (*key_get_sec_desc) (TALLOC_CTX *, struct registry_key *, struct security_descriptor **); - WERROR (*key_set_sec_desc) (struct registry_key *, struct security_descriptor *); + WERROR (*key_get_sec_desc) (TALLOC_CTX *, const struct registry_key *, struct security_descriptor **); + WERROR (*key_set_sec_desc) (const struct registry_key *, const 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); + WERROR (*request_key_change_notify) (const struct registry_key *, reg_key_notification_function); + WERROR (*request_value_change_notify) (const struct registry_value *, reg_value_notification_function); /* Key management */ - 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 *); + WERROR (*add_key)(TALLOC_CTX *, const struct registry_key *, const char *name, uint32_t access_mask, struct security_descriptor *, struct registry_key **); + WERROR (*del_key)(const struct registry_key *, const char *name); + WERROR (*flush_key) (const struct registry_key *); /* Value management */ - WERROR (*set_value)(struct registry_key *, const char *name, uint32_t type, DATA_BLOB data); - WERROR (*del_value)(struct registry_key *, const char *valname); + WERROR (*set_value)(const struct registry_key *, const char *name, uint32_t type, const DATA_BLOB data); + WERROR (*del_value)(const struct registry_key *, const char *valname); }; -struct registry_hive { +struct registry_hive +{ const struct hive_operations *functions; struct registry_key *root; void *backend_data; -- cgit From 86acf90e4335f79cd34e400d687930d922332d8f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 17 Sep 2005 13:08:49 +0000 Subject: r10294: Generate Makefile directly rather then thru Makefile.in. Autoconf substitution variables are now no longer used. This is one more step towards a (hopefully) perl-based configure (This used to be commit 6f9956a1dd870c0669c288b0fe72b7b1c8773dd0) --- source4/lib/registry/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 4cf73bf66a..87e0779007 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -18,7 +18,7 @@ INIT_OBJ_FILES = lib/registry/tdr_regf.o lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c lib/registry/tdr_regf.c: lib/registry/regf.idl - @CPP="$(CPP)" $(PERL) pidl/pidl --header --outputdir=lib/registry --tdr-header --tdr-parser -- lib/registry/regf.idl + @CPP="$(CPP)" pidl/pidl $(PIDL_ARGS) --header --outputdir=lib/registry --tdr-header --tdr-parser -- lib/registry/regf.idl ################################################ # Start MODULE registry_w95 -- cgit From 523034b9fbc1841ed63137e3d8965d52997af4e6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 19 Sep 2005 19:19:10 +0000 Subject: r10323: Add first bits required for getting compile with scons working. This does not work yet and can exist parallel with the existing build system. (This used to be commit 829568d75985e875e3363d76fb44270a0298c7f8) --- source4/lib/registry/SConscript | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 source4/lib/registry/SConscript (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/SConscript b/source4/lib/registry/SConscript new file mode 100644 index 0000000000..f63179283a --- /dev/null +++ b/source4/lib/registry/SConscript @@ -0,0 +1,5 @@ +Import('hostenv') +Import('talloc basic popt_common popt param') +registry = hostenv.StaticLibrary('registry', + [basic,talloc,'common/reg_interface.c','common/reg_util.c']) +hostenv.Program('regtree', ['tools/regtree.c',registry,talloc,basic,popt_common,popt,param]) -- cgit From 96745cbfc0e3386fa32631daa45b4096a1f80e61 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 19 Sep 2005 21:44:36 +0000 Subject: r10328: Add more emacs python-mode markers. (This used to be commit 540a3649e88690e829c17d79ecdccdc9ed464845) --- source4/lib/registry/SConscript | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/SConscript b/source4/lib/registry/SConscript index f63179283a..4ea4301105 100644 --- a/source4/lib/registry/SConscript +++ b/source4/lib/registry/SConscript @@ -1,3 +1,5 @@ +# tastes like -*- python -*- + Import('hostenv') Import('talloc basic popt_common popt param') registry = hostenv.StaticLibrary('registry', -- cgit From 6812c73534001d2dd05a9a74358d2b6d0029f1a7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 20 Sep 2005 11:59:03 +0000 Subject: r10348: Add scons scripts for remaining subsystems. Most subsystems build now, but final linking still fails (as does generating files asn1, et, idl and proto files) (This used to be commit 4f0d7f75b99c7f4388d8acb0838577d86baf68b5) --- source4/lib/registry/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/SConscript b/source4/lib/registry/SConscript index 4ea4301105..65aeb5b17a 100644 --- a/source4/lib/registry/SConscript +++ b/source4/lib/registry/SConscript @@ -1,6 +1,6 @@ +Import('hostenv') # tastes like -*- python -*- -Import('hostenv') Import('talloc basic popt_common popt param') registry = hostenv.StaticLibrary('registry', [basic,talloc,'common/reg_interface.c','common/reg_util.c']) -- cgit From 8db177b652cdede2f509d6c96d1c99e875c2d284 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 20 Sep 2005 22:10:40 +0000 Subject: r10366: More scons fixes. Building et, asn1, lex and yacc files sort-of works now (This used to be commit 22f18a84242e5e68a2d57b6d7ff77c089ee7434a) --- source4/lib/registry/SConscript | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/SConscript b/source4/lib/registry/SConscript index 65aeb5b17a..a90557532b 100644 --- a/source4/lib/registry/SConscript +++ b/source4/lib/registry/SConscript @@ -1,7 +1,12 @@ -Import('hostenv') +Import('hostenv paths') # tastes like -*- python -*- Import('talloc basic popt_common popt param') registry = hostenv.StaticLibrary('registry', [basic,talloc,'common/reg_interface.c','common/reg_util.c']) -hostenv.Program('regtree', ['tools/regtree.c',registry,talloc,basic,popt_common,popt,param]) +regtree = hostenv.Program('regtree', ['tools/regtree.c',registry,talloc,basic,popt_common,popt,param]) +regshell = hostenv.Program('regshell', ['tools/regshell.c',registry,talloc,basic,popt_common,popt,param]) +regpatch = hostenv.Program('regpatch', ['tools/regpatch.c',registry,talloc,basic,popt_common,popt,param]) +regdiff = hostenv.Program('regdiff', ['tools/regdiff.c',registry,talloc,basic,popt_common,popt,param]) + +hostenv.Install(paths['BINDIR'], [regtree,regshell,regpatch,regdiff]) -- cgit From 4be0ae794e4af2354d678fddd7bf1e822ffa9148 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 23 Sep 2005 16:32:52 +0000 Subject: r10456: More SCons fixes: - Add framework for fallback generating code - Move pread / pwrite replacement functions to libreplace - Support pidl builds correctly - Support asn1 builds correctly - Move OS-specific checks to lib/replace/SConscript (This used to be commit fbbfad0a1f7dedbf48e835a864f8285f283d72f3) --- source4/lib/registry/SConscript | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/SConscript b/source4/lib/registry/SConscript index a90557532b..aa2d587260 100644 --- a/source4/lib/registry/SConscript +++ b/source4/lib/registry/SConscript @@ -9,4 +9,12 @@ regshell = hostenv.Program('regshell', ['tools/regshell.c',registry,talloc,basic regpatch = hostenv.Program('regpatch', ['tools/regpatch.c',registry,talloc,basic,popt_common,popt,param]) regdiff = hostenv.Program('regdiff', ['tools/regdiff.c',registry,talloc,basic,popt_common,popt,param]) +hostenv.StaticLibrary('reg_backend_dir.c') +hostenv.StaticLibrary('reg_backend_gconf.c') +hostenv.StaticLibrary('reg_backend_ldb.c') +hostenv.StaticLibrary('reg_backend_nt4', ['reg_backend_nt4.c',hostenv.TdrMarshaller('regf.idl')]) +hostenv.StaticLibrary('reg_backend_rpc.c') +hostenv.StaticLibrary('reg_backend_w95.c') +hostenv.StaticLibrary('reg_backend_wine.c') + hostenv.Install(paths['BINDIR'], [regtree,regshell,regpatch,regdiff]) -- cgit From 5058f4b9e82ca8b9f2405930db3a46b8c37f06ed Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 28 Sep 2005 18:18:09 +0000 Subject: r10586: Add MergedObject() builder. Default to Library() rather then StaticLibrary() (This used to be commit b53313dc517986c69a4e4cb8fe3885b696f8faa1) --- source4/lib/registry/SConscript | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/SConscript b/source4/lib/registry/SConscript index aa2d587260..f2fa526a67 100644 --- a/source4/lib/registry/SConscript +++ b/source4/lib/registry/SConscript @@ -2,19 +2,19 @@ Import('hostenv paths') # tastes like -*- python -*- Import('talloc basic popt_common popt param') -registry = hostenv.StaticLibrary('registry', +registry = hostenv.Library('registry', [basic,talloc,'common/reg_interface.c','common/reg_util.c']) regtree = hostenv.Program('regtree', ['tools/regtree.c',registry,talloc,basic,popt_common,popt,param]) regshell = hostenv.Program('regshell', ['tools/regshell.c',registry,talloc,basic,popt_common,popt,param]) regpatch = hostenv.Program('regpatch', ['tools/regpatch.c',registry,talloc,basic,popt_common,popt,param]) regdiff = hostenv.Program('regdiff', ['tools/regdiff.c',registry,talloc,basic,popt_common,popt,param]) -hostenv.StaticLibrary('reg_backend_dir.c') -hostenv.StaticLibrary('reg_backend_gconf.c') -hostenv.StaticLibrary('reg_backend_ldb.c') -hostenv.StaticLibrary('reg_backend_nt4', ['reg_backend_nt4.c',hostenv.TdrMarshaller('regf.idl')]) -hostenv.StaticLibrary('reg_backend_rpc.c') -hostenv.StaticLibrary('reg_backend_w95.c') -hostenv.StaticLibrary('reg_backend_wine.c') +hostenv.Library('reg_backend_dir.c') +hostenv.Library('reg_backend_gconf.c') +hostenv.Library('reg_backend_ldb.c') +hostenv.Library('reg_backend_nt4', ['reg_backend_nt4.c',hostenv.TdrMarshaller('regf.idl')]) +hostenv.Library('reg_backend_rpc.c') +hostenv.Library('reg_backend_w95.c') +hostenv.Library('reg_backend_wine.c') hostenv.Install(paths['BINDIR'], [regtree,regshell,regpatch,regdiff]) -- cgit From 4abb4797613868e518baafb5f3618e78f67ac05c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 28 Sep 2005 19:56:21 +0000 Subject: r10588: Remove more unused files, macros (This used to be commit d2f80c0457f7404b2cac9df59a400130e9ad025f) --- source4/lib/registry/tools/regpatch.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 887f53df37..98e6c0ff5d 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -156,10 +156,13 @@ static void print_line(struct cmd_line *cl) */ static struct cmd_line *get_cmd_line(int fd) { - CMD_LINE *cl = smb_xmalloc_p(CMD_LINE); + CMD_LINE *cl = malloc_p(CMD_LINE); int i = 0, rc; uint8_t ch; + if (!cl) + return NULL; + cl->len = INIT_ALLOC; /* @@ -447,7 +450,9 @@ static CMD *regedit4_get_cmd(int fd) struct cmd_line *cl = NULL; struct val_spec_list *vl = NULL; - cmd = smb_xmalloc_p(struct command_s); + cmd = malloc_p(struct command_s); + if (!cmd) + return NULL; cmd->cmd = CMD_NONE; cmd->key = NULL; @@ -490,7 +495,9 @@ static CMD *regedit4_get_cmd(int fd) * There could be a \ on the end which we need to * handle at some time */ - vl = smb_xmalloc_p(struct val_spec_list); + vl = malloc_p(struct val_spec_list); + if (!vl) + return NULL; vl->next = NULL; vl->val = NULL; vl->name = parse_value(cl, &vl->type, &vl->val); @@ -609,7 +616,9 @@ static CMD_FILE *cmd_file_create(const char *file) return NULL; } - tmp = smb_xmalloc_p(CMD_FILE); + tmp = malloc_p(CMD_FILE); + if (!tmp) + return NULL; /* * Let's fill in some of the fields; -- cgit From 5e7a0fb5349422cfb782c0348f98505011d27391 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 29 Sep 2005 11:51:06 +0000 Subject: r10604: Put in the new registry "patchfile" code (similar to ldif for LDB); not finished yet. (This used to be commit b405b27ba4bf4ddbaff9ca58926d94d1b2fd09f6) --- source4/lib/registry/TODO | 5 +- source4/lib/registry/common/reg_util.c | 40 +- source4/lib/registry/config.mk | 3 +- source4/lib/registry/registry.h | 23 + source4/lib/registry/tools/regdiff.c | 128 +----- source4/lib/registry/tools/regpatch.c | 741 +-------------------------------- source4/lib/registry/tools/regshell.c | 6 +- 7 files changed, 72 insertions(+), 874 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/TODO b/source4/lib/registry/TODO index 3f48d031e1..518edf6795 100644 --- a/source4/lib/registry/TODO +++ b/source4/lib/registry/TODO @@ -24,12 +24,11 @@ reg_backend_wine.c: regshell: - support for security descriptors - regdiff: - - fix - gregedit.c: - support for editing values / adding values / deleting values - support for adding/deleting keys - support for security descriptors - pass parsed paths around rather then strings (i.e. just a list of strings) +- integrate various registry tools ? +- finish new patchfile code diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index ae30839cca..75f9d3cf00 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -46,27 +46,27 @@ const char *str_regtype(int type) return "Unknown"; } -char *reg_val_data_string(TALLOC_CTX *mem_ctx, struct registry_value *v) +char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, DATA_BLOB *data) { char *ret = NULL; - if(v->data.length == 0) return talloc_strdup(mem_ctx, ""); + if(data->length == 0) return talloc_strdup(mem_ctx, ""); - switch (v->data_type) { + switch (type) { case REG_EXPAND_SZ: case REG_SZ: - convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, v->data.data, v->data.length, (void **)&ret); + convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, data->data, data->length, (void **)&ret); return ret; case REG_BINARY: - ret = data_blob_hex_string(mem_ctx, &v->data); + ret = data_blob_hex_string(mem_ctx, data); return ret; case REG_DWORD: - if (*(int *)v->data.data == 0) + if (*(int *)data->data == 0) return talloc_strdup(mem_ctx, "0"); - return talloc_asprintf(mem_ctx, "0x%x", *(int *)v->data.data); + return talloc_asprintf(mem_ctx, "0x%x", *(int *)data->data); case REG_MULTI_SZ: /* FIXME */ @@ -81,47 +81,51 @@ char *reg_val_data_string(TALLOC_CTX *mem_ctx, struct registry_value *v) 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)); + return talloc_asprintf(mem_ctx, "%s = %s : %s", val->name?val->name:"", str_regtype(val->data_type), reg_val_data_string(mem_ctx, val->data_type, &val->data)); } -BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, struct registry_value **value) +BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data) { int i; - *value = talloc(mem_ctx, struct registry_value); - (*value)->data_type = -1; + *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; + *type = reg_value_types[i].id; break; } } - if ((*value)->data_type == -1) + if (*type == -1) return False; /* Convert data appropriately */ - switch ((*value)->data_type) + switch (*type) { case REG_SZ: case REG_EXPAND_SZ: - (*value)->data.length = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, data_str, strlen(data_str), (void **)&(*value)->data.data); + data->length = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, data_str, strlen(data_str), (void **)&data->data); break; case REG_DWORD: { uint32_t tmp = strtol(data_str, NULL, 0); - (*value)->data = data_blob_talloc(mem_ctx, &tmp, 4); + *data = data_blob_talloc(mem_ctx, &tmp, 4); } break; case REG_NONE: - ZERO_STRUCT((*value)->data); + ZERO_STRUCT(data); break; + case REG_BINARY: + *data = strhex_to_data_blob(data_str); + talloc_steal(mem_ctx, data->data); + break; + default: - case REG_BINARY: /* FIXME */ + /* FIXME */ return False; } return True; diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 87e0779007..8a579d4564 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -83,7 +83,8 @@ INIT_OBJ_FILES = \ lib/registry/common/reg_interface.o ADD_OBJ_FILES = \ lib/registry/common/reg_util.o \ - lib/registry/reg_samba.o + lib/registry/reg_samba.o \ + lib/registry/patchfile.o REQUIRED_SUBSYSTEMS = \ LIBBASIC # End MODULE registry_ldb diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 69f3606736..ebfb2caf5c 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -138,4 +138,27 @@ struct reg_init_function_entry { struct reg_init_function_entry *prev, *next; }; +struct reg_diff_value +{ + char *name; + enum { REG_DIFF_DEL_VAL, REG_DIFF_SET_VAL } changetype; + uint32_t type; + DATA_BLOB data; +}; + +struct reg_diff_key +{ + char *name; + enum { REG_DIFF_CHANGE_KEY, REG_DIFF_DEL_KEY } changetype; + uint32_t numvalues; + struct reg_diff_value *values; +}; + +struct reg_diff +{ + char *format; + uint32_t numkeys; + struct reg_diff_key *keys; +}; + #endif /* _REGISTRY_H */ diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 3d8201330e..92fe53ff67 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. simple registry frontend - Copyright (C) Jelmer Vernooij 2004 + Copyright (C) Jelmer Vernooij 2004-2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,101 +24,15 @@ #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" -static void writediff(struct registry_key *oldkey, struct registry_key *newkey, FILE *out) -{ - int i; - struct registry_key *t1, *t2; - struct registry_value *v1, *v2; - WERROR error1, error2; - TALLOC_CTX *mem_ctx = talloc_init("writediff"); - - for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_subkey_by_index(mem_ctx, oldkey, i, &t1)); i++) { - error2 = reg_key_get_subkey_by_name(mem_ctx, newkey, t1->name, &t2); - if(W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - fprintf(out, "-%s\n", t1->path+1); - } else if(!W_ERROR_IS_OK(error2)) { - DEBUG(0, ("Error occured while getting subkey by name: %d\n", W_ERROR_V(error2))); - } - } - - talloc_free(mem_ctx); - - if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while getting subkey by index: %d\n", W_ERROR_V(error1))); - return; - } - - mem_ctx = talloc_init("writediff"); - - for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_subkey_by_index(mem_ctx, newkey, i, &t1)); i++) { - error2 = reg_key_get_subkey_by_name(mem_ctx, oldkey, t1->name, &t2); - if(W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - fprintf(out, "\n[%s]\n", t1->path+1); - } else if(!W_ERROR_IS_OK(error2)) { - DEBUG(0, ("Error occured while getting subkey by name: %d\n", W_ERROR_V(error2))); - } - writediff(t2, t1, out); - } - - talloc_free(mem_ctx); - - if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while getting subkey by index: %d\n", W_ERROR_V(error1))); - return; - } - - - mem_ctx = talloc_init("writediff"); - - for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(mem_ctx, newkey, i, &v1)); i++) { - error2 = reg_key_get_value_by_name(mem_ctx, oldkey, v1->name, &v2); - if ((W_ERROR_IS_OK(error2) && data_blob_equal(&v1->data, &v2->data)) - || W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - fprintf(out, "\"%s\"=%s:%s\n", v1->name, str_regtype(v1->data_type), reg_val_data_string(mem_ctx, v1)); - } - - if(!W_ERROR_IS_OK(error2) && !W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - DEBUG(0, ("Error occured while getting value by name: %d\n", W_ERROR_V(error2))); - } - } - - talloc_free(mem_ctx); - - if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while getting value by index: %d\n", W_ERROR_V(error1))); - return; - } - - mem_ctx = talloc_init("writediff"); - - for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(mem_ctx, oldkey, i, &v1)); i++) { - error2 = reg_key_get_value_by_name(mem_ctx, newkey, v1->name, &v2); - if(W_ERROR_IS_OK(error2)) { - } else if(W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - fprintf(out, "\"%s\"=-\n", v1->name); - } else { - DEBUG(0, ("Error occured while getting value by name: %d\n", W_ERROR_V(error2))); - } - } - - talloc_free(mem_ctx); - - if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while getting value by index: %d\n", W_ERROR_V(error1))); - return; - } -} - - int main(int argc, char **argv) +int main(int argc, char **argv) { int opt; poptContext pc; char *outputfile = NULL; - FILE *fd = stdout; struct registry_context *h1 = NULL, *h2 = NULL; int from_null = 0; - int i; - WERROR error, error2; + WERROR error; + struct reg_diff *diff; struct poptOption long_options[] = { POPT_AUTOHELP {"output", 'o', POPT_ARG_STRING, &outputfile, 'o', "output file to use", NULL }, @@ -159,37 +73,13 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey, poptFreeContext(pc); - if(outputfile) { - fd = fopen(outputfile, "w+"); - if(!fd) { - fprintf(stderr, "Unable to open '%s'\n", outputfile); - return 1; - } - } - - fprintf(fd, "REGEDIT4\n\n"); - fprintf(fd, "; Generated using regdiff, part of Samba\n"); - - error2 = error = WERR_OK; - - for(i = HKEY_CLASSES_ROOT; i <= HKEY_PERFORMANCE_NLSTEXT; i++) { - struct registry_key *r1, *r2; - error = reg_get_predefined_key(h1, i, &r1); - if (!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Unable to open hive %s for backend 1\n", reg_get_predef_name(i))); - continue; - } - - error = reg_get_predefined_key(h2, i, &r2); - if (!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Unable to open hive %s for backend 2\n", reg_get_predef_name(i))); - continue; - } - - writediff(r1, r2, fd); + diff = reg_generate_diff(NULL, h1, h2); + if (!diff) { + fprintf(stderr, "Unable to generate diff between keys\n"); + return -1; } - fclose(fd); + reg_diff_save(diff, outputfile); return 0; } diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 98e6c0ff5d..eca14741a5 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -2,8 +2,7 @@ Unix SMB/CIFS implementation. simple registry frontend - Copyright (C) 2002, Richard Sharpe, rsharpe@richardsharpe.com - Copyright (C) 2004, Jelmer Vernooij, jelmer@samba.org + Copyright (C) 2004-2005 Jelmer Vernooij, jelmer@samba.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,737 +26,14 @@ #include "system/filesys.h" #include "librpc/gen_ndr/winreg.h" -/* - * Routines to parse a REGEDIT4 file - * - * The file consists of: - * - * REGEDIT4 - * \[[-]key-path\]\n - * * - * - * Format: - * [cmd:]name=type:value - * - * cmd = a|d|c|add|delete|change|as|ds|cs - * - * There can be more than one key-path and value-spec. - * - * Since we want to support more than one type of file format, we - * construct a command-file structure that keeps info about the command file - */ - -#define FMT_UNREC -1 -#define FMT_REGEDIT4 0 -#define FMT_EDITREG1_1 1 - -#define FMT_STRING_REGEDIT4 "REGEDIT4" -#define FMT_STRING_EDITREG1_0 "EDITREG1.0" - -#define CMD_NONE 0 -#define CMD_ADD_KEY 1 -#define CMD_DEL_KEY 2 - -#define CMD_KEY 1 -#define CMD_VAL 2 - -typedef struct val_spec_list { - struct val_spec_list *next; - char *name; - int type; - char *val; /* Kept as a char string, really? */ -} VAL_SPEC_LIST; - -typedef struct command_s { - int cmd; - char *key; - int val_count; - VAL_SPEC_LIST *val_spec_list, *val_spec_last; -} CMD; - -typedef struct cmd_line { - int len, line_len; - char *line; -} CMD_LINE; - -static void free_val_spec_list(VAL_SPEC_LIST *vl) -{ - if (!vl) return; - if (vl->name) free(vl->name); - if (vl->val) free(vl->val); - free(vl); - -} - -/* - * Some routines to handle lines of info in the command files - */ -static void skip_to_eol(int fd) -{ - int rc; - char ch = 0; - - while ((rc = read(fd, &ch, 1)) == 1) { - if (ch == 0x0A) return; - } - if (rc < 0) { - DEBUG(0, ("Could not read file descriptor: %d, %s\n", - fd, strerror(errno))); - exit(1); - } -} - -static void free_cmd(CMD *cmd) -{ - if (!cmd) return; - - while (cmd->val_spec_list) { - VAL_SPEC_LIST *tmp; - - tmp = cmd->val_spec_list; - cmd->val_spec_list = tmp->next; - free(tmp); - } - - free(cmd); - -} - -static void free_cmd_line(CMD_LINE *cmd_line) -{ - if (cmd_line) { - if (cmd_line->line) free(cmd_line->line); - free(cmd_line); - } -} - -static void print_line(struct cmd_line *cl) -{ - char *pl; - - if (!cl) return; - - pl = smb_xmalloc(cl->line_len + 1); - - strncpy(pl, cl->line, cl->line_len); - pl[cl->line_len] = 0; - - fprintf(stdout, "%s\n", pl); - free(pl); -} - -#define INIT_ALLOC 10 - -/* - * Read a line from the input file. - * NULL returned when EOF and no chars read - * Otherwise we return a cmd_line * - * Exit if other errors - */ -static struct cmd_line *get_cmd_line(int fd) -{ - CMD_LINE *cl = malloc_p(CMD_LINE); - int i = 0, rc; - uint8_t ch; - - if (!cl) - return NULL; - - cl->len = INIT_ALLOC; - - /* - * Allocate some space for the line. We extend later if needed. - */ - - cl->line = (char *)smb_xmalloc(INIT_ALLOC); - - /* - * Now read in the chars to EOL. Don't store the EOL in the - * line. What about CR? - */ - - while ((rc = read(fd, &ch, 1)) == 1 && ch != '\n') { - if (ch == '\r') continue; /* skip CR */ - if (i == cl->len-1) { - /* - * Allocate some more memory - */ - if ((cl->line = realloc(cl->line, cl->len + INIT_ALLOC)) == NULL) { - DEBUG(0, ("Unable to realloc space for line: %s\n", - strerror(errno))); - exit(1); - } - cl->len += INIT_ALLOC; - } - cl->line[i] = ch; - i++; - } - - /* read 0 and we were at loc'n 0, return NULL */ - if (rc == 0 && i == 0) { - free_cmd_line(cl); - return NULL; - } - - cl->line[i] = '\0'; - cl->line_len = i; - - return cl; - -} - -/* - * parse_value: parse out a value. We pull it apart as: - * - * ::= =: - * - * ::= char-string-without-spaces | '"' char-string '"' - * - * If it parsed OK, return the as a string, and the - * value type and value-string in parameters. - * - * The value name can be empty. There can only be one empty name in - * a list of values. A value of - removes the value entirely. - */ - -static char *parse_name(char *nstr) -{ - int len = 0, start = 0; - if (!nstr) return NULL; - - len = strlen(nstr); - - while (len && nstr[len - 1] == ' ') len--; - - nstr[len] = 0; /* Trim any spaces ... if there were none, doesn't matter */ - - /* - * Beginning and end should be '"' or neither should be so - */ - if ((nstr[0] == '"' && nstr[len - 1] != '"') || - (nstr[0] != '"' && nstr[len - 1] == '"')) - return NULL; - - if (nstr[0] == '"') { - start = 1; - len -= 2; - } - - return strndup(&nstr[start], len); -} - -static int parse_value_type(char *tstr) -{ - int len = strlen(tstr); - - while (len && tstr[len - 1] == ' ') len--; - tstr[len] = 0; - - if (strcmp(tstr, "REG_DWORD") == 0) - return REG_DWORD; - else if (strcmp(tstr, "dword") == 0) - return REG_DWORD; - else if (strcmp(tstr, "REG_EXPAND_SZ") == 0) - return REG_EXPAND_SZ; - else if (strcmp(tstr, "REG_BIN") == 0) - return REG_BINARY; - else if (strcmp(tstr, "REG_SZ") == 0) - return REG_SZ; - else if (strcmp(tstr, "REG_MULTI_SZ") == 0) - return REG_MULTI_SZ; - else if (strcmp(tstr, "-") == 0) - return REG_DELETE; - - return 0; -} - -static char *parse_val_str(char *vstr) -{ - - return strndup(vstr, strlen(vstr)); - -} - -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[0]) return NULL; - - p1 = strdup(cl->line); - /* FIXME: Better return codes etc ... */ - if (!p1) return NULL; - p2 = strchr(p1, '='); - if (!p2) return NULL; - - *p2 = 0; p2++; /* Split into two strings at p2 */ - - /* Now, parse the name ... */ - - nstr = parse_name(p1); - if (!nstr) goto error; - - /* Now, split the remainder and parse on type and val ... */ - - tstr = p2; - while (*tstr == ' ') tstr++; /* Skip leading white space */ - p2 = strchr(p2, ':'); - - if (p2) { - *p2 = 0; p2++; /* split on the : */ - } - - *vtype = parse_value_type(tstr); - - if (!vtype) goto error; - - if (!p2 || !*p2) return nstr; - - /* Now, parse the value string. It should return a newly malloc'd string */ - - while (*p2 == ' ') p2++; /* Skip leading space */ - vstr = parse_val_str(p2); - - if (!vstr) goto error; - - *val = vstr; - - return nstr; - - error: - if (p1) free(p1); - if (nstr) free(nstr); - if (vstr) free(vstr); - return NULL; -} - -/* - * Parse out a key. Look for a correctly formatted key [...] - * and whether it is a delete or add? A delete is signalled - * by a - in front of the key. - * Assumes that there are no leading and trailing spaces - */ - -static char *parse_key(struct cmd_line *cl, int *cmd) -{ - int start = 1; - char *tmp; - - if (cl->line[0] != '[' || - cl->line[cl->line_len - 1] != ']') return NULL; - if (cl->line_len == 2) return NULL; - *cmd = CMD_ADD_KEY; - if (cl->line[1] == '-') { - if (cl->line_len == 3) return NULL; - start = 2; - *cmd = CMD_DEL_KEY; - } - tmp = smb_xmalloc(cl->line_len - 1 - start + 1); - strncpy(tmp, &cl->line[start], cl->line_len - 1 - start); - tmp[cl->line_len - 1 - start] = 0; - return tmp; -} - -/* - * Parse a line to determine if we have a key or a value - * We only check for key or val ... - */ - -static int parse_line(struct cmd_line *cl) -{ - - if (!cl || cl->len == 0) return 0; - - if (cl->line[0] == '[') /* No further checking for now */ - return CMD_KEY; - else - return CMD_VAL; -} - -/* - * We seek to offset 0, read in the required number of bytes, - * and compare to the correct value. - * We then seek back to the original location - */ -static int regedit4_file_type(int fd) -{ - int cur_ofs = 0; - char desc[9]; - - cur_ofs = lseek(fd, 0, SEEK_CUR); /* Get current offset */ - if (cur_ofs < 0) { - DEBUG(0, ("Unable to get current offset: (%d) %s\n", cur_ofs, strerror(errno))); - exit(1); /* FIXME */ - } - - if (cur_ofs) { - lseek(fd, 0, SEEK_SET); - } - - if (read(fd, desc, 8) < 8) { - DEBUG(0, ("Unable to read command file format\n")); - exit(2); /* FIXME */ - } - - desc[8] = 0; - - if (strcmp(desc, FMT_STRING_REGEDIT4) == 0) { - if (cur_ofs) { - lseek(fd, cur_ofs, SEEK_SET); - } else { - skip_to_eol(fd); - } - return FMT_REGEDIT4; - } - - return FMT_UNREC; -} - -/* - * Run though the data in the line and strip anything after a comment - * char. - */ -static void strip_comment(struct cmd_line *cl) -{ - int i; - - if (!cl) return; - - for (i = 0; i < cl->line_len; i++) { - if (cl->line[i] == ';') { - cl->line[i] = '\0'; - cl->line_len = i; - return; - } - } -} - -/* - * Get a command ... This consists of possibly multiple lines: - * [key] - * values* - * possibly Empty line - * - * value ::= =':' - * is some path, possibly enclosed in quotes ... - * We alctually look for the next key to terminate a previous key - * if == '-', then it is a delete type. - */ -static CMD *regedit4_get_cmd(int fd) -{ - struct command_s *cmd = NULL; - struct cmd_line *cl = NULL; - struct val_spec_list *vl = NULL; - - cmd = malloc_p(struct command_s); - if (!cmd) - return NULL; - - cmd->cmd = CMD_NONE; - cmd->key = NULL; - cmd->val_count = 0; - cmd->val_spec_list = cmd->val_spec_last = NULL; - while ((cl = get_cmd_line(fd))) { - - /* - * If it is an empty command line, and we already have a key - * then exit from here ... FIXME: Clean up the parser - */ - - if (cl->line_len == 0 && cmd->key) { - free_cmd_line(cl); - break; - } - - strip_comment(cl); /* remove anything beyond a comment char */ - trim_string(cl->line, " \t", " \t"); - - if (!cl->line[0]) { /* An empty line */ - free_cmd_line(cl); - } - else { /* Else, non-empty ... */ - /* - * Parse out the bits ... - */ - switch (parse_line(cl)) { - case CMD_KEY: - if ((cmd->key = parse_key(cl, &cmd->cmd)) == NULL) { - DEBUG(0, ("Error parsing key from line: ")); - print_line(cl); - DEBUG(0, ("\n")); - } - break; - - case CMD_VAL: - /* - * We need to add the value stuff to the list - * There could be a \ on the end which we need to - * handle at some time - */ - vl = malloc_p(struct val_spec_list); - if (!vl) - return NULL; - vl->next = NULL; - vl->val = NULL; - vl->name = parse_value(cl, &vl->type, &vl->val); - if (!vl->name) goto error; - if (cmd->val_spec_list == NULL) { - cmd->val_spec_list = cmd->val_spec_last = vl; - } - else { - cmd->val_spec_last->next = vl; - cmd->val_spec_last = vl; - } - cmd->val_count++; - break; - - default: - DEBUG(0, ("Unrecognized line in command file: \n")); - print_line(cl); - break; - } - } - - } - if (!cmd->cmd) goto error; /* End of file ... */ - - return cmd; - - error: - if (vl) free(vl); - if (cmd) free_cmd(cmd); - return NULL; -} - -static int regedit4_exec_cmd(CMD *cmd) -{ - - return 0; -} - -static int editreg_1_0_file_type(int fd) -{ - int cur_ofs = 0; - char desc[11]; - - 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))); - exit(1); /* FIXME */ - } - - if (cur_ofs) { - lseek(fd, 0, SEEK_SET); - } - - if (read(fd, desc, 10) < 10) { - DEBUG(0, ("Unable to read command file format\n")); - exit(2); /* FIXME */ - } - - desc[10] = 0; - - if (strcmp(desc, FMT_STRING_EDITREG1_0) == 0) { - lseek(fd, cur_ofs, SEEK_SET); - return FMT_REGEDIT4; - } - - return FMT_UNREC; -} - -static CMD *editreg_1_0_get_cmd(int fd) +int main(int argc, char **argv) { - return NULL; -} - -static int editreg_1_0_exec_cmd(CMD *cmd) -{ - - return -1; -} - -typedef struct command_ops_s { - int type; - int (*file_type)(int fd); - CMD *(*get_cmd)(int fd); - int (*exec_cmd)(CMD *cmd); -} CMD_OPS; - -static CMD_OPS default_cmd_ops[] = { - {0, regedit4_file_type, regedit4_get_cmd, regedit4_exec_cmd}, - {1, editreg_1_0_file_type, editreg_1_0_get_cmd, editreg_1_0_exec_cmd}, - {-1, NULL, NULL, NULL} -}; - -typedef struct command_file_s { - char *name; - int type, fd; - CMD_OPS cmd_ops; -} CMD_FILE; - -/* - * Create a new command file structure - */ - -static CMD_FILE *cmd_file_create(const char *file) -{ - CMD_FILE *tmp; - struct stat sbuf; - int i = 0; - - /* - * Let's check if the file exists ... - * No use creating the cmd_file structure if the file does not exist - */ - - if (stat(file, &sbuf) < 0) { /* Not able to access file */ - DEBUG(0,("Stat on %s failed\n", file)); - return NULL; - } - - tmp = malloc_p(CMD_FILE); - if (!tmp) - return NULL; - - /* - * Let's fill in some of the fields; - */ - - tmp->name = strdup(file); - - if ((tmp->fd = open(file, O_RDONLY, 666)) < 0) { - DEBUG(0,("Error opening %s\n", file)); - free(tmp); - return NULL; - } - - /* - * Now, try to find the format by indexing through the table - */ - while (default_cmd_ops[i].type != -1) { - if ((tmp->type = default_cmd_ops[i].file_type(tmp->fd)) >= 0) { - tmp->cmd_ops = default_cmd_ops[i]; - return tmp; - } - i++; - } - - /* - * If we got here, return NULL, as we could not figure out the type - * of command file. - * - * What about errors? - */ - - free(tmp); - DEBUG(0,("Unknown type\n")); - return NULL; -} - -/* - * Extract commands from the command file, and execute them. - * We pass a table of command callbacks for that - */ - -/* FIXME */ - -/* - * Main code from here on ... - */ - -/* - * key print function here ... - */ - -/* - * Sec Desc print functions - */ - -char *str_type(uint8_t type); - -static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd_file_name) -{ - CMD *cmd; - BOOL modified = False; - CMD_FILE *cmd_file = NULL; - TALLOC_CTX *mem_ctx = talloc_init("apply_cmd_file"); - struct registry_key *tmp = NULL; - WERROR error; - cmd_file = cmd_file_create(cmd_file_name); - - while ((cmd = cmd_file->cmd_ops.get_cmd(cmd_file->fd)) != NULL) { - - /* - * Now, apply the requests to the tree ... - */ - switch (cmd->cmd) { - case CMD_ADD_KEY: - error = reg_open_key_abs(mem_ctx, r, cmd->key, &tmp); - - /* If we found it, apply the other bits, else create such a key */ - if (W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) { - if(!W_ERROR_IS_OK(reg_key_add_abs(mem_ctx, r, cmd->key, 0, NULL, &tmp))) { - DEBUG(0, ("Error adding new key '%s'\n", cmd->key)); - continue; - } - modified = True; - } - - while (cmd->val_count) { - VAL_SPEC_LIST *val = cmd->val_spec_list; - - if (val->type == REG_DELETE) { - error = reg_del_value(tmp, val->name); - if(!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error removing value '%s'\n", val->name)); - } - modified = True; - } else { - DATA_BLOB blob; - blob.data = (uint8_t *)val->val; - blob.length = strlen(val->val); - if(!W_ERROR_IS_OK(reg_val_set(tmp, val->name, val->type, blob))) { - DEBUG(0, ("Error adding new value '%s'\n", val->name)); - continue; - } - modified = True; - } - - 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 ... - */ - - error = reg_key_del_abs(r, cmd->key); - if(!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Unable to delete key '%s'\n", cmd->key)); - continue; - } - modified = True; - break; - } - } - free_cmd(cmd); - - return modified; -} - - int main(int argc, char **argv) -{ - int opt; + int opt; poptContext pc; const char *patch; struct registry_context *h; const char *remote = NULL; + struct reg_diff *diff; WERROR error; struct poptOption long_options[] = { POPT_AUTOHELP @@ -786,10 +62,15 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd } patch = poptGetArg(pc); - if(!patch) patch = "/dev/stdin"; poptFreeContext(pc); - nt_apply_reg_command_file(h, patch); + diff = reg_diff_load(NULL, patch); + if (!diff) { + fprintf(stderr, "Unable to load registry patch from `%s'\n", patch); + return 1; + } + + reg_diff_apply(diff, h); return 0; } diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 24979943b3..cd67f09c33 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -92,7 +92,7 @@ static struct registry_key *cmd_set(TALLOC_CTX *mem_ctx, struct registry_context 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)) { + if (reg_string_to_val(mem_ctx, argv[2], argv[3], &val->data_type, &val->data)) { WERROR error = reg_val_set(cur, argv[1], val->data_type, val->data); if (!W_ERROR_IS_OK(error)) { fprintf(stderr, "Error setting value: %s\n", win_errstr(error)); @@ -140,7 +140,7 @@ static struct registry_key *cmd_print(TALLOC_CTX *mem_ctx, struct registry_conte return NULL; } - printf("%s\n%s\n", str_regtype(value->data_type), reg_val_data_string(mem_ctx, value)); + printf("%s\n%s\n", str_regtype(value->data_type), reg_val_data_string(mem_ctx, value->data_type, &value->data)); return NULL; } @@ -159,7 +159,7 @@ static struct registry_key *cmd_ls(TALLOC_CTX *mem_ctx, struct registry_context } for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(mem_ctx, cur, i, &value)); i++) { - printf("V \"%s\" %s %s\n", value->name, str_regtype(value->data_type), reg_val_data_string(mem_ctx, value)); + printf("V \"%s\" %s %s\n", value->name, str_regtype(value->data_type), reg_val_data_string(mem_ctx, value->data_type, &value->data)); } return NULL; -- cgit From 9cbafc42ee5cbaae9dfb9d147eefd0e59ff953d0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 29 Sep 2005 12:00:49 +0000 Subject: r10605: Forgot one file... (This used to be commit 441419a08f0845af2b4c8023e1e5bcfda24a6d62) --- source4/lib/registry/patchfile.c | 416 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 416 insertions(+) create mode 100644 source4/lib/registry/patchfile.c (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c new file mode 100644 index 0000000000..cdf35c7b70 --- /dev/null +++ b/source4/lib/registry/patchfile.c @@ -0,0 +1,416 @@ +/* + Unix SMB/CIFS implementation. + Reading .REG files + + Copyright (C) Jelmer Vernooij 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "dynconfig.h" +#include "lib/registry/registry.h" +#include "lib/cmdline/popt_common.h" +#include "system/filesys.h" + +#define DEFAULT_IDENT_STRING "SAMBA4 REGISTRY" + +static struct reg_diff_key *diff_find_add_key(struct reg_diff *diff, const char *path) +{ + int i; + + for (i = 0; diff->numkeys; i++) { + if (!strcasecmp(diff->keys[i].name, path)) + return &diff->keys[i]; + } + + diff->keys = talloc_realloc(diff, diff->keys, struct reg_diff_key, diff->numkeys+2); + diff->keys[diff->numkeys].name = talloc_strdup(diff->keys, path); + diff->keys[diff->numkeys].changetype = REG_DIFF_CHANGE_KEY; + diff->keys[diff->numkeys].numvalues = 0; + diff->keys[diff->numkeys].values = NULL; + + diff->numkeys++; + return NULL; +} + +/* + * Generate difference between two keys + */ +static WERROR reg_generate_diff_key(struct reg_diff *diff, struct registry_key *oldkey, struct registry_key *newkey) +{ + int i; + struct registry_key *t1, *t2; + struct registry_value *v1, *v2; + WERROR error1, error2; + TALLOC_CTX *mem_ctx = talloc_init("writediff"); + + /* Subkeys that were deleted */ + for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_subkey_by_index(mem_ctx, oldkey, i, &t1)); i++) { + error2 = reg_key_get_subkey_by_name(mem_ctx, newkey, t1->name, &t2); + + if (W_ERROR_IS_OK(error2)) + continue; + + if (!W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { + DEBUG(0, ("Error occured while getting subkey by name: %d\n", W_ERROR_V(error2))); + return error2; + } + + /* newkey didn't have such a subkey, add del diff */ + diff->keys = talloc_realloc(diff, diff->keys, struct reg_diff_key, diff->numkeys+2); + diff->keys[diff->numkeys].name = talloc_strdup(diff->keys, t1->path); + diff->keys[diff->numkeys].changetype = REG_DIFF_DEL_KEY; + diff->numkeys++; + } + + if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { + DEBUG(0, ("Error occured while getting subkey by index: %d\n", W_ERROR_V(error1))); + talloc_free(mem_ctx); + return error1; + } + + /* Subkeys that were added */ + for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_subkey_by_index(mem_ctx, newkey, i, &t1)); i++) { + error2 = reg_key_get_subkey_by_name(mem_ctx, oldkey, t1->name, &t2); + + if (W_ERROR_IS_OK(error2)) + continue; + + if (!W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { + DEBUG(0, ("Error occured while getting subkey by name: %d\n", W_ERROR_V(error2))); + return error2; + } + + /* oldkey didn't have such a subkey, add add diff */ + diff->keys = talloc_realloc(diff, diff->keys, struct reg_diff_key, diff->numkeys+2); + diff->keys[diff->numkeys].name = talloc_strdup(diff->keys, t1->path); + diff->keys[diff->numkeys].changetype = REG_DIFF_CHANGE_KEY; + diff->keys[diff->numkeys].numvalues = 0; + diff->keys[diff->numkeys].values = NULL; + diff->numkeys++; + + reg_generate_diff_key(diff, t1, t2); + } + + if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { + DEBUG(0, ("Error occured while getting subkey by index: %d\n", W_ERROR_V(error1))); + talloc_free(mem_ctx); + return error1; + } + + /* Values that were changed */ + for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(mem_ctx, newkey, i, &v1)); i++) { + struct reg_diff_key *thiskey = NULL; + error2 = reg_key_get_value_by_name(mem_ctx, oldkey, v1->name, &v2); + + if(!W_ERROR_IS_OK(error2) && + !W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { + DEBUG(0, ("Error occured while getting value by name: %d\n", W_ERROR_V(error2))); + return error2; + } + + if (W_ERROR_IS_OK(error2) && data_blob_equal(&v1->data, &v2->data)) + continue; + + thiskey = diff_find_add_key(diff, oldkey->path); + thiskey->values = talloc_realloc(diff, thiskey->values, struct reg_diff_value, thiskey->numvalues+2); + thiskey->values[thiskey->numvalues].name = talloc_strdup(thiskey->values, v1->name); + thiskey->values[thiskey->numvalues].type = v2->data_type; + thiskey->values[thiskey->numvalues].changetype = REG_DIFF_SET_VAL; + thiskey->values[thiskey->numvalues].data = data_blob_dup_talloc(thiskey->values, &v2->data); + thiskey->numvalues++; + } + + if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { + DEBUG(0, ("Error occured while getting value by index: %d\n", W_ERROR_V(error1))); + talloc_free(mem_ctx); + return error1; + } + + /* Values that were deleted */ + for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(mem_ctx, oldkey, i, &v1)); i++) { + struct reg_diff_key *thiskey = NULL; + error2 = reg_key_get_value_by_name(mem_ctx, newkey, v1->name, &v2); + + if (W_ERROR_IS_OK(error2)) + continue; + + if (!W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { + DEBUG(0, ("Error occured while getting value by name: %d\n", W_ERROR_V(error2))); + return error2; + } + + thiskey = diff_find_add_key(diff, oldkey->path); + thiskey->values = talloc_realloc(diff, thiskey->values, struct reg_diff_value, thiskey->numvalues+2); + thiskey->values[thiskey->numvalues].name = talloc_strdup(thiskey->values, v1->name); + thiskey->values[thiskey->numvalues].changetype = REG_DIFF_DEL_VAL; + thiskey->numvalues++; + } + + if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { + DEBUG(0, ("Error occured while getting value by index: %d\n", W_ERROR_V(error1))); + talloc_free(mem_ctx); + return error1; + } + + talloc_free(mem_ctx); + return WERR_OK; +} + +/* + * Generate diff between two registry contexts + */ +struct reg_diff *reg_generate_diff(TALLOC_CTX *mem_ctx, struct registry_context *ctx1, struct registry_context *ctx2) +{ + struct reg_diff *diff = talloc_zero(mem_ctx, struct reg_diff); + int i; + WERROR error; + + for(i = HKEY_CLASSES_ROOT; i <= HKEY_PERFORMANCE_NLSTEXT; i++) { + struct registry_key *r1, *r2; + error = reg_get_predefined_key(ctx1, i, &r1); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Unable to open hive %s for backend 1\n", reg_get_predef_name(i))); + continue; + } + + error = reg_get_predefined_key(ctx2, i, &r2); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Unable to open hive %s for backend 2\n", reg_get_predef_name(i))); + continue; + } + + reg_generate_diff_key(diff, r1, r2); + } + + return diff; +} + +/* + * Save registry diff + */ +WERROR reg_diff_save(const struct reg_diff *diff, const char *filename) +{ + int xf, i, j; + + if (filename) { + xf = open(filename, O_CREAT, 0755); + if (xf == -1) { + DEBUG(0, ("Unable to open %s\n", filename)); + return WERR_BADFILE; + } + } else + xf = STDIN_FILENO; + + fdprintf(xf, "%s\n\n", diff->format?diff->format:DEFAULT_IDENT_STRING); + + for (i = 0; i < diff->numkeys; i++) { + if (diff->keys[i].changetype == REG_DIFF_DEL_KEY) { + fdprintf(xf, "-%s\n\n", diff->keys[i].name); + continue; + } + + fdprintf(xf, "[%s]\n", diff->keys[i].name); + + for (j = 0; j < diff->keys[i].numvalues; j++) { + fdprintf(xf, "\"%s\"=", diff->keys[i].values[j].name); + switch (diff->keys[i].values[j].changetype) { + case REG_DIFF_DEL_VAL: + fdprintf(xf, "-\n"); + break; + case REG_DIFF_SET_VAL: + fdprintf(xf, "%s:%s\n", + str_regtype(diff->keys[i].values[j].type), + reg_val_data_string(NULL, + diff->keys[i].values[j].type, + &diff->keys[i].values[j].data)); + break; + } + } + + fdprintf(xf, "\n"); + } + + close(xf); + + return WERR_OK; +} + +/* + * Load diff file + */ +struct reg_diff *reg_diff_load(TALLOC_CTX *ctx, const char *fn) +{ + struct reg_diff *diff; + int fd; + char *line, *p, *q; + struct reg_diff_key *curkey; + struct reg_diff_value *curval; + + fd = open(fn, O_RDONLY, 0); + if (fd == -1) { + DEBUG(0, ("Error opening registry patch file `%s'\n", fn)); + return NULL; + } + + diff = talloc_zero(ctx, struct reg_diff); + if (diff == NULL) { + close(fd); + return NULL; + } + + diff->format = afdgets(fd, diff, 0); + if (!diff->format) { + talloc_free(diff); + close(fd); + return NULL; + } + + while ((line = afdgets(fd, diff, 0))) { + /* Ignore comments and empty lines */ + if (strlen(line) == 0 || line[0] == ';') { + curkey = NULL; + talloc_free(line); + continue; + } + + /* Start of key */ + if (line[0] == '[') { + p = strchr_m(line, ']'); + if (p[strlen(p)-2] != ']') { + DEBUG(0, ("Malformed line\n")); + return NULL; + } + diff->keys = talloc_realloc(diff, diff->keys, struct reg_diff_key, diff->numkeys+2); + diff->keys[diff->numkeys].name = talloc_strndup(diff->keys, line+1, strlen(line)-2); + diff->keys[diff->numkeys].changetype = REG_DIFF_CHANGE_KEY; + diff->keys[diff->numkeys].numvalues = 0; + diff->keys[diff->numkeys].values = NULL; + curkey = &diff->keys[diff->numkeys]; + diff->numkeys++; + talloc_free(line); + continue; + } + + /* Deleting key */ + if (line[0] == '-') { + diff->keys = talloc_realloc(diff, diff->keys, struct reg_diff_key, diff->numkeys+2); + diff->keys[diff->numkeys].name = talloc_strdup(diff->keys, line+1); + diff->keys[diff->numkeys].changetype = REG_DIFF_DEL_KEY; + diff->numkeys++; + talloc_free(line); + continue; + } + + /* Deleting/Changing value */ + p = strchr_m(line, '='); + if (p == NULL) { + DEBUG(0, ("Malformed line\n")); + talloc_free(line); + continue; + } + + *p = '\0'; p++; + + if (curkey == NULL) { + DEBUG(0, ("Value change without key\n")); + talloc_free(line); + continue; + } + + curkey->values = talloc_realloc(diff->keys, curkey->values, struct reg_diff_value, curkey->numvalues+2); + curval = &curkey->values[curkey->numvalues]; + curkey->numvalues++; + curval->name = talloc_strdup(curkey->values, line); + + /* Delete value */ + if (strcmp(p, "-")) { + curval->changetype = REG_DIFF_DEL_VAL; + talloc_free(line); + continue; + } + + q = strchr_m(p, ':'); + if (q) { + *q = '\0'; + q++; + } + + curval->changetype = REG_DIFF_SET_VAL; + reg_string_to_val(curkey->values, q?p:"REG_SZ", q?q:p, &curval->type, &curval->data); + + talloc_free(line); + } + + close(fd); + + return diff; +} + +/* + * Apply diff to a registry context + */ +BOOL reg_diff_apply (const struct reg_diff *diff, struct registry_context *ctx) +{ + TALLOC_CTX *mem_ctx = talloc_init("apply_cmd_file"); + struct registry_key *tmp = NULL; + WERROR error; + int i, j; + + for (i = 0; i < diff->numkeys; i++) { + if (diff->keys[i].changetype == REG_DIFF_DEL_KEY) { + error = reg_key_del_abs(ctx, diff->keys[i].name); + + if(!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Unable to delete key '%s'\n", diff->keys[i].name)); + return False; + } + + continue; + } + + /* Add / change key */ + error = reg_open_key_abs(mem_ctx, ctx, diff->keys[i].name, &tmp); + + /* If we found it, apply the other bits, else create such a key */ + if (W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) { + if(!W_ERROR_IS_OK(reg_key_add_abs(mem_ctx, ctx, diff->keys[i].name, 0, NULL, &tmp))) { + DEBUG(0, ("Error adding new key '%s'\n", diff->keys[i].name)); + return False; + } + } + + for (j = 0; j < diff->keys[i].numvalues; j++) { + if (diff->keys[i].values[j].changetype == REG_DIFF_DEL_VAL) { + error = reg_del_value(tmp, diff->keys[i].values[j].name); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error deleting value '%s'\n", diff->keys[i].values[j].name)); + return False; + } + + error = reg_val_set(tmp, diff->keys[i].values[j].name, + diff->keys[i].values[j].type, + diff->keys[i].values[j].data); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error setting value '%s'\n", diff->keys[i].values[j].name)); + return False; + } + } + } + } + + return True; +} -- cgit From a599edf04cbdeef9014923ba0d3713b8ff84f266 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 12 Oct 2005 06:10:23 +0000 Subject: r10913: This patch isn't as big as it looks ... most of the changes are fixes to make all the ldb code compile without warnings on gcc4. Unfortunately That required a lot of casts :-( I have also added the start of an 'operational' module, which will replace the timestamp module, plus add support for some other operational attributes In ldb_msg_*() I added some new utility functions to make the operational module sane, and remove the 'ldb' argument from the ldb_msg_add_*() functions. That argument was only needed back in the early days of ldb when we didn't use the hierarchical talloc and thus needed a place to get the allocation function from. Now its just a pain to pass around everywhere. Also added a ldb_debug_set() function that calls ldb_debug() plus sets the result using ldb_set_errstring(). That saves on some awkward coding in a few places. (This used to be commit f6818daecca95760c12f79fd307770cbe3346f57) --- source4/lib/registry/reg_backend_ldb.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 469961dfb4..108dd01a6b 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -70,25 +70,25 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, TALLOC_CT struct ldb_message *msg = talloc_zero(mem_ctx, struct ldb_message); char *type_s; - ldb_msg_add_string(ctx, msg, "value", talloc_strdup(mem_ctx, name)); + ldb_msg_add_string(msg, "value", talloc_strdup(mem_ctx, name)); switch (type) { case REG_SZ: case REG_EXPAND_SZ: val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8, (void *)data.data, data.length, (void **)&val.data); - ldb_msg_add_value(ctx, msg, "data", &val); + ldb_msg_add_value(msg, "data", &val); break; case REG_DWORD: - ldb_msg_add_string(ctx, msg, "data", talloc_asprintf(mem_ctx, "0x%x", IVAL(data.data, 0))); + ldb_msg_add_string(msg, "data", talloc_asprintf(mem_ctx, "0x%x", IVAL(data.data, 0))); break; default: - ldb_msg_add_value(ctx, msg, "data", &data); + ldb_msg_add_value(msg, "data", &data); } type_s = talloc_asprintf(mem_ctx, "%u", type); - ldb_msg_add_string(ctx, msg, "type", type_s); + ldb_msg_add_string(msg, "type", type_s); return msg; } @@ -276,7 +276,7 @@ static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, const struct registry_key *paren msg->dn = reg_path_to_ldb(msg, parent, name, NULL); - ldb_msg_add_string(ctx, msg, "key", talloc_strdup(mem_ctx, name)); + ldb_msg_add_string(msg, "key", talloc_strdup(mem_ctx, name)); ret = ldb_add(ctx, msg); if (ret < 0) { -- cgit From f4d590662effeb80c2b55ae5ad869b4b7810cf08 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 20 Oct 2005 10:04:57 +0000 Subject: r11214: Remove scons files (see http://lists.samba.org/archive/samba-technical/2005-October/043443.html) (This used to be commit 7fffc5c9178158249be632ac0ca179c13bd1f98f) --- source4/lib/registry/SConscript | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 source4/lib/registry/SConscript (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/SConscript b/source4/lib/registry/SConscript deleted file mode 100644 index f2fa526a67..0000000000 --- a/source4/lib/registry/SConscript +++ /dev/null @@ -1,20 +0,0 @@ -Import('hostenv paths') -# tastes like -*- python -*- - -Import('talloc basic popt_common popt param') -registry = hostenv.Library('registry', - [basic,talloc,'common/reg_interface.c','common/reg_util.c']) -regtree = hostenv.Program('regtree', ['tools/regtree.c',registry,talloc,basic,popt_common,popt,param]) -regshell = hostenv.Program('regshell', ['tools/regshell.c',registry,talloc,basic,popt_common,popt,param]) -regpatch = hostenv.Program('regpatch', ['tools/regpatch.c',registry,talloc,basic,popt_common,popt,param]) -regdiff = hostenv.Program('regdiff', ['tools/regdiff.c',registry,talloc,basic,popt_common,popt,param]) - -hostenv.Library('reg_backend_dir.c') -hostenv.Library('reg_backend_gconf.c') -hostenv.Library('reg_backend_ldb.c') -hostenv.Library('reg_backend_nt4', ['reg_backend_nt4.c',hostenv.TdrMarshaller('regf.idl')]) -hostenv.Library('reg_backend_rpc.c') -hostenv.Library('reg_backend_w95.c') -hostenv.Library('reg_backend_wine.c') - -hostenv.Install(paths['BINDIR'], [regtree,regshell,regpatch,regdiff]) -- cgit From 4c5a4a7e0288e9ac0b2f795befd5684059e4c429 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 21 Oct 2005 16:29:54 +0000 Subject: r11244: Relative path names in .mk files (This used to be commit 24e10300906c380919d2d631bfb3b8fd6b3f54ba) --- source4/lib/registry/config.mk | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 8a579d4564..9461bb2a95 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -6,7 +6,7 @@ INIT_FUNCTION = registry_nt4_init SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ - lib/registry/reg_backend_nt4.o + reg_backend_nt4.o REQUIRED_SUBSYSTEMS = TDR_REGF # End MODULE registry_nt4 ################################################ @@ -14,7 +14,7 @@ REQUIRED_SUBSYSTEMS = TDR_REGF [SUBSYSTEM::TDR_REGF] REQUIRED_SUBSYSTEMS = TDR NOPROTO = YES -INIT_OBJ_FILES = lib/registry/tdr_regf.o +INIT_OBJ_FILES = tdr_regf.o lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c lib/registry/tdr_regf.c: lib/registry/regf.idl @@ -26,7 +26,7 @@ lib/registry/tdr_regf.c: lib/registry/regf.idl INIT_FUNCTION = registry_w95_init SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ - lib/registry/reg_backend_w95.o + reg_backend_w95.o # End MODULE registry_w95 ################################################ @@ -36,7 +36,7 @@ INIT_OBJ_FILES = \ INIT_FUNCTION = registry_dir_init SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ - lib/registry/reg_backend_dir.o + reg_backend_dir.o # End MODULE registry_dir ################################################ @@ -46,7 +46,7 @@ INIT_OBJ_FILES = \ INIT_FUNCTION = registry_rpc_init SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ - lib/registry/reg_backend_rpc.o + reg_backend_rpc.o REQUIRED_SUBSYSTEMS = RPC_NDR_WINREG # End MODULE registry_rpc ################################################ @@ -59,7 +59,7 @@ REQUIRED_SUBSYSTEMS = RPC_NDR_WINREG INIT_FUNCTION = registry_gconf_init SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ - lib/registry/reg_backend_gconf.o + reg_backend_gconf.o REQUIRED_SUBSYSTEMS = EXT_LIB_gconf # End MODULE registry_gconf ################################################ @@ -70,7 +70,7 @@ REQUIRED_SUBSYSTEMS = EXT_LIB_gconf INIT_FUNCTION = registry_ldb_init SUBSYSTEM = REGISTRY INIT_OBJ_FILES = \ - lib/registry/reg_backend_ldb.o + reg_backend_ldb.o REQUIRED_SUBSYSTEMS = \ LIBLDB # End MODULE registry_ldb @@ -80,11 +80,11 @@ REQUIRED_SUBSYSTEMS = \ # Start SUBSYSTEM REGISTRY [SUBSYSTEM::REGISTRY] INIT_OBJ_FILES = \ - lib/registry/common/reg_interface.o + common/reg_interface.o ADD_OBJ_FILES = \ - lib/registry/common/reg_util.o \ - lib/registry/reg_samba.o \ - lib/registry/patchfile.o + common/reg_util.o \ + reg_samba.o \ + patchfile.o REQUIRED_SUBSYSTEMS = \ LIBBASIC # End MODULE registry_ldb @@ -107,10 +107,10 @@ REQUIRED_SUBSYSTEMS = \ [BINARY::regdiff] INSTALLDIR = BINDIR OBJ_FILES= \ - lib/registry/tools/regdiff.o + tools/regdiff.o REQUIRED_SUBSYSTEMS = \ CONFIG LIBCMDLINE REGISTRY -MANPAGE = lib/registry/man/regdiff.1 +MANPAGE = man/regdiff.1 # End BINARY regdiff ################################################ @@ -119,10 +119,10 @@ MANPAGE = lib/registry/man/regdiff.1 [BINARY::regpatch] INSTALLDIR = BINDIR OBJ_FILES= \ - lib/registry/tools/regpatch.o + tools/regpatch.o REQUIRED_SUBSYSTEMS = \ CONFIG LIBCMDLINE REGISTRY -MANPAGE = lib/registry/man/regpatch.1 +MANPAGE = man/regpatch.1 # End BINARY regpatch ################################################ @@ -131,10 +131,10 @@ MANPAGE = lib/registry/man/regpatch.1 [BINARY::regshell] INSTALLDIR = BINDIR OBJ_FILES= \ - lib/registry/tools/regshell.o + tools/regshell.o REQUIRED_SUBSYSTEMS = \ CONFIG LIBCMDLINE REGISTRY -MANPAGE = lib/registry/man/regshell.1 +MANPAGE = man/regshell.1 # End BINARY regshell ################################################ @@ -143,9 +143,9 @@ MANPAGE = lib/registry/man/regshell.1 [BINARY::regtree] INSTALLDIR = BINDIR OBJ_FILES= \ - lib/registry/tools/regtree.o + tools/regtree.o REQUIRED_SUBSYSTEMS = \ CONFIG LIBCMDLINE REGISTRY -MANPAGE = lib/registry/man/regtree.1 +MANPAGE = man/regtree.1 # End BINARY regtree ################################################ -- cgit From e19a291e21ee98892af36295b7e74952a1bd0e62 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 21 Oct 2005 19:14:43 +0000 Subject: r11246: Another fix for OpenBSD's make (This used to be commit f04072f7a9fe341efced4aff57cc061cf789d5bd) --- source4/lib/registry/config.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 9461bb2a95..7aa720cc7a 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -16,8 +16,8 @@ REQUIRED_SUBSYSTEMS = TDR NOPROTO = YES INIT_OBJ_FILES = tdr_regf.o -lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c -lib/registry/tdr_regf.c: lib/registry/regf.idl +./lib/registry/reg_backend_nt4.c: ./lib/registry/tdr_regf.c +./lib/registry/tdr_regf.c: lib/registry/regf.idl @CPP="$(CPP)" pidl/pidl $(PIDL_ARGS) --header --outputdir=lib/registry --tdr-header --tdr-parser -- lib/registry/regf.idl ################################################ -- cgit From fff24f9ebde4c605f9cb390ed5ef939801a25cfa Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 21 Oct 2005 20:40:58 +0000 Subject: r11249: More OpenBSD make fixes... (This used to be commit 118e3bc507b2694f7e5ea191950626931d8ebf29) --- source4/lib/registry/config.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 7aa720cc7a..9461bb2a95 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -16,8 +16,8 @@ REQUIRED_SUBSYSTEMS = TDR NOPROTO = YES INIT_OBJ_FILES = tdr_regf.o -./lib/registry/reg_backend_nt4.c: ./lib/registry/tdr_regf.c -./lib/registry/tdr_regf.c: lib/registry/regf.idl +lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c +lib/registry/tdr_regf.c: lib/registry/regf.idl @CPP="$(CPP)" pidl/pidl $(PIDL_ARGS) --header --outputdir=lib/registry --tdr-header --tdr-parser -- lib/registry/regf.idl ################################################ -- cgit From 9759d435ca014b192a79d7de2cd2eb0fb92745b9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sat, 22 Oct 2005 08:00:09 +0000 Subject: r11261: Rename access_required field in winreg idl to access_mask so it matches the other interfaces. (This used to be commit 8eb582b5780188b6304c560b3e84fd7d75c483f8) --- source4/lib/registry/reg_backend_rpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 1e9fff4d7c..81f002daa2 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -39,7 +39,7 @@ static void init_winreg_String(struct winreg_String *name, const char *s) NTSTATUS status; \ \ r.in.system_name = 0; \ - r.in.access_required = SEC_FLAG_MAXIMUM_ALLOWED; \ + r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; \ r.out.handle = hnd;\ \ status = dcerpc_winreg_Open ## u(p, mem_ctx, &r); \ @@ -253,7 +253,7 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, const struct registry_key *parent r.in.handle = parent->backend_data; r.out.new_handle = talloc(mem_ctx, struct policy_handle); r.in.options = 0; - r.in.access_required = access_mask; + r.in.access_mask = access_mask; r.in.secdesc = NULL; status = dcerpc_winreg_CreateKey((struct dcerpc_pipe *)(parent->hive->backend_data), mem_ctx, &r); -- cgit From bf300c868781fed3b0c0556b4e40608589ad1585 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 26 Oct 2005 13:19:15 +0000 Subject: r11300: Treat libraries as a special kind of subsystem (one that can also be built as a library and installed). (This used to be commit 98d1f9b1dc523ed88c5aa8d066030b33d74f62bf) --- source4/lib/registry/config.mk | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 9461bb2a95..288e3d21ee 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -78,7 +78,10 @@ REQUIRED_SUBSYSTEMS = \ ################################################ # Start SUBSYSTEM REGISTRY -[SUBSYSTEM::REGISTRY] +[LIBRARY::REGISTRY] +MAJOR_VERSION = 0 +MINOR_VERSION = 0 +RELEASE_VERSION = 1 INIT_OBJ_FILES = \ common/reg_interface.o ADD_OBJ_FILES = \ @@ -90,18 +93,6 @@ REQUIRED_SUBSYSTEMS = \ # End MODULE registry_ldb ################################################ -################################################ -# Start LIBRARY libwinregistry -[LIBRARY::libwinregistry] -MAJOR_VERSION = 0 -MINOR_VERSION = 0 -RELEASE_VERSION = 1 -REQUIRED_SUBSYSTEMS = \ - REGISTRY -# -# End LIBRARY libwinregistry -################################################ - ################################################ # Start BINARY regdiff [BINARY::regdiff] -- cgit From 8ee1ee66edb1c98b63cbc26741080932995156a4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 26 Oct 2005 14:18:27 +0000 Subject: r11303: Support defining and installing public headers for libraries. Support installing libraries. Get rid of pkg-config file (will be autogenerated later on). (This used to be commit b4745032a2c55752c527026feb221ccc3dce10c8) --- source4/lib/registry/config.m4 | 2 -- source4/lib/registry/config.mk | 1 + source4/lib/registry/winregistry.pc.in | 10 ---------- 3 files changed, 1 insertion(+), 12 deletions(-) delete mode 100644 source4/lib/registry/winregistry.pc.in (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index d0d1d2c54b..27e55c63b4 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -5,8 +5,6 @@ if test t$BLDSHARED = ttrue; then fi LIBWINREG=libwinregistry -AC_CONFIG_FILES(lib/registry/winregistry.pc) - SMB_MODULE_DEFAULT(registry_gconf, NOT) SMB_EXT_LIB_FROM_PKGCONFIG(gconf, gconf-2.0) diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 288e3d21ee..51387df303 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -90,6 +90,7 @@ ADD_OBJ_FILES = \ patchfile.o REQUIRED_SUBSYSTEMS = \ LIBBASIC +PUBLIC_HEADERS = registry.h # End MODULE registry_ldb ################################################ diff --git a/source4/lib/registry/winregistry.pc.in b/source4/lib/registry/winregistry.pc.in deleted file mode 100644 index ad134da236..0000000000 --- a/source4/lib/registry/winregistry.pc.in +++ /dev/null @@ -1,10 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: winregistry -Description: Windows registry library -Version: @PACKAGE_VERSION@ -Libs: @LIBS@ @REG_LIBS@ -L${prefix}/lib -lwinregistry -Cflags: -I${includedir} @CFLAGS@ @CFLAGS@ -- cgit From 67c808f5ffed2b348a0973e4a9b118ce7c1fc116 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 26 Oct 2005 15:07:13 +0000 Subject: r11304: Add support back in for loading shared modules (not used yet) (This used to be commit 90f49b6f70c4aaf0e4ab4fad2e6f9caeb0f6f3a6) --- source4/lib/registry/config.m4 | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index 27e55c63b4..ffea96c829 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -1,10 +1,4 @@ # Registry backends - -if test t$BLDSHARED = ttrue; then - LIBWINREG_SHARED=bin/libwinregistry.$SHLIBEXT -fi -LIBWINREG=libwinregistry - SMB_MODULE_DEFAULT(registry_gconf, NOT) SMB_EXT_LIB_FROM_PKGCONFIG(gconf, gconf-2.0) @@ -16,7 +10,3 @@ AC_ARG_ENABLE(reg-gconf, SMB_MODULE_DEFAULT(registry_gconf, STATIC) fi ]) - -if test x"$experimental" = x"yes"; then - SMB_LIBRARY_ENABLE(libwinregistry, YES) -fi -- cgit From a4e7bf3a89a986f0055bb8b6c6890449ca405f39 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 28 Oct 2005 21:13:30 +0000 Subject: r11382: Require number of required M4 macros Make MODULE handling a bit more like BINARY, LIBRARY and SUBSYSTEM Add some more PUBLIC_HEADERS (This used to be commit 875eb8f4cc658e6aebab070029fd499a726ad520) --- source4/lib/registry/config.m4 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index ffea96c829..af885825ee 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -1,12 +1,12 @@ # Registry backends -SMB_MODULE_DEFAULT(registry_gconf, NOT) +SMB_ENABLE(registry_gconf, NO) SMB_EXT_LIB_FROM_PKGCONFIG(gconf, gconf-2.0) AC_ARG_ENABLE(reg-gconf, [ --enable-reg-gconf Enable support for GConf registry backend], [ - if test t$enable = tyes && test t$SMB_EXT_LIB_ENABLE_gconf = tYES; then - SMB_MODULE_DEFAULT(registry_gconf, STATIC) + if test t$enable = tyes; then + SMB_ENABLE(registry_gconf, $SMB_EXT_LIB_ENABLE_gconf) fi ]) -- cgit From 66caa3234d14321b579e5d8befa3a12579c6a68e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 2 Nov 2005 04:49:45 +0000 Subject: r11472: use talloc_get_type() to try to catch an intermittent failure I'm seeing in the ldb winreg backend (This used to be commit a56a3696cc6a5186f736e503704c288589e5a833) --- source4/lib/registry/reg_backend_ldb.c | 56 ++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 26 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 108dd01a6b..faf99b42f9 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -35,6 +35,7 @@ static int ldb_free_hive (void *_hive) { struct registry_hive *hive = _hive; talloc_free(hive->backend_data); + hive->backend_data = NULL; return 0; } @@ -97,7 +98,7 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, TALLOC_CT static int reg_close_ldb_key (void *data) { struct registry_key *key = data; - struct ldb_key_data *kd = key->backend_data; + struct ldb_key_data *kd = talloc_get_type(key->backend_data, struct ldb_key_data); /* struct ldb_context *c = key->hive->backend_data; */ if (kd->subkeys) { @@ -118,9 +119,9 @@ static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const struct registry struct ldb_dn *ret = ldb_dn_new(mem_ctx); char *mypath = talloc_strdup(mem_ctx, path); char *begin; - struct ldb_key_data *kd = from->backend_data; + struct ldb_key_data *kd = talloc_get_type(from->backend_data, struct ldb_key_data); - local_ctx = talloc_named(mem_ctx, 0, "reg_path_to_ldb context"); + local_ctx = talloc_new(mem_ctx); if (add) ret = ldb_dn_compose(local_ctx, ret, ldb_dn_explode(mem_ctx, add)); @@ -147,7 +148,9 @@ static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const struct registry } } - ret = ldb_dn_compose(local_ctx, ret, kd->dn); + ret = ldb_dn_compose(mem_ctx, ret, kd->dn); + + talloc_free(local_ctx); return ret; } @@ -155,9 +158,10 @@ static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const struct registry static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, const struct registry_key *k, int idx, struct registry_key **subkey) { - struct ldb_context *c = k->hive->backend_data; + struct ldb_context *c = talloc_get_type(k->hive->backend_data, struct ldb_context); struct ldb_message_element *el; - struct ldb_key_data *kd = k->backend_data, *newkd; + struct ldb_key_data *kd = talloc_get_type(k->backend_data, struct ldb_key_data); + struct ldb_key_data *newkd; /* Do a search if necessary */ if (kd->subkeys == NULL) { @@ -186,8 +190,8 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, const struct registry_ke static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct registry_key *k, int idx, struct registry_value **value) { - struct ldb_context *c = k->hive->backend_data; - struct ldb_key_data *kd = k->backend_data; + struct ldb_context *c = talloc_get_type(k->hive->backend_data, struct ldb_context); + struct ldb_key_data *kd = talloc_get_type(k->backend_data, struct ldb_key_data); /* Do the search if necessary */ if (kd->values == NULL) { @@ -210,7 +214,7 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct registry_key static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct registry_key *h, const char *name, struct registry_key **key) { - struct ldb_context *c = h->hive->backend_data; + struct ldb_context *c = talloc_get_type(h->hive->backend_data, struct ldb_context); struct ldb_message **msg; struct ldb_dn *ldap_path; int ret; @@ -267,7 +271,7 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, const 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_context *ctx = talloc_get_type(parent->hive->backend_data, struct ldb_context); struct ldb_message *msg; struct ldb_key_data *newkd; int ret; @@ -280,7 +284,7 @@ static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, const struct registry_key *paren ret = ldb_add(ctx, msg); if (ret < 0) { - DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parent->hive->backend_data))); + DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(ctx))); return WERR_FOOBAR; } @@ -295,17 +299,17 @@ static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, const struct registry_key *paren static WERROR ldb_del_key (const struct registry_key *key, const char *child) { + struct ldb_context *ctx = talloc_get_type(key->hive->backend_data, struct ldb_context); int ret; - struct ldb_key_data *kd = key->backend_data; - TALLOC_CTX *local_ctx = talloc_named(NULL, 0, "ldb_del_key mem ctx"); - struct ldb_dn *childdn = ldb_dn_build_child(local_ctx, "key", child, kd->dn); + struct ldb_key_data *kd = talloc_get_type(key->backend_data, struct ldb_key_data); + struct ldb_dn *childdn = ldb_dn_build_child(ctx, "key", child, kd->dn); - ret = ldb_delete(key->hive->backend_data, childdn); + ret = ldb_delete(ctx, childdn); - talloc_free(local_ctx); + talloc_free(childdn); if (ret < 0) { - DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(key->hive->backend_data))); + DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(ctx))); return WERR_FOOBAR; } @@ -315,16 +319,16 @@ static WERROR ldb_del_key (const struct registry_key *key, const char *child) static WERROR ldb_del_value (const struct registry_key *key, const char *child) { int ret; - struct ldb_key_data *kd = key->backend_data; - TALLOC_CTX *local_ctx = talloc_named(NULL, 0, "ldb_del_value mem ctx"); - struct ldb_dn *childdn = ldb_dn_build_child(local_ctx, "value", child, kd->dn); + struct ldb_context *ctx = talloc_get_type(key->hive->backend_data, struct ldb_context); + struct ldb_key_data *kd = talloc_get_type(key->backend_data, struct ldb_key_data); + struct ldb_dn *childdn = ldb_dn_build_child(ctx, "value", child, kd->dn); - ret = ldb_delete(key->hive->backend_data, childdn); + ret = ldb_delete(ctx, childdn); - talloc_free(local_ctx); + talloc_free(childdn); if (ret < 0) { - DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(key->hive->backend_data))); + DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(ctx))); return WERR_FOOBAR; } @@ -333,9 +337,9 @@ static WERROR ldb_del_value (const struct registry_key *key, const char *child) static WERROR ldb_set_value (const struct registry_key *parent, const char *name, uint32_t type, DATA_BLOB data) { - struct ldb_context *ctx = parent->hive->backend_data; + struct ldb_context *ctx = talloc_get_type(parent->hive->backend_data, struct ldb_context); struct ldb_message *msg; - struct ldb_key_data *kd = parent->backend_data; + struct ldb_key_data *kd = talloc_get_type(parent->backend_data, struct ldb_key_data); int ret; TALLOC_CTX *mem_ctx = talloc_init("ldb_set_value"); @@ -347,7 +351,7 @@ static WERROR ldb_set_value (const struct registry_key *parent, const char *name if (ret < 0) { ret = ldb_modify(ctx, msg); if (ret < 0) { - DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parent->hive->backend_data))); + DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(ctx))); talloc_free(mem_ctx); return WERR_FOOBAR; } -- cgit From d59807eba4dda1454eb63e5408af0bdf1563dfa5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 2 Nov 2005 07:27:06 +0000 Subject: r11476: finally fixed the intermittent registry server bug! This has been cropping up occasionally for ages. The problem was the generic reg code setting up a backend_data value, which it has no business doing (backend_data is for backends ...) (This used to be commit 9d6d03fd1d360e15883bb1b8917ccedcc0d97a5d) --- source4/lib/registry/common/reg_interface.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 7a35c97c43..87bc3fd70c 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -416,7 +416,6 @@ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, const struct registry_key *parent, } (*newkey)->hive = parent->hive; - (*newkey)->backend_data = talloc_asprintf(mem_ctx, "%s\\%s", parent->path, name); return WERR_OK; } -- cgit From 51597d878049daa37fc107d4986b5c558ca381d0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 5 Nov 2005 23:09:23 +0000 Subject: r11526: And another warning... (This used to be commit 16467008c64d84f29bec0ea45767bb1050726b34) --- source4/lib/registry/patchfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index cdf35c7b70..dd118c780f 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -257,7 +257,7 @@ struct reg_diff *reg_diff_load(TALLOC_CTX *ctx, const char *fn) struct reg_diff *diff; int fd; char *line, *p, *q; - struct reg_diff_key *curkey; + struct reg_diff_key *curkey = NULL; struct reg_diff_value *curval; fd = open(fn, O_RDONLY, 0); -- cgit From 5c9590587197dcb95007fdc54318187d5716c7c6 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 8 Nov 2005 00:11:45 +0000 Subject: r11567: Ldb API change patch. This patch changes the way lsb_search is called and the meaning of the returned integer. The last argument of ldb_search is changed from struct ldb_message to struct ldb_result which contains a pointer to a struct ldb_message list and a count of the number of messages. The return is not the count of messages anymore but instead it is an ldb error value. I tryed to keep the patch as tiny as possible bu as you can guess I had to change a good amount of places. I also tried to double check all my changes being sure that the calling functions would still behave as before. But this patch is big enough that I fear some bug may have been introduced anyway even if it passes the test suite. So if you are currently working on any file being touched please give it a deep look and blame me for any error. Simo. (This used to be commit 22c8c97e6fb466b41859e090e959d7f1134be780) --- source4/lib/registry/reg_backend_ldb.c | 36 +++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index faf99b42f9..f1c3187aa5 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -21,6 +21,7 @@ #include "includes.h" #include "registry.h" #include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" #include "db_wrap.h" #include "librpc/gen_ndr/winreg.h" @@ -165,12 +166,19 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, const struct registry_ke /* Do a search if necessary */ if (kd->subkeys == NULL) { - kd->subkey_count = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &kd->subkeys); + struct ldb_result *res; + int ret; - if(kd->subkey_count < 0) { + ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &res); + + if (ret != LDB_SUCCESS) { DEBUG(0, ("Error getting subkeys for '%s': %s\n", ldb_dn_linearize(mem_ctx, kd->dn), ldb_errstring(c))); return WERR_FOOBAR; } + + kd->subkey_count = res->count; + kd->subkeys = talloc_steal(kd, res->msgs); + talloc_free(res); } if (idx >= kd->subkey_count) return WERR_NO_MORE_ITEMS; @@ -195,12 +203,18 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct registry_key /* Do the search if necessary */ if (kd->values == NULL) { - kd->value_count = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(value=*)", NULL,&kd->values); + struct ldb_result *res; + int ret; + + ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(value=*)", NULL, &res); - if(kd->value_count < 0) { + if (ret != LDB_SUCCESS) { DEBUG(0, ("Error getting values for '%s': %s\n", ldb_dn_linearize(mem_ctx, kd->dn), ldb_errstring(c))); return WERR_FOOBAR; } + kd->value_count = res->count; + kd->values = talloc_steal(kd, res->msgs); + talloc_free(res); } if(idx >= kd->value_count) return WERR_NO_MORE_ITEMS; @@ -215,29 +229,29 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct registry_key static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct registry_key *h, const char *name, struct registry_key **key) { struct ldb_context *c = talloc_get_type(h->hive->backend_data, struct ldb_context); - struct ldb_message **msg; + struct ldb_result *res; struct ldb_dn *ldap_path; int ret; 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); + ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL, &res); - if(ret == 0) { - return WERR_BADFILE; - } else if(ret < 0) { + if (ret != LDB_SUCCESS) { DEBUG(0, ("Error opening key '%s': %s\n", ldb_dn_linearize(ldap_path, ldap_path), ldb_errstring(c))); return WERR_FOOBAR; + } else if (res->count == 0) { + return WERR_BADFILE; } *key = talloc(mem_ctx, struct registry_key); talloc_set_destructor(*key, reg_close_ldb_key); (*key)->name = talloc_strdup(mem_ctx, strrchr(name, '\\')?strchr(name, '\\'):name); (*key)->backend_data = newkd = talloc_zero(*key, struct ldb_key_data); - newkd->dn = ldb_dn_copy(mem_ctx, msg[0]->dn); + newkd->dn = ldb_dn_copy(mem_ctx, res->msgs[0]->dn); - talloc_free(msg); + talloc_free(res); return WERR_OK; } -- cgit From b5fdc3609ece3c3f56ed8a56ae2171d240c97fff Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 14 Nov 2005 00:57:19 +0000 Subject: r11709: Comment out unused function. (This used to be commit 8fe5eadafeda91e0540a30952a786949e0678511) --- source4/lib/registry/reg_backend_nt4.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index 4d33f481e6..38abaf6490 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -652,6 +652,8 @@ static WERROR regf_set_value (const struct registry_key *key, const char *name, return WERR_NOT_SUPPORTED; } +#if 0 /* Unused */ + static WERROR regf_save_hbin(struct registry_hive *hive, struct hbin_block *hbin) { struct regf_data *regf = hive->backend_data; @@ -670,6 +672,8 @@ static WERROR regf_save_hbin(struct registry_hive *hive, struct hbin_block *hbin return WERR_OK; } +#endif + static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) { struct regf_data *regf; -- cgit From d0f46637713cb54b44fb8e371a54412146f05406 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 13 Dec 2005 16:48:37 +0000 Subject: r12209: Fix some issues with XML entities. (This used to be commit 754e51b19d2d1fd6be8e01d62b6ec892688f934c) --- source4/lib/registry/man/regdiff.1.xml | 4 +--- source4/lib/registry/man/regpatch.1.xml | 4 +--- source4/lib/registry/man/regshell.1.xml | 4 +--- source4/lib/registry/man/regtree.1.xml | 5 +---- 4 files changed, 4 insertions(+), 13 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/man/regdiff.1.xml b/source4/lib/registry/man/regdiff.1.xml index d4d9d75b91..0e237bfece 100644 --- a/source4/lib/registry/man/regdiff.1.xml +++ b/source4/lib/registry/man/regdiff.1.xml @@ -75,8 +75,6 @@ -&man.registry.backends; - VERSION @@ -93,7 +91,7 @@ AUTHOR - &man.credits.samba; + This utility is part of the Samba suite, which is developed by the global Samba Team. This manpage and regdiff were written by Jelmer Vernooij. diff --git a/source4/lib/registry/man/regpatch.1.xml b/source4/lib/registry/man/regpatch.1.xml index f1792d8bc9..c04bad9e66 100644 --- a/source4/lib/registry/man/regpatch.1.xml +++ b/source4/lib/registry/man/regpatch.1.xml @@ -61,8 +61,6 @@ -&man.registry.backends; - VERSION @@ -79,7 +77,7 @@ AUTHOR - &man.credits.samba; + This utility is part of the Samba suite, which is developed by the global Samba Team. This manpage and regpatch were written by Jelmer Vernooij. diff --git a/source4/lib/registry/man/regshell.1.xml b/source4/lib/registry/man/regshell.1.xml index fbfff86b09..edec729120 100644 --- a/source4/lib/registry/man/regshell.1.xml +++ b/source4/lib/registry/man/regshell.1.xml @@ -127,8 +127,6 @@ -&man.registry.backends; - EXAMPLES @@ -179,7 +177,7 @@ HKEY_CURRENT_USER\AppEvents> exit AUTHOR - &man.credits.samba; + This utility is part of the Samba suite, which is developed by the global Samba Team. This manpage and regshell were written by Jelmer Vernooij. diff --git a/source4/lib/registry/man/regtree.1.xml b/source4/lib/registry/man/regtree.1.xml index 7fc0de2721..98e58070d1 100644 --- a/source4/lib/registry/man/regtree.1.xml +++ b/source4/lib/registry/man/regtree.1.xml @@ -73,9 +73,6 @@ - -&man.registry.backends; - VERSION @@ -92,7 +89,7 @@ AUTHOR - &man.credits.samba; + This utility is part of the Samba suite, which is developed by the global Samba Team. This manpage and regtree were written by Jelmer Vernooij. -- cgit From a1827a1deba04e0b4b2a508dc4e4e66603a46d16 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 14 Dec 2005 07:22:25 +0000 Subject: r12227: I realised that I wasn't yet seeing authenticated LDAP for the ldb backend. The idea is that every time we open an LDB, we can provide a session_info and/or credentials. This would allow any ldb to be remote to LDAP. We should also support provisioning to a authenticated ldap server. (They are separate so we can say authenticate as foo for remote, but here we just want a token of SYSTEM). Andrew Bartlett (This used to be commit ae2f3a64ee0b07575624120db45299c65204210b) --- source4/lib/registry/reg_backend_ldb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index f1c3187aa5..6c668d7b48 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -262,7 +262,8 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) struct ldb_context *wrap; if (!hive->location) return WERR_INVALID_PARAM; - wrap = ldb_wrap_connect(hive, hive->location, 0, NULL); + /* TODO: Support remoting with credentials and ACLs with session tokens */ + wrap = ldb_wrap_connect(hive, hive->location, NULL, NULL, 0, NULL); if(!wrap) { DEBUG(1, ("ldb_open_hive: unable to connect\n")); -- cgit From ab31a4421688142690a7903388abeb0786e7f4f9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 15 Dec 2005 16:32:08 +0000 Subject: r12254: Add some (hopefully correct) descriptions for libraries that are installed. Install pkg-config files. (This used to be commit a86abe84e2cae7c6188c094a92c6b62aace02fdf) --- source4/lib/registry/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 51387df303..a76595b94d 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -81,6 +81,7 @@ REQUIRED_SUBSYSTEMS = \ [LIBRARY::REGISTRY] MAJOR_VERSION = 0 MINOR_VERSION = 0 +DESCRIPTION = Windows-style registry library RELEASE_VERSION = 1 INIT_OBJ_FILES = \ common/reg_interface.o -- cgit From 50bb996dc0c6a0d3b505b961c310e4cd8345f2e0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 20 Dec 2005 00:06:31 +0000 Subject: r12385: call pidl with the perl found by configure metze (This used to be commit 00b7800695938e2374a26208273996efeb9ab258) --- source4/lib/registry/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index a76595b94d..9dd67cb3b9 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -18,7 +18,7 @@ INIT_OBJ_FILES = tdr_regf.o lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c lib/registry/tdr_regf.c: lib/registry/regf.idl - @CPP="$(CPP)" pidl/pidl $(PIDL_ARGS) --header --outputdir=lib/registry --tdr-header --tdr-parser -- lib/registry/regf.idl + @CPP="$(CPP)" $(PERL) pidl/pidl $(PIDL_ARGS) --header --outputdir=lib/registry --tdr-header --tdr-parser -- lib/registry/regf.idl ################################################ # Start MODULE registry_w95 -- cgit From 25d57c0ad8704894ee055f74bab2f33b688a7d72 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 25 Dec 2005 15:19:55 +0000 Subject: r12483: Remove --tdr-header option (merged into --tdr-parser) (This used to be commit 45013467f57d646f3db099862665d2631272b446) --- source4/lib/registry/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 9dd67cb3b9..775e201f7e 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -18,7 +18,7 @@ INIT_OBJ_FILES = tdr_regf.o lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c lib/registry/tdr_regf.c: lib/registry/regf.idl - @CPP="$(CPP)" $(PERL) pidl/pidl $(PIDL_ARGS) --header --outputdir=lib/registry --tdr-header --tdr-parser -- lib/registry/regf.idl + @CPP="$(CPP)" $(PERL) pidl/pidl $(PIDL_ARGS) --header --outputdir=lib/registry --tdr-parser -- lib/registry/regf.idl ################################################ # Start MODULE registry_w95 -- cgit From 448483199fb436309735f5203b3282fca2c517ec Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 26 Dec 2005 16:46:55 +0000 Subject: r12494: Support loading modules from .so files for most subsystems. We now use a different system for initializing the modules for a subsystem. Most subsystems now have an init function that looks something like this: init_module_fn static_init[] = STATIC_AUTH_MODULES; init_module_fn *shared_init = load_samba_modules(NULL, "auth"); run_init_functions(static_init); run_init_functions(shared_init); talloc_free(shared_init); I hope to eliminate the other init functions later on (the init_programname_subsystems; defines). (This used to be commit b6d2ad4ce0a91c4be790dd258820c492ff1787ea) --- source4/lib/registry/common/reg_interface.c | 13 +++++++++++++ source4/lib/registry/config.mk | 1 + 2 files changed, 14 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 87bc3fd70c..ac8b90dcdb 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -64,6 +64,19 @@ static struct reg_init_function_entry *reg_find_backend_entry(const char *name) return NULL; } +NTSTATUS registry_init(void) +{ + init_module_fn static_init[] = STATIC_REGISTRY_MODULES; + init_module_fn *shared_init = load_samba_modules(NULL, "registry"); + + run_init_functions(static_init); + run_init_functions(shared_init); + + talloc_free(shared_init); + + return NT_STATUS_OK; +} + /* Check whether a certain backend is present */ BOOL reg_has_backend(const char *backend) { diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 775e201f7e..768697e2a1 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -81,6 +81,7 @@ REQUIRED_SUBSYSTEMS = \ [LIBRARY::REGISTRY] MAJOR_VERSION = 0 MINOR_VERSION = 0 +INIT_FUNCTION = registry_init DESCRIPTION = Windows-style registry library RELEASE_VERSION = 1 INIT_OBJ_FILES = \ -- cgit From d8e35f882879e189f55b3bca818dd44cc5f0c6fa Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 26 Dec 2005 18:03:50 +0000 Subject: r12498: Eliminate INIT_OBJ_FILES and ADD_OBJ_FILES. We were not using the difference between these at all, and in the future the fact that INIT_OBJ_FILES include smb_build.h will be sufficient to have recompiles at the right time. (This used to be commit b24f2583edee38abafa58578d8b5c4b43e517def) --- source4/lib/registry/config.mk | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 768697e2a1..f3e7abec3a 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -5,7 +5,7 @@ [MODULE::registry_nt4] INIT_FUNCTION = registry_nt4_init SUBSYSTEM = REGISTRY -INIT_OBJ_FILES = \ +OBJ_FILES = \ reg_backend_nt4.o REQUIRED_SUBSYSTEMS = TDR_REGF # End MODULE registry_nt4 @@ -14,7 +14,7 @@ REQUIRED_SUBSYSTEMS = TDR_REGF [SUBSYSTEM::TDR_REGF] REQUIRED_SUBSYSTEMS = TDR NOPROTO = YES -INIT_OBJ_FILES = tdr_regf.o +OBJ_FILES = tdr_regf.o lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c lib/registry/tdr_regf.c: lib/registry/regf.idl @@ -25,7 +25,7 @@ lib/registry/tdr_regf.c: lib/registry/regf.idl [MODULE::registry_w95] INIT_FUNCTION = registry_w95_init SUBSYSTEM = REGISTRY -INIT_OBJ_FILES = \ +OBJ_FILES = \ reg_backend_w95.o # End MODULE registry_w95 ################################################ @@ -35,7 +35,7 @@ INIT_OBJ_FILES = \ [MODULE::registry_dir] INIT_FUNCTION = registry_dir_init SUBSYSTEM = REGISTRY -INIT_OBJ_FILES = \ +OBJ_FILES = \ reg_backend_dir.o # End MODULE registry_dir ################################################ @@ -45,7 +45,7 @@ INIT_OBJ_FILES = \ [MODULE::registry_rpc] INIT_FUNCTION = registry_rpc_init SUBSYSTEM = REGISTRY -INIT_OBJ_FILES = \ +OBJ_FILES = \ reg_backend_rpc.o REQUIRED_SUBSYSTEMS = RPC_NDR_WINREG # End MODULE registry_rpc @@ -58,7 +58,7 @@ REQUIRED_SUBSYSTEMS = RPC_NDR_WINREG [MODULE::registry_gconf] INIT_FUNCTION = registry_gconf_init SUBSYSTEM = REGISTRY -INIT_OBJ_FILES = \ +OBJ_FILES = \ reg_backend_gconf.o REQUIRED_SUBSYSTEMS = EXT_LIB_gconf # End MODULE registry_gconf @@ -69,7 +69,7 @@ REQUIRED_SUBSYSTEMS = EXT_LIB_gconf [MODULE::registry_ldb] INIT_FUNCTION = registry_ldb_init SUBSYSTEM = REGISTRY -INIT_OBJ_FILES = \ +OBJ_FILES = \ reg_backend_ldb.o REQUIRED_SUBSYSTEMS = \ LIBLDB @@ -84,9 +84,8 @@ MINOR_VERSION = 0 INIT_FUNCTION = registry_init DESCRIPTION = Windows-style registry library RELEASE_VERSION = 1 -INIT_OBJ_FILES = \ - common/reg_interface.o -ADD_OBJ_FILES = \ +OBJ_FILES = \ + common/reg_interface.o \ common/reg_util.o \ reg_samba.o \ patchfile.o -- cgit From 6aafed9600a3fa05932668c70fc0e20f3724dab6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 26 Dec 2005 18:48:23 +0000 Subject: r12499: Move smb_build.h out of includes.h (This used to be commit c92ace494f92084ddf178626cdf392d151043bc7) --- source4/lib/registry/common/reg_interface.c | 1 + source4/lib/registry/tools/regdiff.c | 1 + source4/lib/registry/tools/regpatch.c | 1 + source4/lib/registry/tools/regshell.c | 1 + source4/lib/registry/tools/regtree.c | 1 + 5 files changed, 5 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index ac8b90dcdb..b0540c1ba4 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -21,6 +21,7 @@ #include "includes.h" #include "dlinklist.h" #include "lib/registry/registry.h" +#include "smb_build.h" /* List of available backends */ static struct reg_init_function_entry *backends = NULL; diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 92fe53ff67..7c6a5d75ae 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -23,6 +23,7 @@ #include "dynconfig.h" #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" +#include "smb_build.h" int main(int argc, char **argv) { diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index eca14741a5..8f86d8a8f0 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -25,6 +25,7 @@ #include "lib/cmdline/popt_common.h" #include "system/filesys.h" #include "librpc/gen_ndr/winreg.h" +#include "smb_build.h" int main(int argc, char **argv) { diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index cd67f09c33..ef5c598989 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -25,6 +25,7 @@ #include "lib/cmdline/popt_common.h" #include "system/time.h" #include "librpc/gen_ndr/ndr_security.h" +#include "smb_build.h" /* * ck/cd - change key diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index c24e66412f..8856c4d61c 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -23,6 +23,7 @@ #include "dynconfig.h" #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" +#include "smb_build.h" static void print_tree(int l, struct registry_key *p, int fullpath, int novals) { -- cgit From 09c44f6cae89621871d2e5475b0c0f99c25804b4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 26 Dec 2005 21:58:31 +0000 Subject: r12500: Use init functions explicitly in a few more places. 'gensec' and 'librpc' are the only two subsystems left to convert. (This used to be commit f6bbc72996aeee8607fc583140fd60be0e06e969) --- source4/lib/registry/config.mk | 1 - source4/lib/registry/tools/regdiff.c | 2 ++ source4/lib/registry/tools/regpatch.c | 2 ++ source4/lib/registry/tools/regshell.c | 2 ++ source4/lib/registry/tools/regtree.c | 2 ++ 5 files changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index f3e7abec3a..9d949a5c1d 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -81,7 +81,6 @@ REQUIRED_SUBSYSTEMS = \ [LIBRARY::REGISTRY] MAJOR_VERSION = 0 MINOR_VERSION = 0 -INIT_FUNCTION = registry_init DESCRIPTION = Windows-style registry library RELEASE_VERSION = 1 OBJ_FILES = \ diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 7c6a5d75ae..3720298df8 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -48,6 +48,8 @@ int main(int argc, char **argv) regdiff_init_subsystems; + registry_init(); + pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); while((opt = poptGetNextOpt(pc)) != -1) { diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 8f86d8a8f0..2cc1507b3e 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -46,6 +46,8 @@ int main(int argc, char **argv) regpatch_init_subsystems; + registry_init(); + pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); while((opt = poptGetNextOpt(pc)) != -1) { diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index ef5c598989..52bda8aa42 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -419,6 +419,8 @@ static char **reg_completion(const char *text, int start, int end) regshell_init_subsystems; + registry_init(); + pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); while((opt = poptGetNextOpt(pc)) != -1) { diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 8856c4d61c..01e4f92f4a 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -101,6 +101,8 @@ int main(int argc, char **argv) regtree_init_subsystems; + registry_init(); + pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); while((opt = poptGetNextOpt(pc)) != -1) { -- cgit From acd6a086b341096fcbea1775ce748587fcc8020a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 Dec 2005 14:28:01 +0000 Subject: r12510: Change the DCE/RPC interfaces to take a pointer to a dcerpc_interface_table struct rather then a tuple of interface name, UUID and version. This removes the requirement for having a global list of DCE/RPC interfaces, except for these parts of the code that use that list explicitly (ndrdump and the scanner torture test). This should also allow us to remove the hack that put the authservice parameter in the dcerpc_binding struct as it can now be read directly from dcerpc_interface_table. I will now modify some of these functions to take a dcerpc_syntax_id structure rather then a full dcerpc_interface_table. (This used to be commit 8aae0f168e54c01d0866ad6e0da141dbd828574f) --- source4/lib/registry/reg_backend_rpc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 81f002daa2..e799b3a8e4 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -371,8 +371,7 @@ WERROR reg_open_remote(struct registry_context **ctx, struct cli_credentials *cr status = dcerpc_pipe_connect(*ctx /* TALLOC_CTX */, &p, location, - DCERPC_WINREG_UUID, - DCERPC_WINREG_VERSION, + &dcerpc_table_winreg, credentials, ev); (*ctx)->backend_data = p; -- cgit From 7285e102f063122ca8ef1222cc6e9a5cde176b41 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 Dec 2005 21:11:09 +0000 Subject: r12523: Convert the registry subsystem to use a seperate prototype header (note that this doesn't use the distinction between private and public prototypes yet) (This used to be commit 60e11f575821c1762b25ad66441b6e69ad1167ef) --- source4/lib/registry/config.mk | 1 + source4/lib/registry/registry.h | 2 ++ 2 files changed, 3 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 9d949a5c1d..3f63c5be98 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -90,6 +90,7 @@ OBJ_FILES = \ patchfile.o REQUIRED_SUBSYSTEMS = \ LIBBASIC +PRIVATE_PROTO_HEADER = registry_proto.h PUBLIC_HEADERS = registry.h # End MODULE registry_ldb ################################################ diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index ebfb2caf5c..7f57a9244d 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -161,4 +161,6 @@ struct reg_diff struct reg_diff_key *keys; }; +#include "registry_proto.h" + #endif /* _REGISTRY_H */ -- cgit From 0a3c167f6bcf08b2204ca49831ca49eef73dcbf4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 Dec 2005 22:51:30 +0000 Subject: r12528: Add seperate proto headers for ntvfs, tdr, smb_server and nbt_server. (This used to be commit 87f665a1d5ba74289974bf9d8f9441c162e6f1b1) --- source4/lib/registry/common/reg_interface.c | 16 ++++++++-------- source4/lib/registry/patchfile.c | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index b0540c1ba4..00fa42d342 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -29,7 +29,7 @@ static struct reg_init_function_entry *backends = NULL; static struct reg_init_function_entry *reg_find_backend_entry(const char *name); /* Register new backend */ -NTSTATUS registry_register(const void *_hive_ops) +_PUBLIC_ NTSTATUS registry_register(const void *_hive_ops) { const struct hive_operations *hive_ops = _hive_ops; struct reg_init_function_entry *entry = backends; @@ -65,7 +65,7 @@ static struct reg_init_function_entry *reg_find_backend_entry(const char *name) return NULL; } -NTSTATUS registry_init(void) +_PUBLIC_ NTSTATUS registry_init(void) { init_module_fn static_init[] = STATIC_REGISTRY_MODULES; init_module_fn *shared_init = load_samba_modules(NULL, "registry"); @@ -101,7 +101,7 @@ static struct { { 0, NULL } }; -int reg_list_predefs(TALLOC_CTX *mem_ctx, char ***predefs, uint32_t **hkeys) +_PUBLIC_ int reg_list_predefs(TALLOC_CTX *mem_ctx, char ***predefs, uint32_t **hkeys) { int i; *predefs = talloc_array(mem_ctx, char *, ARRAY_SIZE(predef_names)); @@ -151,7 +151,7 @@ WERROR reg_get_predefined_key(struct registry_context *ctx, uint32_t hkey, struc } /* Open a registry file/host/etc */ -WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *backend, const char *location, const char *credentials, struct registry_key **root) +_PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *backend, const char *location, const char *credentials, struct registry_key **root) { struct registry_hive *rethive; struct registry_key *retkey = NULL; @@ -200,7 +200,7 @@ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *backend, const char *lo * First tries to use the open_key function from the backend * then falls back to get_subkey_by_name and later get_subkey_by_index */ -WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, struct registry_key **result) +_PUBLIC_ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, struct registry_key **result) { WERROR error; @@ -251,7 +251,7 @@ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char return WERR_OK; } -WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *key, int idx, struct registry_value **val) +_PUBLIC_ WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *key, int idx, struct registry_value **val) { if(!key) return WERR_INVALID_PARAM; @@ -434,7 +434,7 @@ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, const struct registry_key *parent, return WERR_OK; } -WERROR reg_val_set(struct registry_key *key, const char *value, uint32_t type, DATA_BLOB data) +_PUBLIC_ WERROR reg_val_set(struct registry_key *key, const char *value, uint32_t type, DATA_BLOB data) { /* A 'real' set function has preference */ if (key->hive->functions->set_value) @@ -455,7 +455,7 @@ WERROR reg_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, struct return WERR_NOT_SUPPORTED; } -WERROR reg_del_value(const struct registry_key *key, const char *valname) +_PUBLIC_ WERROR reg_del_value(const struct registry_key *key, const char *valname) { WERROR ret = WERR_OK; if(!key->hive->functions->del_value) diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index dd118c780f..21c9c26b21 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -173,7 +173,7 @@ static WERROR reg_generate_diff_key(struct reg_diff *diff, struct registry_key * /* * Generate diff between two registry contexts */ -struct reg_diff *reg_generate_diff(TALLOC_CTX *mem_ctx, struct registry_context *ctx1, struct registry_context *ctx2) +_PUBLIC_ struct reg_diff *reg_generate_diff(TALLOC_CTX *mem_ctx, struct registry_context *ctx1, struct registry_context *ctx2) { struct reg_diff *diff = talloc_zero(mem_ctx, struct reg_diff); int i; @@ -202,7 +202,7 @@ struct reg_diff *reg_generate_diff(TALLOC_CTX *mem_ctx, struct registry_context /* * Save registry diff */ -WERROR reg_diff_save(const struct reg_diff *diff, const char *filename) +_PUBLIC_ WERROR reg_diff_save(const struct reg_diff *diff, const char *filename) { int xf, i, j; @@ -363,7 +363,7 @@ struct reg_diff *reg_diff_load(TALLOC_CTX *ctx, const char *fn) /* * Apply diff to a registry context */ -BOOL reg_diff_apply (const struct reg_diff *diff, struct registry_context *ctx) +_PUBLIC_ BOOL reg_diff_apply (const struct reg_diff *diff, struct registry_context *ctx) { TALLOC_CTX *mem_ctx = talloc_init("apply_cmd_file"); struct registry_key *tmp = NULL; -- cgit From 46aa296cc94933082dbb4b9b2b1ed210a600ad2d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 29 Dec 2005 23:14:33 +0000 Subject: r12592: Remove some useless dependencies (This used to be commit ca8db1a0cd77682ac2c6dc4718f5d753a4fcc4db) --- source4/lib/registry/config.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 3f63c5be98..c55f02aee7 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -102,7 +102,7 @@ INSTALLDIR = BINDIR OBJ_FILES= \ tools/regdiff.o REQUIRED_SUBSYSTEMS = \ - CONFIG LIBCMDLINE REGISTRY + CONFIG REGISTRY LIBPOPT POPT_SAMBA POPT_CREDENTIALS MANPAGE = man/regdiff.1 # End BINARY regdiff ################################################ @@ -114,7 +114,7 @@ INSTALLDIR = BINDIR OBJ_FILES= \ tools/regpatch.o REQUIRED_SUBSYSTEMS = \ - CONFIG LIBCMDLINE REGISTRY + CONFIG REGISTRY LIBPOPT POPT_SAMBA POPT_CREDENTIALS MANPAGE = man/regpatch.1 # End BINARY regpatch ################################################ @@ -126,7 +126,7 @@ INSTALLDIR = BINDIR OBJ_FILES= \ tools/regshell.o REQUIRED_SUBSYSTEMS = \ - CONFIG LIBCMDLINE REGISTRY + CONFIG LIBPOPT REGISTRY POPT_SAMBA POPT_CREDENTIALS LIBREADLINE MANPAGE = man/regshell.1 # End BINARY regshell ################################################ @@ -138,7 +138,7 @@ INSTALLDIR = BINDIR OBJ_FILES= \ tools/regtree.o REQUIRED_SUBSYSTEMS = \ - CONFIG LIBCMDLINE REGISTRY + CONFIG LIBPOPT REGISTRY POPT_SAMBA POPT_CREDENTIALS MANPAGE = man/regtree.1 # End BINARY regtree ################################################ -- cgit From d4de4c2d210d2e8c9b5aedf70695594809ad6a0b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 30 Dec 2005 13:16:54 +0000 Subject: r12608: Remove some unused #include lines. (This used to be commit 70e7449318aa0e9d2639c76730a7d1683b2f4981) --- source4/lib/registry/patchfile.c | 2 -- source4/lib/registry/tools/regdiff.c | 1 - source4/lib/registry/tools/regpatch.c | 3 --- source4/lib/registry/tools/regshell.c | 2 -- source4/lib/registry/tools/regtree.c | 1 - 5 files changed, 9 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index 21c9c26b21..e498c296ae 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -20,9 +20,7 @@ */ #include "includes.h" -#include "dynconfig.h" #include "lib/registry/registry.h" -#include "lib/cmdline/popt_common.h" #include "system/filesys.h" #define DEFAULT_IDENT_STRING "SAMBA4 REGISTRY" diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 3720298df8..68cc56f9dd 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -20,7 +20,6 @@ */ #include "includes.h" -#include "dynconfig.h" #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" #include "smb_build.h" diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 2cc1507b3e..b8b8805486 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -20,11 +20,8 @@ */ #include "includes.h" -#include "dynconfig.h" #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" -#include "system/filesys.h" -#include "librpc/gen_ndr/winreg.h" #include "smb_build.h" int main(int argc, char **argv) diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 52bda8aa42..c858b37f4a 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -20,11 +20,9 @@ */ #include "includes.h" -#include "dynconfig.h" #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" #include "system/time.h" -#include "librpc/gen_ndr/ndr_security.h" #include "smb_build.h" /* diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 01e4f92f4a..9a9121379b 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -20,7 +20,6 @@ */ #include "includes.h" -#include "dynconfig.h" #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" #include "smb_build.h" -- cgit From aa9f67163cd2df2a815ef585edad1951343b82c8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 30 Dec 2005 22:46:16 +0000 Subject: r12620: Get rid of automatically generated lists of init functions of subsystems. This allows Samba libraries to be used by other projects (and parts of Samba to be built as shared libraries). (This used to be commit 44f0aba715bfedc7e1ee3d07e9a101a91dbd84b3) --- source4/lib/registry/reg_backend_rpc.c | 1 + source4/lib/registry/tools/regdiff.c | 3 --- source4/lib/registry/tools/regpatch.c | 3 --- source4/lib/registry/tools/regshell.c | 3 --- source4/lib/registry/tools/regtree.c | 3 --- 5 files changed, 1 insertion(+), 12 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index e799b3a8e4..32ecbec6c6 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -389,5 +389,6 @@ WERROR reg_open_remote(struct registry_context **ctx, struct cli_credentials *cr NTSTATUS registry_rpc_init(void) { + dcerpc_init(); return registry_register(®_backend_rpc); } diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 68cc56f9dd..5b876ca025 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -22,7 +22,6 @@ #include "includes.h" #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" -#include "smb_build.h" int main(int argc, char **argv) { @@ -45,8 +44,6 @@ int main(int argc, char **argv) POPT_TABLEEND }; - regdiff_init_subsystems; - registry_init(); pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index b8b8805486..6f5c79bc0e 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -22,7 +22,6 @@ #include "includes.h" #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" -#include "smb_build.h" int main(int argc, char **argv) { @@ -41,8 +40,6 @@ int main(int argc, char **argv) POPT_TABLEEND }; - regpatch_init_subsystems; - registry_init(); pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index c858b37f4a..89493c761e 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -23,7 +23,6 @@ #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" #include "system/time.h" -#include "smb_build.h" /* * ck/cd - change key @@ -415,8 +414,6 @@ static char **reg_completion(const char *text, int start, int end) POPT_TABLEEND }; - regshell_init_subsystems; - registry_init(); pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 9a9121379b..d8f5d68a94 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -22,7 +22,6 @@ #include "includes.h" #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" -#include "smb_build.h" static void print_tree(int l, struct registry_key *p, int fullpath, int novals) { @@ -98,8 +97,6 @@ int main(int argc, char **argv) POPT_TABLEEND }; - regtree_init_subsystems; - registry_init(); pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); -- cgit From 54613f5ae078dfde28838837027d0819b3d9b6e9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 31 Dec 2005 00:27:55 +0000 Subject: r12624: (hopefully) fix for BSD make after srcdir/builddir changes (This used to be commit 261dc568f9b0e8641d3a28a03b440bddc5db668e) --- source4/lib/registry/config.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index c55f02aee7..988bbdbb12 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -16,9 +16,9 @@ REQUIRED_SUBSYSTEMS = TDR NOPROTO = YES OBJ_FILES = tdr_regf.o -lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c -lib/registry/tdr_regf.c: lib/registry/regf.idl - @CPP="$(CPP)" $(PERL) pidl/pidl $(PIDL_ARGS) --header --outputdir=lib/registry --tdr-parser -- lib/registry/regf.idl +$(srcdir)/lib/registry/reg_backend_nt4.c: $(builddir)/lib/registry/tdr_regf.c +$(builddir)/lib/registry/tdr_regf.c: $(srcdir)/lib/registry/regf.idl + @CPP="$(CPP)" $(PERL) pidl/pidl $(PIDL_ARGS) --header --outputdir=$(builddir)/lib/registry --tdr-parser -- $(srcdir)/lib/registry/regf.idl ################################################ # Start MODULE registry_w95 -- cgit From d73156d2c49c7876e2c396c207a02f575ca43fbe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 31 Dec 2005 08:19:48 +0000 Subject: r12638: fix the build on BSD systems metze (This used to be commit cd3cc29fdc2c0b9ffd82253857a7968e3324ea9b) --- source4/lib/registry/config.mk | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 988bbdbb12..fbef97a299 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -16,9 +16,11 @@ REQUIRED_SUBSYSTEMS = TDR NOPROTO = YES OBJ_FILES = tdr_regf.o -$(srcdir)/lib/registry/reg_backend_nt4.c: $(builddir)/lib/registry/tdr_regf.c -$(builddir)/lib/registry/tdr_regf.c: $(srcdir)/lib/registry/regf.idl - @CPP="$(CPP)" $(PERL) pidl/pidl $(PIDL_ARGS) --header --outputdir=$(builddir)/lib/registry --tdr-parser -- $(srcdir)/lib/registry/regf.idl +lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c +lib/registry/tdr_regf.c: lib/registry/regf.idl + @CPP="$(CPP)" $(PERL) pidl/pidl $(PIDL_ARGS) \ + --header --outputdir=lib/registry \ + --tdr-parser -- lib/registry/regf.idl ################################################ # Start MODULE registry_w95 -- cgit From bc4aebfaecf52678eb40aee2fd4bd81a315c554d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 2 Jan 2006 00:16:08 +0000 Subject: r12670: Make a couple of dependencies stricter Re-introduce and use the OUTPUT_TYPE property for MODULEs to force specific modules to always be included (This used to be commit f9eede3d40098eddc3618ee48f9253cdddb94a6f) --- source4/lib/registry/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index fbef97a299..a977e0ea5c 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -46,6 +46,7 @@ OBJ_FILES = \ # Start MODULE registry_rpc [MODULE::registry_rpc] INIT_FUNCTION = registry_rpc_init +OUTPUT_TYPE = MERGEDOBJ SUBSYSTEM = REGISTRY OBJ_FILES = \ reg_backend_rpc.o -- cgit From 80c8a522861068e7b0974986936f65052dd6f70f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 23 Feb 2006 12:48:13 +0000 Subject: r13655: Use new name of build header (This used to be commit bca0e8054f6d9c7adc9d92e0c30d4323f994c9e9) --- source4/lib/registry/common/reg_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 00fa42d342..6ea2f2baa6 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -21,7 +21,7 @@ #include "includes.h" #include "dlinklist.h" #include "lib/registry/registry.h" -#include "smb_build.h" +#include "build.h" /* List of available backends */ static struct reg_init_function_entry *backends = NULL; -- cgit From af30a32b6924b0f2b701186e435defbca2ebd1aa Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 5 Mar 2006 17:15:19 +0000 Subject: r13840: Mark some functions as public. (This used to be commit 9a188eb1f48a50d92a67a4fc2b3899b90074059a) --- source4/lib/registry/patchfile.c | 2 +- source4/lib/registry/reg_backend_rpc.c | 2 +- source4/lib/registry/reg_samba.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index e498c296ae..9a7a8e586f 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -250,7 +250,7 @@ _PUBLIC_ WERROR reg_diff_save(const struct reg_diff *diff, const char *filename) /* * Load diff file */ -struct reg_diff *reg_diff_load(TALLOC_CTX *ctx, const char *fn) +_PUBLIC_ struct reg_diff *reg_diff_load(TALLOC_CTX *ctx, const char *fn) { struct reg_diff *diff; int fd; diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 32ecbec6c6..0fda6c64cc 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -356,7 +356,7 @@ static struct hive_operations reg_backend_rpc = { .num_values = rpc_num_values, }; -WERROR reg_open_remote(struct registry_context **ctx, struct cli_credentials *credentials, +WERROR _PUBLIC_ reg_open_remote(struct registry_context **ctx, struct cli_credentials *credentials, const char *location, struct event_context *ev) { NTSTATUS status; diff --git a/source4/lib/registry/reg_samba.c b/source4/lib/registry/reg_samba.c index 6341a1c4ee..61d4bb2c4a 100644 --- a/source4/lib/registry/reg_samba.c +++ b/source4/lib/registry/reg_samba.c @@ -63,7 +63,7 @@ static WERROR reg_samba_get_predef (struct registry_context *ctx, uint32_t hkey, return error; } -WERROR reg_open_local (struct registry_context **ctx) +_PUBLIC_ WERROR reg_open_local (struct registry_context **ctx) { *ctx = talloc(NULL, struct registry_context); (*ctx)->get_predefined_key = reg_samba_get_predef; -- cgit From 1589791b95091ab387acc70ded8a067a836f9779 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 6 Mar 2006 10:09:53 +0000 Subject: r13855: Docs for the registry library as well (This used to be commit ad43464cc1d1fdb59a26e612e0b4ec85ef4a43d2) --- source4/lib/registry/Doxyfile | 1229 +++++++++++++++++++++++++++ source4/lib/registry/common/reg_interface.c | 66 +- source4/lib/registry/common/reg_util.c | 10 +- source4/lib/registry/patchfile.c | 13 +- source4/lib/registry/reg_samba.c | 5 + 5 files changed, 1310 insertions(+), 13 deletions(-) create mode 100644 source4/lib/registry/Doxyfile (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/Doxyfile b/source4/lib/registry/Doxyfile new file mode 100644 index 0000000000..d12ab2d0cd --- /dev/null +++ b/source4/lib/registry/Doxyfile @@ -0,0 +1,1229 @@ +# Doxyfile 1.4.4 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = REGISTRY + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = apidocs + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = include + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = YES + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is YES. + +SHOW_DIRECTORIES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the progam writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = . common + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm + +FILE_PATTERNS = *.c + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = include/config.h include/dlinklist.h \ + include/includes.h + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = examples + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = YES + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = NO + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = NO + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = NO + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = NO + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 6ea2f2baa6..11af99e695 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -23,12 +23,17 @@ #include "lib/registry/registry.h" #include "build.h" +/** + * @file + * @brief Main registry functions + */ + /* List of available backends */ static struct reg_init_function_entry *backends = NULL; static struct reg_init_function_entry *reg_find_backend_entry(const char *name); -/* Register new backend */ +/** Register a new backend. */ _PUBLIC_ NTSTATUS registry_register(const void *_hive_ops) { const struct hive_operations *hive_ops = _hive_ops; @@ -50,7 +55,7 @@ _PUBLIC_ NTSTATUS registry_register(const void *_hive_ops) return NT_STATUS_OK; } -/* Find a backend in the list of available backends */ +/** Find a backend in the list of available backends */ static struct reg_init_function_entry *reg_find_backend_entry(const char *name) { struct reg_init_function_entry *entry; @@ -65,6 +70,7 @@ static struct reg_init_function_entry *reg_find_backend_entry(const char *name) return NULL; } +/** Initialize the registry subsystem */ _PUBLIC_ NTSTATUS registry_init(void) { init_module_fn static_init[] = STATIC_REGISTRY_MODULES; @@ -78,13 +84,13 @@ _PUBLIC_ NTSTATUS registry_init(void) return NT_STATUS_OK; } -/* Check whether a certain backend is present */ +/** Check whether a certain backend is present. */ BOOL reg_has_backend(const char *backend) { return reg_find_backend_entry(backend) != NULL?True:False; } -static struct { +static const struct { uint32_t handle; const char *name; } predef_names[] = @@ -101,6 +107,7 @@ static struct { { 0, NULL } }; +/** Obtain a list of predefined keys. */ _PUBLIC_ int reg_list_predefs(TALLOC_CTX *mem_ctx, char ***predefs, uint32_t **hkeys) { int i; @@ -115,6 +122,7 @@ _PUBLIC_ int reg_list_predefs(TALLOC_CTX *mem_ctx, char ***predefs, uint32_t **h return i; } +/** Obtain name of specific hkey. */ const char *reg_get_predef_name(uint32_t hkey) { int i; @@ -125,6 +133,7 @@ const char *reg_get_predef_name(uint32_t hkey) return NULL; } +/** Get predefined key by name. */ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, const char *name, struct registry_key **key) { int i; @@ -138,6 +147,7 @@ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, const char * return WERR_BADFILE; } +/** Get predefined key by id. */ WERROR reg_get_predefined_key(struct registry_context *ctx, uint32_t hkey, struct registry_key **key) { WERROR ret = ctx->get_predefined_key(ctx, hkey, key); @@ -150,7 +160,7 @@ WERROR reg_get_predefined_key(struct registry_context *ctx, uint32_t hkey, struc return ret; } -/* Open a registry file/host/etc */ +/** Open a registry file/host/etc */ _PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *backend, const char *location, const char *credentials, struct registry_key **root) { struct registry_hive *rethive; @@ -196,7 +206,8 @@ _PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *backend, const return WERR_OK; } -/* Open a key +/** + * Open a key * First tries to use the open_key function from the backend * then falls back to get_subkey_by_name and later get_subkey_by_index */ @@ -251,6 +262,9 @@ _PUBLIC_ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, c return WERR_OK; } +/** + * Get value by index + */ _PUBLIC_ WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *key, int idx, struct registry_value **val) { if(!key) return WERR_INVALID_PARAM; @@ -266,6 +280,9 @@ _PUBLIC_ WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, const struct reg return WERR_OK; } +/** + * Get the number of subkeys. + */ WERROR reg_key_num_subkeys(const struct registry_key *key, uint32_t *count) { if(!key) return WERR_INVALID_PARAM; @@ -291,6 +308,9 @@ WERROR reg_key_num_subkeys(const struct registry_key *key, uint32_t *count) return WERR_NOT_SUPPORTED; } +/** + * Get the number of values of a key. + */ WERROR reg_key_num_values(const struct registry_key *key, uint32_t *count) { @@ -317,6 +337,9 @@ WERROR reg_key_num_values(const struct registry_key *key, uint32_t *count) return WERR_NOT_SUPPORTED; } +/** + * Get subkey by index. + */ WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *key, int idx, struct registry_key **subkey) { if(!key) return WERR_INVALID_PARAM; @@ -337,6 +360,9 @@ WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, const struct registry_ke return WERR_OK;; } +/** + * Get subkey by name. + */ WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char *name, struct registry_key **subkey) { int i; @@ -370,6 +396,9 @@ WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, const struct registry_key return WERR_OK; } +/** + * Get value by name. + */ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char *name, struct registry_value **val) { int i; @@ -394,6 +423,9 @@ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, const struct registry_key return error; } +/** + * Delete a key. + */ WERROR reg_key_del(struct registry_key *parent, const char *name) { WERROR error; @@ -409,6 +441,9 @@ WERROR reg_key_del(struct registry_key *parent, const char *name) return WERR_OK; } +/** + * Add a key. + */ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, const struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *desc, struct registry_key **newkey) { WERROR error; @@ -434,6 +469,9 @@ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, const struct registry_key *parent, return WERR_OK; } +/** + * Set a value. + */ _PUBLIC_ WERROR reg_val_set(struct registry_key *key, const char *value, uint32_t type, DATA_BLOB data) { /* A 'real' set function has preference */ @@ -444,7 +482,9 @@ _PUBLIC_ WERROR reg_val_set(struct registry_key *key, const char *value, uint32_ return WERR_NOT_SUPPORTED; } - +/** + * Get the security descriptor on a key. + */ WERROR reg_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, struct security_descriptor **secdesc) { /* A 'real' set function has preference */ @@ -455,6 +495,9 @@ WERROR reg_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, struct return WERR_NOT_SUPPORTED; } +/** + * Delete a value. + */ _PUBLIC_ WERROR reg_del_value(const struct registry_key *key, const char *valname) { WERROR ret = WERR_OK; @@ -468,6 +511,9 @@ _PUBLIC_ WERROR reg_del_value(const struct registry_key *key, const char *valnam return ret; } +/** + * Flush a key to disk. + */ WERROR reg_key_flush(const struct registry_key *key) { if (!key) { @@ -482,6 +528,9 @@ WERROR reg_key_flush(const struct registry_key *key) return WERR_OK; } +/** + * Get the maximum name and data lengths of the subkeys. + */ WERROR reg_key_subkeysizes(const struct registry_key *key, uint32_t *max_subkeylen, uint32_t *max_subkeysize) { int i = 0; @@ -507,6 +556,9 @@ WERROR reg_key_subkeysizes(const struct registry_key *key, uint32_t *max_subkeyl return WERR_OK; } +/** + * Get the maximum name and data lengths of the values. + */ WERROR reg_key_valuesizes(const struct registry_key *key, uint32_t *max_valnamelen, uint32_t *max_valbufsize) { int i = 0; diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index 75f9d3cf00..a35e55696b 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -22,6 +22,11 @@ #include "lib/registry/registry.h" #include "librpc/gen_ndr/winreg.h" +/** + * @file + * @brief Registry utility functions + */ + static const struct { uint32_t id; const char *name; @@ -34,7 +39,7 @@ static const struct { { 0, NULL } }; -/* Return string description of registry value type */ +/** Return string description of registry value type */ const char *str_regtype(int type) { int i; @@ -79,6 +84,7 @@ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, DATA_BLOB *data) return ret; } +/** Generate a string that describes a registry value */ 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->data_type, &val->data)); @@ -154,7 +160,7 @@ char *reg_path_unix2win(char *path) return path; } -/* Open a key by name (including the predefined key name!) */ +/** Open a key by name (including the predefined key name!) */ WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result) { struct registry_key *predef; diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index 9a7a8e586f..bb37e4bb6a 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -23,6 +23,11 @@ #include "lib/registry/registry.h" #include "system/filesys.h" +/** + * @file + * @brief Registry patch files + */ + #define DEFAULT_IDENT_STRING "SAMBA4 REGISTRY" static struct reg_diff_key *diff_find_add_key(struct reg_diff *diff, const char *path) @@ -168,7 +173,7 @@ static WERROR reg_generate_diff_key(struct reg_diff *diff, struct registry_key * return WERR_OK; } -/* +/** * Generate diff between two registry contexts */ _PUBLIC_ struct reg_diff *reg_generate_diff(TALLOC_CTX *mem_ctx, struct registry_context *ctx1, struct registry_context *ctx2) @@ -197,7 +202,7 @@ _PUBLIC_ struct reg_diff *reg_generate_diff(TALLOC_CTX *mem_ctx, struct registry return diff; } -/* +/** * Save registry diff */ _PUBLIC_ WERROR reg_diff_save(const struct reg_diff *diff, const char *filename) @@ -247,7 +252,7 @@ _PUBLIC_ WERROR reg_diff_save(const struct reg_diff *diff, const char *filename) return WERR_OK; } -/* +/** * Load diff file */ _PUBLIC_ struct reg_diff *reg_diff_load(TALLOC_CTX *ctx, const char *fn) @@ -358,7 +363,7 @@ _PUBLIC_ struct reg_diff *reg_diff_load(TALLOC_CTX *ctx, const char *fn) return diff; } -/* +/** * Apply diff to a registry context */ _PUBLIC_ BOOL reg_diff_apply (const struct reg_diff *diff, struct registry_context *ctx) diff --git a/source4/lib/registry/reg_samba.c b/source4/lib/registry/reg_samba.c index 61d4bb2c4a..71f7160686 100644 --- a/source4/lib/registry/reg_samba.c +++ b/source4/lib/registry/reg_samba.c @@ -20,6 +20,11 @@ #include "includes.h" #include "registry.h" +/** + * @file + * @brief Samba-specific registry functions + */ + static WERROR reg_samba_get_predef (struct registry_context *ctx, uint32_t hkey, struct registry_key **k) { WERROR error; -- cgit From ce3032cab82fd66ddfd4d55d7cc242aff80be161 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 6 Mar 2006 21:14:41 +0000 Subject: r13898: Add a subsystem-specific DEFAULT_VISIBILITY property that can be used to not export symbols when building shared libraries. Symbols that have to be available to users of the library can be explicitly exported by prepending them with _PUBLIC_ in the C source. (This used to be commit ea9988dfda6df09f1ee8f9aea1dc5b96fff52ee6) --- source4/lib/registry/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index a977e0ea5c..82309ad470 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -82,6 +82,7 @@ REQUIRED_SUBSYSTEMS = \ ################################################ # Start SUBSYSTEM REGISTRY [LIBRARY::REGISTRY] +DEFAULT_VISIBILITY = hidden MAJOR_VERSION = 0 MINOR_VERSION = 0 DESCRIPTION = Windows-style registry library -- cgit From 86dda205623926e83d28a20d0b4d87ea1ac11824 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 6 Mar 2006 21:36:24 +0000 Subject: r13899: Get the shared library build building again. Just compiles for now, but modules don't work yet.. (Run LIBRARY_OUTPUT_TYPE=SHARED_LIBRARY MODULE_OUTPUT_TYPE=SHARED_LIBRARY ./config.status) (This used to be commit ba74f24e422eda0379615f2ab39bef1e1e025ce7) --- source4/lib/registry/common/reg_interface.c | 28 ++++++++++++++-------------- source4/lib/registry/common/reg_util.c | 8 ++++---- 2 files changed, 18 insertions(+), 18 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 11af99e695..676d9ec3b3 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -85,7 +85,7 @@ _PUBLIC_ NTSTATUS registry_init(void) } /** Check whether a certain backend is present. */ -BOOL reg_has_backend(const char *backend) +_PUBLIC_ BOOL reg_has_backend(const char *backend) { return reg_find_backend_entry(backend) != NULL?True:False; } @@ -123,7 +123,7 @@ _PUBLIC_ int reg_list_predefs(TALLOC_CTX *mem_ctx, char ***predefs, uint32_t **h } /** Obtain name of specific hkey. */ -const char *reg_get_predef_name(uint32_t hkey) +_PUBLIC_ const char *reg_get_predef_name(uint32_t hkey) { int i; for (i = 0; predef_names[i].name; i++) { @@ -134,7 +134,7 @@ const char *reg_get_predef_name(uint32_t hkey) } /** Get predefined key by name. */ -WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, const char *name, struct registry_key **key) +_PUBLIC_ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, const char *name, struct registry_key **key) { int i; @@ -148,7 +148,7 @@ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, const char * } /** Get predefined key by id. */ -WERROR reg_get_predefined_key(struct registry_context *ctx, uint32_t hkey, struct registry_key **key) +_PUBLIC_ WERROR reg_get_predefined_key(struct registry_context *ctx, uint32_t hkey, struct registry_key **key) { WERROR ret = ctx->get_predefined_key(ctx, hkey, key); @@ -283,7 +283,7 @@ _PUBLIC_ WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, const struct reg /** * Get the number of subkeys. */ -WERROR reg_key_num_subkeys(const struct registry_key *key, uint32_t *count) +_PUBLIC_ WERROR reg_key_num_subkeys(const struct registry_key *key, uint32_t *count) { if(!key) return WERR_INVALID_PARAM; @@ -311,7 +311,7 @@ WERROR reg_key_num_subkeys(const struct registry_key *key, uint32_t *count) /** * Get the number of values of a key. */ -WERROR reg_key_num_values(const struct registry_key *key, uint32_t *count) +_PUBLIC_ WERROR reg_key_num_values(const struct registry_key *key, uint32_t *count) { if(!key) return WERR_INVALID_PARAM; @@ -340,7 +340,7 @@ WERROR reg_key_num_values(const struct registry_key *key, uint32_t *count) /** * Get subkey by index. */ -WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *key, int idx, struct registry_key **subkey) +_PUBLIC_ WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *key, int idx, struct registry_key **subkey) { if(!key) return WERR_INVALID_PARAM; @@ -399,7 +399,7 @@ WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, const struct registry_key /** * Get value by name. */ -WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char *name, struct registry_value **val) +_PUBLIC_ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char *name, struct registry_value **val) { int i; WERROR error = WERR_OK; @@ -426,7 +426,7 @@ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, const struct registry_key /** * Delete a key. */ -WERROR reg_key_del(struct registry_key *parent, const char *name) +_PUBLIC_ WERROR reg_key_del(struct registry_key *parent, const char *name) { WERROR error; if(!parent) return WERR_INVALID_PARAM; @@ -444,7 +444,7 @@ WERROR reg_key_del(struct registry_key *parent, const char *name) /** * Add a key. */ -WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, const struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *desc, struct registry_key **newkey) +_PUBLIC_ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, const struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *desc, struct registry_key **newkey) { WERROR error; @@ -485,7 +485,7 @@ _PUBLIC_ WERROR reg_val_set(struct registry_key *key, const char *value, uint32_ /** * Get the security descriptor on a key. */ -WERROR reg_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, struct security_descriptor **secdesc) +_PUBLIC_ WERROR reg_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, struct security_descriptor **secdesc) { /* A 'real' set function has preference */ if (key->hive->functions->key_get_sec_desc) @@ -514,7 +514,7 @@ _PUBLIC_ WERROR reg_del_value(const struct registry_key *key, const char *valnam /** * Flush a key to disk. */ -WERROR reg_key_flush(const struct registry_key *key) +_PUBLIC_ WERROR reg_key_flush(const struct registry_key *key) { if (!key) { return WERR_INVALID_PARAM; @@ -531,7 +531,7 @@ WERROR reg_key_flush(const struct registry_key *key) /** * Get the maximum name and data lengths of the subkeys. */ -WERROR reg_key_subkeysizes(const struct registry_key *key, uint32_t *max_subkeylen, uint32_t *max_subkeysize) +_PUBLIC_ WERROR reg_key_subkeysizes(const struct registry_key *key, uint32_t *max_subkeylen, uint32_t *max_subkeysize) { int i = 0; struct registry_key *subkey; @@ -559,7 +559,7 @@ WERROR reg_key_subkeysizes(const struct registry_key *key, uint32_t *max_subkeyl /** * Get the maximum name and data lengths of the values. */ -WERROR reg_key_valuesizes(const struct registry_key *key, uint32_t *max_valnamelen, uint32_t *max_valbufsize) +_PUBLIC_ WERROR reg_key_valuesizes(const struct registry_key *key, uint32_t *max_valnamelen, uint32_t *max_valbufsize) { int i = 0; struct registry_value *value; diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index a35e55696b..da18102d1f 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -40,7 +40,7 @@ static const struct { }; /** Return string description of registry value type */ -const char *str_regtype(int type) +_PUBLIC_ const char *str_regtype(int type) { int i; for (i = 0; reg_value_types[i].name; i++) { @@ -51,7 +51,7 @@ const char *str_regtype(int type) return "Unknown"; } -char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, DATA_BLOB *data) +_PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, DATA_BLOB *data) { char *ret = NULL; @@ -85,12 +85,12 @@ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, DATA_BLOB *data) } /** Generate a string that describes a registry value */ -char *reg_val_description(TALLOC_CTX *mem_ctx, struct registry_value *val) +_PUBLIC_ 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->data_type, &val->data)); } -BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data) +_PUBLIC_ BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data) { int i; *type = -1; -- cgit From ba564a901e519b0f2cf2b7651bd260f618506b5c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 6 Mar 2006 23:28:18 +0000 Subject: r13903: Don't generate prototypes for modules and binaries in include/proto.h by default. (This used to be commit c80a8f1102caf744b66c13bebde38fba74983dc4) --- source4/lib/registry/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 82309ad470..9df95f4f2f 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -46,6 +46,7 @@ OBJ_FILES = \ # Start MODULE registry_rpc [MODULE::registry_rpc] INIT_FUNCTION = registry_rpc_init +NOPROTO = NO OUTPUT_TYPE = MERGEDOBJ SUBSYSTEM = REGISTRY OBJ_FILES = \ -- cgit From 5a4f87fe121d07eaaa9c4934f4cba5c37b68f66e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Mar 2006 10:20:47 +0000 Subject: r13920: "hidden" visibility is the default... metze (This used to be commit d37f63bf93aef1a289e5762536a72f89cc0c64d1) --- source4/lib/registry/config.mk | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 9df95f4f2f..29a5901125 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -83,7 +83,6 @@ REQUIRED_SUBSYSTEMS = \ ################################################ # Start SUBSYSTEM REGISTRY [LIBRARY::REGISTRY] -DEFAULT_VISIBILITY = hidden MAJOR_VERSION = 0 MINOR_VERSION = 0 DESCRIPTION = Windows-style registry library -- cgit From 9bd7dd912124d8ffda6f9967d6ba358c16be2aa0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 12:08:58 +0000 Subject: r13926: More header splitups. (This used to be commit 930daa9f416ecba1d75b8ad46bb42e336545672f) --- source4/lib/registry/reg_backend_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 0fda6c64cc..ced5f92e5e 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -356,7 +356,7 @@ static struct hive_operations reg_backend_rpc = { .num_values = rpc_num_values, }; -WERROR _PUBLIC_ reg_open_remote(struct registry_context **ctx, struct cli_credentials *credentials, +_PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, struct cli_credentials *credentials, const char *location, struct event_context *ev) { NTSTATUS status; -- cgit From f8fdbc967c774a1d62f87a534e4990d83ecc6b67 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 14:34:32 +0000 Subject: r13944: Yet another round of splitups. (This used to be commit f87debeb12cebd734b47314554ab671c9e06237e) --- source4/lib/registry/config.mk | 2 +- source4/lib/registry/tools/regdiff.c | 1 + source4/lib/registry/tools/regpatch.c | 1 + source4/lib/registry/tools/regshell.c | 1 + source4/lib/registry/tools/regtree.c | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 29a5901125..5c68bacd94 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -46,7 +46,7 @@ OBJ_FILES = \ # Start MODULE registry_rpc [MODULE::registry_rpc] INIT_FUNCTION = registry_rpc_init -NOPROTO = NO +PRIVATE_PROTO_HEADER = reg_backend_rpc.h OUTPUT_TYPE = MERGEDOBJ SUBSYSTEM = REGISTRY OBJ_FILES = \ diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 5b876ca025..f1c5db1598 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -21,6 +21,7 @@ #include "includes.h" #include "lib/registry/registry.h" +#include "lib/registry/reg_backend_rpc.h" #include "lib/cmdline/popt_common.h" int main(int argc, char **argv) diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 6f5c79bc0e..713d4b32cc 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -22,6 +22,7 @@ #include "includes.h" #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" +#include "lib/registry/reg_backend_rpc.h" int main(int argc, char **argv) { diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 89493c761e..4d1bb95f35 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -22,6 +22,7 @@ #include "includes.h" #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" +#include "lib/registry/reg_backend_rpc.h" #include "system/time.h" /* diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index d8f5d68a94..ccdb24a4cc 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -21,6 +21,7 @@ #include "includes.h" #include "lib/registry/registry.h" +#include "lib/registry/reg_backend_rpc.h" #include "lib/cmdline/popt_common.h" static void print_tree(int l, struct registry_key *p, int fullpath, int novals) -- cgit From ceb6e9717bf8ea5c83a01e159a7006fd8651620c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 16:41:04 +0000 Subject: r13960: Generate makefile rules for installing/removing shared modules. (This used to be commit 2c746980328431ab04852dc668899e3eb042da99) --- source4/lib/registry/config.mk | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 5c68bacd94..173d7bc5a4 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -4,7 +4,7 @@ # Start MODULE registry_nt4 [MODULE::registry_nt4] INIT_FUNCTION = registry_nt4_init -SUBSYSTEM = REGISTRY +SUBSYSTEM = registry OBJ_FILES = \ reg_backend_nt4.o REQUIRED_SUBSYSTEMS = TDR_REGF @@ -26,7 +26,7 @@ lib/registry/tdr_regf.c: lib/registry/regf.idl # Start MODULE registry_w95 [MODULE::registry_w95] INIT_FUNCTION = registry_w95_init -SUBSYSTEM = REGISTRY +SUBSYSTEM = registry OBJ_FILES = \ reg_backend_w95.o # End MODULE registry_w95 @@ -36,7 +36,7 @@ OBJ_FILES = \ # Start MODULE registry_dir [MODULE::registry_dir] INIT_FUNCTION = registry_dir_init -SUBSYSTEM = REGISTRY +SUBSYSTEM = registry OBJ_FILES = \ reg_backend_dir.o # End MODULE registry_dir @@ -48,7 +48,7 @@ OBJ_FILES = \ INIT_FUNCTION = registry_rpc_init PRIVATE_PROTO_HEADER = reg_backend_rpc.h OUTPUT_TYPE = MERGEDOBJ -SUBSYSTEM = REGISTRY +SUBSYSTEM = registry OBJ_FILES = \ reg_backend_rpc.o REQUIRED_SUBSYSTEMS = RPC_NDR_WINREG @@ -61,7 +61,7 @@ REQUIRED_SUBSYSTEMS = RPC_NDR_WINREG # Start MODULE registry_gconf [MODULE::registry_gconf] INIT_FUNCTION = registry_gconf_init -SUBSYSTEM = REGISTRY +SUBSYSTEM = registry OBJ_FILES = \ reg_backend_gconf.o REQUIRED_SUBSYSTEMS = EXT_LIB_gconf @@ -72,17 +72,17 @@ REQUIRED_SUBSYSTEMS = EXT_LIB_gconf # Start MODULE registry_ldb [MODULE::registry_ldb] INIT_FUNCTION = registry_ldb_init -SUBSYSTEM = REGISTRY +SUBSYSTEM = registry OBJ_FILES = \ reg_backend_ldb.o REQUIRED_SUBSYSTEMS = \ - LIBLDB + ldb # End MODULE registry_ldb ################################################ ################################################ -# Start SUBSYSTEM REGISTRY -[LIBRARY::REGISTRY] +# Start SUBSYSTEM registry +[LIBRARY::registry] MAJOR_VERSION = 0 MINOR_VERSION = 0 DESCRIPTION = Windows-style registry library @@ -106,7 +106,7 @@ INSTALLDIR = BINDIR OBJ_FILES= \ tools/regdiff.o REQUIRED_SUBSYSTEMS = \ - CONFIG REGISTRY LIBPOPT POPT_SAMBA POPT_CREDENTIALS + CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS MANPAGE = man/regdiff.1 # End BINARY regdiff ################################################ @@ -118,7 +118,7 @@ INSTALLDIR = BINDIR OBJ_FILES= \ tools/regpatch.o REQUIRED_SUBSYSTEMS = \ - CONFIG REGISTRY LIBPOPT POPT_SAMBA POPT_CREDENTIALS + CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS MANPAGE = man/regpatch.1 # End BINARY regpatch ################################################ @@ -130,7 +130,7 @@ INSTALLDIR = BINDIR OBJ_FILES= \ tools/regshell.o REQUIRED_SUBSYSTEMS = \ - CONFIG LIBPOPT REGISTRY POPT_SAMBA POPT_CREDENTIALS LIBREADLINE + CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS LIBREADLINE MANPAGE = man/regshell.1 # End BINARY regshell ################################################ @@ -142,7 +142,7 @@ INSTALLDIR = BINDIR OBJ_FILES= \ tools/regtree.o REQUIRED_SUBSYSTEMS = \ - CONFIG LIBPOPT REGISTRY POPT_SAMBA POPT_CREDENTIALS + CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS MANPAGE = man/regtree.1 # End BINARY regtree ################################################ -- cgit From 0fbcfd8920e8df3cfb4ba5ce2d1fcf48b38a4acf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 17:53:28 +0000 Subject: r13969: Make these names lowercase as well (just like they are now in the buildsystem) (This used to be commit 04c49e211fc4f80e03d9322b983bbde15baba640) --- source4/lib/registry/common/reg_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 676d9ec3b3..7af0616ce0 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -73,7 +73,7 @@ static struct reg_init_function_entry *reg_find_backend_entry(const char *name) /** Initialize the registry subsystem */ _PUBLIC_ NTSTATUS registry_init(void) { - init_module_fn static_init[] = STATIC_REGISTRY_MODULES; + init_module_fn static_init[] = STATIC_registry_MODULES; init_module_fn *shared_init = load_samba_modules(NULL, "registry"); run_init_functions(static_init); -- cgit From 306b12ad4943737f6810df9237ab93b64c931fbd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 9 Mar 2006 19:55:04 +0000 Subject: r14094: Use saner module directory names, fix loading of server service modules. (This used to be commit b6ffad3860ba2cf9d8f3423d65be91dcfc962ca2) --- source4/lib/registry/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 173d7bc5a4..1c006b3e09 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -39,6 +39,7 @@ INIT_FUNCTION = registry_dir_init SUBSYSTEM = registry OBJ_FILES = \ reg_backend_dir.o +REQUIRED_SUBSYSTEMS = LIBTALLOC # End MODULE registry_dir ################################################ -- cgit From 3ccea395aa3e00e4f9cb0eb2fdee2cb763cc47ac Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 9 Mar 2006 22:01:48 +0000 Subject: r14108: Make the Doxyfiles a bit shorter... (This used to be commit 1004e1521a379ba6afb47e0fd3872d43363bc606) --- source4/lib/registry/Doxyfile | 1217 +---------------------------------------- 1 file changed, 6 insertions(+), 1211 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/Doxyfile b/source4/lib/registry/Doxyfile index d12ab2d0cd..ff591b6fe4 100644 --- a/source4/lib/registry/Doxyfile +++ b/source4/lib/registry/Doxyfile @@ -1,1229 +1,24 @@ -# Doxyfile 1.4.4 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - PROJECT_NAME = REGISTRY - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - OUTPUT_DIRECTORY = apidocs - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, -# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, -# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, -# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, -# Swedish, and Ukrainian. - -OUTPUT_LANGUAGE = English - -# This tag can be used to specify the encoding used in the generated output. -# The encoding is not always determined by the language that is chosen, -# but also whether or not the output is meant for Windows or non-Windows users. -# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES -# forces the Windows encoding (this is the default for the Windows binary), -# whereas setting the tag to NO uses a Unix-style encoding (the default for -# all platforms other than Windows). - -USE_WINDOWS_ENCODING = NO - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - +BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = include - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like the Qt-style comments (thus requiring an -# explicit @brief command for a brief description. - -JAVADOC_AUTOBRIEF = YES - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = YES - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources -# only. Doxygen will then generate output that is more tailored for Java. -# For instance, namespaces will be presented as packages, qualified scopes -# will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = NO - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - SORT_BRIEF_DOCS = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is YES. - -SHOW_DIRECTORIES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from the -# version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the progam writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - +SHOW_USED_FILES = NO +SHOW_DIRECTORIES = NO WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - INPUT = . common - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm - -FILE_PATTERNS = *.c - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = include/config.h include/dlinklist.h \ - include/includes.h - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = examples - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - +FILE_PATTERNS = *.c *.h *.dox GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - GENERATE_MAN = YES - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_PREDEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = NO - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = NO - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = NO - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will -# generate a call dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = NO - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_WIDTH = 1024 - -# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_HEIGHT = 1024 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that a graph may be further truncated if the graph's -# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH -# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), -# the graph is not depth-constrained. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, which results in a white background. -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO +ALWAYS_DETAILED_SEC = YES +JAVADOC_AUTOBRIEF = YES -- cgit From 250dc086bff0c9f86c799f3718ca38cbb6636962 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Mar 2006 05:01:58 +0000 Subject: r14295: make sure we return a valid data blob (This used to be commit 759e1487349ca9631eab0315595a73c253badc1f) --- source4/lib/registry/reg_backend_nt4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index 38abaf6490..87ae2be070 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -133,7 +133,7 @@ static DATA_BLOB hbin_alloc (struct regf_data *data, uint32_t size, uint32_t *of int i; if (size == 0) - return ret; + return data_blob(NULL, 0); size += 4; /* Need to include uint32 for the length */ -- cgit From e153a8099e9a187e6bcac6507ed4b1ddfe7cb764 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 13 Mar 2006 16:32:44 +0000 Subject: r14327: Replace MAJOR_VERSION/MINOR_VERSION/RELEASE_VERSION with two parameters: - VERSION: should contain the current version. Will be made part of the filename. - SO_VERSION: should contain the latest version that this on is compatible to. Will be used for setting the soname of the shared library. Fix sonames and use them on platforms that support them Remove symlinking code. ldconfig will take care of creating the symlinks now that we set the soname. (This used to be commit 7871b07e21c85c63d0ecac4c31b98dc112d18af5) --- source4/lib/registry/config.mk | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 1c006b3e09..4456d57ccc 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -84,10 +84,9 @@ REQUIRED_SUBSYSTEMS = \ ################################################ # Start SUBSYSTEM registry [LIBRARY::registry] -MAJOR_VERSION = 0 -MINOR_VERSION = 0 +VERSION = 0.0.1 +SO_VERSION = 0.0.1 DESCRIPTION = Windows-style registry library -RELEASE_VERSION = 1 OBJ_FILES = \ common/reg_interface.o \ common/reg_util.o \ -- cgit From 7a121583b496a8fc0c1fcf44504d814700273e40 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 13 Mar 2006 22:36:07 +0000 Subject: r14349: Kill proto.h! Prototypes are now spread over multiple headers, usually one per subsystem. This change is required to allow proper header dependencies later on, without recompiling Samba each time the mtime of any source file changes. (This used to be commit 3da79bf909f801386a52e6013db399c384d0401c) --- source4/lib/registry/tools/regshell.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 4d1bb95f35..8829d862d3 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -24,6 +24,7 @@ #include "lib/cmdline/popt_common.h" #include "lib/registry/reg_backend_rpc.h" #include "system/time.h" +#include "lib/replace/readline.h" /* * ck/cd - change key -- cgit From 9b8717edecc761e5be06e6f67a6246b1e20d24dd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 14 Mar 2006 13:04:28 +0000 Subject: r14374: remove sparse warning metze (This used to be commit bb6d0be0aa6de180c9e0e7353d6c270324de3ed7) --- source4/lib/registry/reg_backend_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index ced5f92e5e..b29895b27d 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -38,7 +38,7 @@ static void init_winreg_String(struct winreg_String *name, const char *s) struct winreg_Open ## u r; \ NTSTATUS status; \ \ - r.in.system_name = 0; \ + r.in.system_name = NULL; \ r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; \ r.out.handle = hnd;\ \ -- cgit From 1060f6b3f621cb70b075a879f129e57f10fdbf8a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 14 Mar 2006 23:35:30 +0000 Subject: r14402: Generate seperate headers for RPC client functions. (This used to be commit 7054ebf0249930843a2baf4d023ae8f62cedb109) --- source4/lib/registry/reg_backend_rpc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index b29895b27d..5b2f873331 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -20,6 +20,7 @@ #include "includes.h" #include "registry.h" #include "librpc/gen_ndr/ndr_winreg.h" +#include "librpc/gen_ndr/ndr_winreg_c.h" static struct hive_operations reg_backend_rpc; -- cgit From 8528016978b084213ef53d66e1b6e831b1a01acc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 16 Mar 2006 00:23:11 +0000 Subject: r14464: Don't include ndr_BASENAME.h files unless strictly required, instead try to include just the BASENAME.h files (containing only structs) (This used to be commit 3dd477ca5147f28a962b8437e2611a8222d706bd) --- source4/lib/registry/tools/regshell.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 8829d862d3..c0bffa78e5 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -25,6 +25,7 @@ #include "lib/registry/reg_backend_rpc.h" #include "system/time.h" #include "lib/replace/readline.h" +#include "librpc/gen_ndr/ndr_security.h" /* * ck/cd - change key -- cgit From 4f1c8daa36a7a0372c5fd9eab51f3c16ee81c49d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 16 Mar 2006 12:43:28 +0000 Subject: r14470: Remove some unnecessary headers. (This used to be commit f7312dab3b9aba2b2b82e8a6e0c483a32a03a63a) --- source4/lib/registry/reg_backend_rpc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 5b2f873331..c4d9c28d9d 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -19,7 +19,6 @@ #include "includes.h" #include "registry.h" -#include "librpc/gen_ndr/ndr_winreg.h" #include "librpc/gen_ndr/ndr_winreg_c.h" static struct hive_operations reg_backend_rpc; -- cgit From 71b4fd97922933b24424924acee606389bfecb2d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 16 Mar 2006 13:56:14 +0000 Subject: r14477: Remove the NOPROTO property - it's no longer used as proto.h is gone. (This used to be commit 9c37f847d32d2f327a88c53a90af0c73126b76be) --- source4/lib/registry/config.mk | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 4456d57ccc..02071d721b 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -13,7 +13,6 @@ REQUIRED_SUBSYSTEMS = TDR_REGF [SUBSYSTEM::TDR_REGF] REQUIRED_SUBSYSTEMS = TDR -NOPROTO = YES OBJ_FILES = tdr_regf.o lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c -- cgit From b785a7c40c185512207ef8da837a766933073032 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 16 Mar 2006 21:36:36 +0000 Subject: r14492: Fix shared libs - set SO_VERSION to 0 everywhere for now. (This used to be commit 4682bc5ce047d81586447b9df82c91ed1fe677cf) --- source4/lib/registry/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 02071d721b..13700939cb 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -84,7 +84,7 @@ REQUIRED_SUBSYSTEMS = \ # Start SUBSYSTEM registry [LIBRARY::registry] VERSION = 0.0.1 -SO_VERSION = 0.0.1 +SO_VERSION = 0 DESCRIPTION = Windows-style registry library OBJ_FILES = \ common/reg_interface.o \ -- cgit From 35349a58df5b69446607fbd742a05f57f3515319 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 18 Mar 2006 15:42:57 +0000 Subject: r14542: Remove librpc, libndr and libnbt from includes.h (This used to be commit 51b4270513752d2eafbe77f9de598de16ef84a1f) --- source4/lib/registry/registry.h | 3 +++ source4/lib/registry/tools/regdiff.c | 1 + source4/lib/registry/tools/regpatch.c | 1 + source4/lib/registry/tools/regshell.c | 1 + source4/lib/registry/tools/regtree.c | 1 + 5 files changed, 7 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 7f57a9244d..efe22573c2 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -22,6 +22,9 @@ #ifndef _REGISTRY_H /* _REGISTRY_H */ #define _REGISTRY_H +#include "librpc/gen_ndr/security.h" +#include "auth/credentials/credentials.h" + /* Handles for the predefined keys */ #define HKEY_CLASSES_ROOT 0x80000000 #define HKEY_CURRENT_USER 0x80000001 diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index f1c5db1598..ae617bbe84 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -21,6 +21,7 @@ #include "includes.h" #include "lib/registry/registry.h" +#include "lib/events/events.h" #include "lib/registry/reg_backend_rpc.h" #include "lib/cmdline/popt_common.h" diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 713d4b32cc..9392e66192 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "lib/events/events.h" #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" #include "lib/registry/reg_backend_rpc.h" diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index c0bffa78e5..0812cad73f 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -22,6 +22,7 @@ #include "includes.h" #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" +#include "lib/events/events.h" #include "lib/registry/reg_backend_rpc.h" #include "system/time.h" #include "lib/replace/readline.h" diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index ccdb24a4cc..a4fb69f073 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -21,6 +21,7 @@ #include "includes.h" #include "lib/registry/registry.h" +#include "lib/events/events.h" #include "lib/registry/reg_backend_rpc.h" #include "lib/cmdline/popt_common.h" -- cgit From c84cfc0ecc46ef05dc7997a128ba9486516cb112 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Mar 2006 02:23:52 +0000 Subject: r14554: Write out header dependencies. This means all C files affected will be rebuilt when a header file is changed. It also means parallel builds work now. It will take a minute or so to generate all the dependency information, but there should be no need to rebuild that information later on, unless a file changes. This behaviour is only enabled when building in developer mode (--enable-developer) and requires a GNU make (or compatible). In all other cases, the file 'static_deps.mk' is included, which contains some basic hardcoded dependency information. (This used to be commit eb435386f015ce1d89eb6f7e7837622ebd9e1951) --- source4/lib/registry/reg_backend_nt4.c | 2 +- source4/lib/registry/registry.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index 87ae2be070..569b1e1942 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -18,7 +18,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "includes.h" -#include "registry.h" +#include "lib/registry/registry.h" #include "system/filesys.h" #include "system/time.h" #include "lib/registry/tdr_regf.h" diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index efe22573c2..87a23db93d 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -164,6 +164,6 @@ struct reg_diff struct reg_diff_key *keys; }; -#include "registry_proto.h" +#include "lib/registry/registry_proto.h" #endif /* _REGISTRY_H */ -- cgit From 184955ffd711a5db8b1e1b7c179c232ce0e29145 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Mar 2006 19:47:05 +0000 Subject: r14572: Give libraries saner names, remove some .pc files, make some things subsystems in case a library doesn't make sense. (This used to be commit ed382873fd01457a53e0a1e1f5ba6753dfbc0646) --- source4/lib/registry/config.mk | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 13700939cb..fe80c62af4 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -92,7 +92,7 @@ OBJ_FILES = \ reg_samba.o \ patchfile.o REQUIRED_SUBSYSTEMS = \ - LIBBASIC + LIBSAMBA-UTIL PRIVATE_PROTO_HEADER = registry_proto.h PUBLIC_HEADERS = registry.h # End MODULE registry_ldb @@ -105,7 +105,7 @@ INSTALLDIR = BINDIR OBJ_FILES= \ tools/regdiff.o REQUIRED_SUBSYSTEMS = \ - CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS + LIBSAMBA-CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS MANPAGE = man/regdiff.1 # End BINARY regdiff ################################################ @@ -117,7 +117,7 @@ INSTALLDIR = BINDIR OBJ_FILES= \ tools/regpatch.o REQUIRED_SUBSYSTEMS = \ - CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS + LIBSAMBA-CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS MANPAGE = man/regpatch.1 # End BINARY regpatch ################################################ @@ -129,7 +129,7 @@ INSTALLDIR = BINDIR OBJ_FILES= \ tools/regshell.o REQUIRED_SUBSYSTEMS = \ - CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS LIBREADLINE + LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS LIBREADLINE MANPAGE = man/regshell.1 # End BINARY regshell ################################################ @@ -141,7 +141,7 @@ INSTALLDIR = BINDIR OBJ_FILES= \ tools/regtree.o REQUIRED_SUBSYSTEMS = \ - CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS + LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS MANPAGE = man/regtree.1 # End BINARY regtree ################################################ -- cgit From d64ccc01769ce274c74d8458f9ef81cdcc8986f6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 21 Mar 2006 01:30:22 +0000 Subject: r14599: Pass ACLs down the registry layer. (This used to be commit 6cdefd8945eee5513a6993350ea71f12d4dbd6fa) --- source4/lib/registry/common/reg_interface.c | 4 +++- source4/lib/registry/reg_backend_ldb.c | 4 ++-- source4/lib/registry/reg_backend_rpc.c | 2 +- source4/lib/registry/reg_samba.c | 6 ++++-- source4/lib/registry/regf.idl | 1 + source4/lib/registry/registry.h | 6 ++++++ source4/lib/registry/tools/regdiff.c | 8 ++++---- source4/lib/registry/tools/regpatch.c | 4 ++-- source4/lib/registry/tools/regshell.c | 6 +++--- source4/lib/registry/tools/regtree.c | 6 +++--- 10 files changed, 29 insertions(+), 18 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 7af0616ce0..42535d835d 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -161,7 +161,7 @@ _PUBLIC_ WERROR reg_get_predefined_key(struct registry_context *ctx, uint32_t hk } /** Open a registry file/host/etc */ -_PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *backend, const char *location, const char *credentials, struct registry_key **root) +_PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *backend, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, struct registry_key **root) { struct registry_hive *rethive; struct registry_key *retkey = NULL; @@ -181,6 +181,8 @@ _PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *backend, const rethive = talloc(parent_ctx, struct registry_hive); rethive->location = location?talloc_strdup(rethive, location):NULL; + rethive->session_info = talloc_reference(rethive, session_info); + rethive->credentials = talloc_reference(rethive, credentials); rethive->functions = entry->hive_functions; rethive->backend_data = NULL; diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 6c668d7b48..ec185cd65b 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -262,8 +262,8 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) struct ldb_context *wrap; if (!hive->location) return WERR_INVALID_PARAM; - /* TODO: Support remoting with credentials and ACLs with session tokens */ - wrap = ldb_wrap_connect(hive, hive->location, NULL, NULL, 0, NULL); + + wrap = ldb_wrap_connect(hive, hive->location, hive->session_info, hive->credentials, 0, NULL); if(!wrap) { DEBUG(1, ("ldb_open_hive: unable to connect\n")); diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index c4d9c28d9d..eb98565554 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -356,7 +356,7 @@ static struct hive_operations reg_backend_rpc = { .num_values = rpc_num_values, }; -_PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, struct cli_credentials *credentials, +_PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, struct auth_session_info *session_info, struct cli_credentials *credentials, const char *location, struct event_context *ev) { NTSTATUS status; diff --git a/source4/lib/registry/reg_samba.c b/source4/lib/registry/reg_samba.c index 71f7160686..4a88d96042 100644 --- a/source4/lib/registry/reg_samba.c +++ b/source4/lib/registry/reg_samba.c @@ -61,16 +61,18 @@ static WERROR reg_samba_get_predef (struct registry_context *ctx, uint32_t hkey, /* FIXME: HKEY_LOCAL_MACHINE\Security\SAM is an alias for HKEY_LOCAL_MACHINE\SAM */ - error = reg_open_hive(ctx, backend, location, NULL, k); + error = reg_open_hive(ctx, backend, location, ctx->session_info, ctx->credentials, k); talloc_free(backend); return error; } -_PUBLIC_ WERROR reg_open_local (struct registry_context **ctx) +_PUBLIC_ WERROR reg_open_local (struct registry_context **ctx, struct auth_session_info *session_info, struct cli_credentials *credentials) { *ctx = talloc(NULL, struct registry_context); + (*ctx)->credentials = talloc_reference(*ctx, credentials); + (*ctx)->session_info = talloc_reference(*ctx, session_info); (*ctx)->get_predefined_key = reg_samba_get_predef; return WERR_OK; diff --git a/source4/lib/registry/regf.idl b/source4/lib/registry/regf.idl index dcb1df039b..8f5db8c236 100644 --- a/source4/lib/registry/regf.idl +++ b/source4/lib/registry/regf.idl @@ -17,6 +17,7 @@ interface regf /* * Registry version number + * 1.2.0.1 for WinNT 3.51 * 1.3.0.1 for WinNT 4 * 1.5.0.1 for WinXP */ diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 87a23db93d..d6b4e5b08c 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -125,6 +125,8 @@ struct registry_hive { const struct hive_operations *functions; struct registry_key *root; + struct auth_session_info *session_info; + struct cli_credentials *credentials; void *backend_data; const char *location; }; @@ -133,6 +135,8 @@ struct registry_hive * contains zero or more hives */ struct registry_context { void *backend_data; + struct cli_credentials *credentials; + struct auth_session_info *session_info; WERROR (*get_predefined_key) (struct registry_context *, uint32_t hkey, struct registry_key **); }; @@ -164,6 +168,8 @@ struct reg_diff struct reg_diff_key *keys; }; +struct auth_session_info; + #include "lib/registry/registry_proto.h" #endif /* _REGISTRY_H */ diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index ae617bbe84..c7e6f87792 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -54,14 +54,14 @@ int main(int argc, char **argv) error = WERR_OK; switch(opt) { case 'L': - if (!h1 && !from_null) error = reg_open_local(&h1); - else if (!h2) error = reg_open_local(&h2); + if (!h1 && !from_null) error = reg_open_local(&h1, NULL, cmdline_credentials); + else if (!h2) error = reg_open_local(&h2, NULL, cmdline_credentials); break; case 'R': if (!h1 && !from_null) - error = reg_open_remote(&h1, cmdline_credentials, + error = reg_open_remote(&h1, NULL, cmdline_credentials, poptGetOptArg(pc), NULL); - else if (!h2) error = reg_open_remote(&h2, cmdline_credentials, + else if (!h2) error = reg_open_remote(&h2, NULL, cmdline_credentials, poptGetOptArg(pc), NULL); break; } diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 9392e66192..74601d73f9 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -50,9 +50,9 @@ int main(int argc, char **argv) } if (remote) { - error = reg_open_remote (&h, cmdline_credentials, remote, NULL); + error = reg_open_remote (&h, NULL, cmdline_credentials, remote, NULL); } else { - error = reg_open_local (&h); + error = reg_open_local (&h, NULL, cmdline_credentials); } if (W_ERROR_IS_OK(error)) { diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 0812cad73f..19f544bccf 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -426,11 +426,11 @@ static char **reg_completion(const char *text, int start, int end) } if (remote) { - error = reg_open_remote (&h, cmdline_credentials, remote, NULL); + error = reg_open_remote (&h, NULL, cmdline_credentials, remote, NULL); } else if (backend) { - error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, &curkey); + error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, cmdline_credentials, &curkey); } else { - error = reg_open_local(&h); + error = reg_open_local(&h, NULL, cmdline_credentials); } if(!W_ERROR_IS_OK(error)) { diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index a4fb69f073..fae2c6eacf 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -107,11 +107,11 @@ int main(int argc, char **argv) } if (remote) { - error = reg_open_remote(&h, cmdline_credentials, remote, NULL); + error = reg_open_remote(&h, NULL, cmdline_credentials, remote, NULL); } else if (backend) { - error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, &root); + error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, cmdline_credentials, &root); } else { - error = reg_open_local (&h); + error = reg_open_local (&h, NULL, cmdline_credentials); } if(!W_ERROR_IS_OK(error)) { -- cgit From 6ad6506cb1483aad69c2273b539f876a8e948455 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 4 Apr 2006 14:39:00 +0000 Subject: r14906: Move SWIG-specific files to scripting/swig/ (This used to be commit 222723e4434b85748aa82f192c5c4ce136933ce3) --- source4/lib/registry/config.mk | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index fe80c62af4..5d535e4c58 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -21,6 +21,9 @@ lib/registry/tdr_regf.c: lib/registry/regf.idl --header --outputdir=lib/registry \ --tdr-parser -- lib/registry/regf.idl +clean:: + @-rm -f lib/registry/regf.h lib/registry/tdr_regf* + ################################################ # Start MODULE registry_w95 [MODULE::registry_w95] -- cgit From 02a224d3bf777ef5b82b6c4f69231e6430d283bc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 8 Apr 2006 02:47:42 +0000 Subject: r14978: fixed a print of NULL (This used to be commit bf867dc789dc966864223d8fdc52e093ccacf181) --- source4/lib/registry/tools/regtree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index fae2c6eacf..106039361a 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -42,7 +42,7 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) } else { if(!p->name) printf("\n"); if(fullpath) printf("%s\n", p->path); - else printf("%s\n", p->name); + else printf("%s\n", p->name?p->name:"(NULL)"); } mem_ctx = talloc_init("print_tree"); -- cgit From 5f64fcf473f5cdb4b560fa672097c7cc144a67bb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 8 Apr 2006 02:58:36 +0000 Subject: r14981: fixed a use of a wild ptr in regshell (This used to be commit 868deaf89f34124a2a7ba2798fad83ffdabe316d) --- source4/lib/registry/tools/regshell.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 19f544bccf..b71c15cb67 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -93,9 +93,9 @@ static struct registry_key *cmd_set(TALLOC_CTX *mem_ctx, struct registry_context 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->data_type, &val->data)) { - WERROR error = reg_val_set(cur, argv[1], val->data_type, val->data); + struct registry_value val; + if (reg_string_to_val(mem_ctx, argv[2], argv[3], &val.data_type, &val.data)) { + WERROR error = reg_val_set(cur, argv[1], val.data_type, val.data); if (!W_ERROR_IS_OK(error)) { fprintf(stderr, "Error setting value: %s\n", win_errstr(error)); return NULL; -- cgit From 9cf41988ff6cf0647ec4850f25415ba66845fd70 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 11 Apr 2006 11:37:52 +0000 Subject: r15036: Add out of tree build support and see how buildfarm will respond to make constructs (This used to be commit 9329854489e2c231ffb7986d39009e0936873c11) --- source4/lib/registry/config.mk | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 5d535e4c58..9cc8c93450 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -15,11 +15,14 @@ REQUIRED_SUBSYSTEMS = TDR_REGF REQUIRED_SUBSYSTEMS = TDR OBJ_FILES = tdr_regf.o -lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c -lib/registry/tdr_regf.c: lib/registry/regf.idl - @CPP="$(CPP)" $(PERL) pidl/pidl $(PIDL_ARGS) \ +# Special support for external builddirs +lib/registry/reg_backend_nt4.c: $(srcdir)/lib/registry/reg_backend_nt4.c +$(srcdir)/lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c +lib/registry/tdr_regf.h: lib/registry/tdr_regf.c +lib/registry/tdr_regf.c: $(srcdir)/lib/registry/regf.idl + @CPP="$(CPP)" $(PERL) $(srcdir)/pidl/pidl $(PIDL_ARGS) \ --header --outputdir=lib/registry \ - --tdr-parser -- lib/registry/regf.idl + --tdr-parser -- $^ clean:: @-rm -f lib/registry/regf.h lib/registry/tdr_regf* -- cgit From 573b2f75fbc1de1572ac885804a94ff8ae7d499a Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Mon, 17 Apr 2006 07:04:56 +0000 Subject: r15099: An attempt to fix BSD make portability issues. With these changes Samba 4 builds successfully on NetBSD 3.0 (This used to be commit 71ea07e72d71b06166e0384950df83061a4677b8) --- source4/lib/registry/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 9cc8c93450..2693f7dde3 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -22,7 +22,7 @@ lib/registry/tdr_regf.h: lib/registry/tdr_regf.c lib/registry/tdr_regf.c: $(srcdir)/lib/registry/regf.idl @CPP="$(CPP)" $(PERL) $(srcdir)/pidl/pidl $(PIDL_ARGS) \ --header --outputdir=lib/registry \ - --tdr-parser -- $^ + --tdr-parser -- $(srcdir)/lib/registry/regf.idl clean:: @-rm -f lib/registry/regf.h lib/registry/tdr_regf* -- cgit From 6ab33938d5239e8688440f65e802f627622d301b Mon Sep 17 00:00:00 2001 From: James Peach Date: Mon, 24 Apr 2006 00:16:51 +0000 Subject: r15186: Introduce ISDOT and ISDOTDOT macros for testing whether a filename is "." for "..". These express the intention better that strcmp or strequal and improve searchability via cscope/ctags. (This used to be commit 7e4ad7e8e5ec266b969e3075c4ad7f021571f24e) --- source4/lib/registry/reg_backend_dir.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_dir.c b/source4/lib/registry/reg_backend_dir.c index da22d8d9ee..beedc0615b 100644 --- a/source4/lib/registry/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir.c @@ -88,8 +88,7 @@ static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, const struct registry_ke if(!d) return WERR_INVALID_PARAM; while((e = readdir(d))) { - if( strcmp(e->d_name, ".") && - strcmp(e->d_name, "..")) { + if(!ISDOT(e->d_name) && !ISDOTDOT(e->d_name)) { struct stat stbuf; char *thispath; -- cgit From 0eddf14b307e905663b95296aa695a10d3fb90f7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 24 Apr 2006 09:36:09 +0000 Subject: r15191: Avoid uint_t as it's not standard. (This used to be commit 7af59357b94e3819415b3a9257be0ced745ce130) --- source4/lib/registry/reg_backend_w95.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95.c index d5ce0e33f8..1d3781c583 100644 --- a/source4/lib/registry/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95.c @@ -42,7 +42,7 @@ * the keys and the RGDB contains the actual data. */ -typedef uint_t DWORD; +typedef uint32_t DWORD; typedef unsigned short WORD; typedef struct creg_block { -- cgit From 69b51f702af1ded825d5c17bdb97014cac12e752 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 24 Apr 2006 15:47:59 +0000 Subject: r15207: Introduce PRIVATE_DEPENDENCIES and PUBLIC_DEPENDENCIES as replacement for REQUIRED_SUBSYSTEMS. (This used to be commit adc8a019b6da256f104abed1b82bfde6998a2ac9) --- source4/lib/registry/config.mk | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 2693f7dde3..6cf2f50268 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -7,12 +7,12 @@ INIT_FUNCTION = registry_nt4_init SUBSYSTEM = registry OBJ_FILES = \ reg_backend_nt4.o -REQUIRED_SUBSYSTEMS = TDR_REGF +PUBLIC_DEPENDENCIES = TDR_REGF # End MODULE registry_nt4 ################################################ [SUBSYSTEM::TDR_REGF] -REQUIRED_SUBSYSTEMS = TDR +PUBLIC_DEPENDENCIES = TDR OBJ_FILES = tdr_regf.o # Special support for external builddirs @@ -44,7 +44,7 @@ INIT_FUNCTION = registry_dir_init SUBSYSTEM = registry OBJ_FILES = \ reg_backend_dir.o -REQUIRED_SUBSYSTEMS = LIBTALLOC +PUBLIC_DEPENDENCIES = LIBTALLOC # End MODULE registry_dir ################################################ @@ -57,7 +57,7 @@ OUTPUT_TYPE = MERGEDOBJ SUBSYSTEM = registry OBJ_FILES = \ reg_backend_rpc.o -REQUIRED_SUBSYSTEMS = RPC_NDR_WINREG +PUBLIC_DEPENDENCIES = RPC_NDR_WINREG # End MODULE registry_rpc ################################################ @@ -70,7 +70,7 @@ INIT_FUNCTION = registry_gconf_init SUBSYSTEM = registry OBJ_FILES = \ reg_backend_gconf.o -REQUIRED_SUBSYSTEMS = EXT_LIB_gconf +PUBLIC_DEPENDENCIES = EXT_LIB_gconf # End MODULE registry_gconf ################################################ @@ -81,7 +81,7 @@ INIT_FUNCTION = registry_ldb_init SUBSYSTEM = registry OBJ_FILES = \ reg_backend_ldb.o -REQUIRED_SUBSYSTEMS = \ +PUBLIC_DEPENDENCIES = \ ldb # End MODULE registry_ldb ################################################ @@ -97,7 +97,7 @@ OBJ_FILES = \ common/reg_util.o \ reg_samba.o \ patchfile.o -REQUIRED_SUBSYSTEMS = \ +PUBLIC_DEPENDENCIES = \ LIBSAMBA-UTIL PRIVATE_PROTO_HEADER = registry_proto.h PUBLIC_HEADERS = registry.h @@ -108,9 +108,8 @@ PUBLIC_HEADERS = registry.h # Start BINARY regdiff [BINARY::regdiff] INSTALLDIR = BINDIR -OBJ_FILES= \ - tools/regdiff.o -REQUIRED_SUBSYSTEMS = \ +OBJ_FILES = tools/regdiff.o +PRIVATE_DEPENDENCIES = \ LIBSAMBA-CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS MANPAGE = man/regdiff.1 # End BINARY regdiff @@ -120,9 +119,8 @@ MANPAGE = man/regdiff.1 # Start BINARY regpatch [BINARY::regpatch] INSTALLDIR = BINDIR -OBJ_FILES= \ - tools/regpatch.o -REQUIRED_SUBSYSTEMS = \ +OBJ_FILES = tools/regpatch.o +PRIVATE_DEPENDENCIES = \ LIBSAMBA-CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS MANPAGE = man/regpatch.1 # End BINARY regpatch @@ -132,9 +130,8 @@ MANPAGE = man/regpatch.1 # Start BINARY regshell [BINARY::regshell] INSTALLDIR = BINDIR -OBJ_FILES= \ - tools/regshell.o -REQUIRED_SUBSYSTEMS = \ +OBJ_FILES = tools/regshell.o +PRIVATE_DEPENDENCIES = \ LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS LIBREADLINE MANPAGE = man/regshell.1 # End BINARY regshell @@ -144,9 +141,8 @@ MANPAGE = man/regshell.1 # Start BINARY regtree [BINARY::regtree] INSTALLDIR = BINDIR -OBJ_FILES= \ - tools/regtree.o -REQUIRED_SUBSYSTEMS = \ +OBJ_FILES = tools/regtree.o +PRIVATE_DEPENDENCIES = \ LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS MANPAGE = man/regtree.1 # End BINARY regtree -- cgit From 62bdececc6de25d1dfdc5c27b5600180d2c8f446 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 24 Apr 2006 16:16:43 +0000 Subject: r15214: Introduce subsystem-specific CFLAGS to keep the global CFLAGS short. (This used to be commit a495bc60ab1b233fe507b2b1aa0ad7378cf52677) --- source4/lib/registry/registry.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index d6b4e5b08c..b556829880 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -36,7 +36,7 @@ #define HKEY_PERFORMANCE_TEXT 0x80000050 #define HKEY_PERFORMANCE_NLSTEXT 0x80000060 -#define REG_DELETE -1 +#define REG_DELETE -1 /* * The general idea here is that every backend provides a 'hive'. Combining -- cgit From 1cc7c693ad94aec88d231d77afc08b38065ae37c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Apr 2006 16:35:06 +0000 Subject: r15248: Fix automatic dependencies build (This used to be commit 3e5aa5e7940ebbb961c53418d170495860f514a0) --- source4/lib/registry/config.mk | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 6cf2f50268..e31a775a3c 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -16,7 +16,6 @@ PUBLIC_DEPENDENCIES = TDR OBJ_FILES = tdr_regf.o # Special support for external builddirs -lib/registry/reg_backend_nt4.c: $(srcdir)/lib/registry/reg_backend_nt4.c $(srcdir)/lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c lib/registry/tdr_regf.h: lib/registry/tdr_regf.c lib/registry/tdr_regf.c: $(srcdir)/lib/registry/regf.idl -- cgit From 882bc0a19efd6cb49c50b4f4dfa668c9ba60f2d2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Apr 2006 21:03:05 +0000 Subject: r15253: Fix dependency on tdr_regf.h (This used to be commit 31819f5411e30199198c334701176ba3bdf258d5) --- source4/lib/registry/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index e31a775a3c..2f80716fd2 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -16,6 +16,7 @@ PUBLIC_DEPENDENCIES = TDR OBJ_FILES = tdr_regf.o # Special support for external builddirs +lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c $(srcdir)/lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c lib/registry/tdr_regf.h: lib/registry/tdr_regf.c lib/registry/tdr_regf.c: $(srcdir)/lib/registry/regf.idl -- cgit From 0d5587b5d128d9dd502a3b78c02fb986b33d92c4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 26 Apr 2006 12:22:54 +0000 Subject: r15274: Drop default EXT_LIB_ prefix for external libraries. Fixes issues with local (empty) libpopt.a overriding global one (This used to be commit 2f06305e53478e5030c24550954f221a9a97c83f) --- source4/lib/registry/config.m4 | 2 +- source4/lib/registry/config.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 index af885825ee..852c74b4ab 100644 --- a/source4/lib/registry/config.m4 +++ b/source4/lib/registry/config.m4 @@ -7,6 +7,6 @@ AC_ARG_ENABLE(reg-gconf, [ --enable-reg-gconf Enable support for GConf registry backend], [ if test t$enable = tyes; then - SMB_ENABLE(registry_gconf, $SMB_EXT_LIB_ENABLE_gconf) + SMB_ENABLE(registry_gconf, $SMB_ENABLE_gconf) fi ]) diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 2f80716fd2..981e852311 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -70,7 +70,7 @@ INIT_FUNCTION = registry_gconf_init SUBSYSTEM = registry OBJ_FILES = \ reg_backend_gconf.o -PUBLIC_DEPENDENCIES = EXT_LIB_gconf +PUBLIC_DEPENDENCIES = gconf # End MODULE registry_gconf ################################################ -- cgit From 8d137d97858a618c8c5451bb7b11fb95990540c8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 27 Apr 2006 16:05:05 +0000 Subject: r15295: Fix some dependencies Move unistr-specific code to lib/charset/. Remove _m from some places where it's not needed. (This used to be commit 03224e112424968fc3f547c6159c7ccae2d1aa5b) --- source4/lib/registry/config.mk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 981e852311..44437dfa69 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -98,7 +98,7 @@ OBJ_FILES = \ reg_samba.o \ patchfile.o PUBLIC_DEPENDENCIES = \ - LIBSAMBA-UTIL + LIBSAMBA-UTIL CHARSET PRIVATE_PROTO_HEADER = registry_proto.h PUBLIC_HEADERS = registry.h # End MODULE registry_ldb @@ -132,7 +132,8 @@ MANPAGE = man/regpatch.1 INSTALLDIR = BINDIR OBJ_FILES = tools/regshell.o PRIVATE_DEPENDENCIES = \ - LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS LIBREADLINE + LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \ + SMBREADLINE MANPAGE = man/regshell.1 # End BINARY regshell ################################################ -- cgit From 620d759f49f4b648d0fa4a84e67f1cecbbdd0f06 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 27 Apr 2006 19:50:13 +0000 Subject: r15298: Fix the build using a few hacks in the build system. Recursive dependencies are now forbidden (the build system will bail out if there are any). I've split up auth_sam.c into auth_sam.c and sam.c. Andrew, please rename sam.c / move its contents to whatever/wherever you think suits best. (This used to be commit 6646384aaf3e7fa2aa798c3e564b94b0617ec4d0) --- source4/lib/registry/config.mk | 2 +- source4/lib/registry/registry.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 44437dfa69..89a77c231e 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -53,7 +53,7 @@ PUBLIC_DEPENDENCIES = LIBTALLOC [MODULE::registry_rpc] INIT_FUNCTION = registry_rpc_init PRIVATE_PROTO_HEADER = reg_backend_rpc.h -OUTPUT_TYPE = MERGEDOBJ +OUTPUT_TYPE = INTEGRATED SUBSYSTEM = registry OBJ_FILES = \ reg_backend_rpc.o diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index b556829880..385b0e7d6f 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -169,6 +169,7 @@ struct reg_diff }; struct auth_session_info; +struct event_context; #include "lib/registry/registry_proto.h" -- cgit From 5afe44c62c569b347a137da8ba1df2b6d2bbee29 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 30 Apr 2006 02:11:25 +0000 Subject: r15351: Fix tcc compile error (This used to be commit 0ba3390a9c1f4f0601a13bf2078817d85ed77de5) --- source4/lib/registry/reg_backend_rpc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index eb98565554..79adad1356 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -168,7 +168,8 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, const struct registry_ struct rpc_key_data *mykeydata = parent->backend_data; WERROR error; struct winreg_EnumValue r; - uint32_t type, len1, zero = 0; + uint32_t len1, zero = 0; + enum winreg_Type type; NTSTATUS status; struct winreg_StringBuf name; uint8_t u8; -- cgit From ad1cbc52cccf123c9f97edd4ff30df29e4677499 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 30 Apr 2006 16:09:00 +0000 Subject: r15361: Export table of predefined registry keys (This used to be commit 684ef2dae1145388308502942da15e59a8beb425) --- source4/lib/registry/common/reg_interface.c | 26 +++++++++++--------------- source4/lib/registry/registry.h | 9 +++++++++ source4/lib/registry/tools/regtree.c | 6 +++--- 3 files changed, 23 insertions(+), 18 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 42535d835d..7d65d31d0f 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -34,7 +34,7 @@ static struct reg_init_function_entry *backends = NULL; static struct reg_init_function_entry *reg_find_backend_entry(const char *name); /** Register a new backend. */ -_PUBLIC_ NTSTATUS registry_register(const void *_hive_ops) +_PUBLIC_ NTSTATUS registry_register(const void *_hive_ops) { const struct hive_operations *hive_ops = _hive_ops; struct reg_init_function_entry *entry = backends; @@ -90,11 +90,7 @@ _PUBLIC_ BOOL reg_has_backend(const char *backend) return reg_find_backend_entry(backend) != NULL?True:False; } -static const struct { - uint32_t handle; - const char *name; -} predef_names[] = -{ +const struct reg_predefined_key reg_predefined_keys[] = { {HKEY_CLASSES_ROOT,"HKEY_CLASSES_ROOT" }, {HKEY_CURRENT_USER,"HKEY_CURRENT_USER" }, {HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" }, @@ -111,12 +107,12 @@ static const struct { _PUBLIC_ int reg_list_predefs(TALLOC_CTX *mem_ctx, char ***predefs, uint32_t **hkeys) { int i; - *predefs = talloc_array(mem_ctx, char *, ARRAY_SIZE(predef_names)); - *hkeys = talloc_array(mem_ctx, uint32_t, ARRAY_SIZE(predef_names)); + *predefs = talloc_array(mem_ctx, char *, ARRAY_SIZE(reg_predefined_keys)); + *hkeys = talloc_array(mem_ctx, uint32_t, ARRAY_SIZE(reg_predefined_keys)); - for (i = 0; predef_names[i].name; i++) { - (*predefs)[i] = talloc_strdup(mem_ctx, predef_names[i].name); - (*hkeys)[i] = predef_names[i].handle; + for (i = 0; reg_predefined_keys[i].name; i++) { + (*predefs)[i] = talloc_strdup(mem_ctx, reg_predefined_keys[i].name); + (*hkeys)[i] = reg_predefined_keys[i].handle; } return i; @@ -126,8 +122,8 @@ _PUBLIC_ int reg_list_predefs(TALLOC_CTX *mem_ctx, char ***predefs, uint32_t **h _PUBLIC_ const char *reg_get_predef_name(uint32_t hkey) { int i; - for (i = 0; predef_names[i].name; i++) { - if (predef_names[i].handle == hkey) return predef_names[i].name; + for (i = 0; reg_predefined_keys[i].name; i++) { + if (reg_predefined_keys[i].handle == hkey) return reg_predefined_keys[i].name; } return NULL; @@ -138,8 +134,8 @@ _PUBLIC_ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, con { int i; - for (i = 0; predef_names[i].name; i++) { - if (!strcasecmp(predef_names[i].name, name)) return reg_get_predefined_key(ctx, predef_names[i].handle, key); + for (i = 0; reg_predefined_keys[i].name; i++) { + if (!strcasecmp(reg_predefined_keys[i].name, name)) return reg_get_predefined_key(ctx, reg_predefined_keys[i].handle, key); } DEBUG(1, ("No predefined key with name '%s'\n", name)); diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 385b0e7d6f..80b412a314 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -36,6 +36,13 @@ #define HKEY_PERFORMANCE_TEXT 0x80000050 #define HKEY_PERFORMANCE_NLSTEXT 0x80000060 +struct reg_predefined_key { + uint32_t handle; + const char *name; +}; + +extern const struct reg_predefined_key reg_predefined_keys[]; + #define REG_DELETE -1 /* @@ -145,6 +152,8 @@ struct reg_init_function_entry { struct reg_init_function_entry *prev, *next; }; +/* Representing differences between registry files */ + struct reg_diff_value { char *name; diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 106039361a..b0e1c46d9c 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -125,10 +125,10 @@ int main(int argc, char **argv) if (!h) { print_tree(0, root, fullpath, no_values); } else { - for(i = HKEY_CLASSES_ROOT; i < HKEY_PERFORMANCE_NLSTEXT; i++) { - error = reg_get_predefined_key(h, i, &root); + for(i = 0; reg_predefined_keys[i].handle; i++) { + error = reg_get_predefined_key(h, reg_predefined_keys[i].handle, &root); if (!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Skipping %s\n", reg_get_predef_name(i)); + fprintf(stderr, "Skipping %s\n", reg_predefined_keys[i].name); continue; } print_tree(0, root, fullpath, no_values); -- cgit From e0e8743baf6c34987d56c8b7166a7c928bbdd6a5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 30 Apr 2006 18:46:14 +0000 Subject: r15363: Fix dependencies for shared library (This used to be commit f2ca71f1229f4c20296895116c09bacbd6a53b55) --- source4/lib/registry/tools/regtree.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index b0e1c46d9c..dae8c389c2 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -99,13 +99,13 @@ int main(int argc, char **argv) POPT_TABLEEND }; - registry_init(); - pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); while((opt = poptGetNextOpt(pc)) != -1) { } + registry_init(); + if (remote) { error = reg_open_remote(&h, NULL, cmdline_credentials, remote, NULL); } else if (backend) { -- cgit From ad53de9d599d9ca1b935754d93b455a89198fa37 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 30 Apr 2006 19:22:56 +0000 Subject: r15364: Use global list of predefined keys (This used to be commit eee9e33442f846d278f0fc545480cc2ec8ea295b) --- source4/lib/registry/tools/regshell.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index b71c15cb67..6bcaf42b6c 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -439,23 +439,11 @@ static char **reg_completion(const char *text, int start, int end) } if (h) { - uint32_t try_hkeys[] = { - HKEY_CLASSES_ROOT, - HKEY_CURRENT_USER, - HKEY_LOCAL_MACHINE, - HKEY_USERS, - HKEY_PERFORMANCE_DATA, - HKEY_CURRENT_CONFIG, - HKEY_DYN_DATA, - HKEY_PERFORMANCE_TEXT, - HKEY_PERFORMANCE_NLSTEXT, - 0 - }; int i; - for (i = 0; try_hkeys[i]; i++) { + for (i = 0; reg_predefined_keys[i].handle; i++) { WERROR err; - err = reg_get_predefined_key(h, try_hkeys[i], &curkey); + err = reg_get_predefined_key(h, reg_predefined_keys[i].handle, &curkey); if (W_ERROR_IS_OK(err)) { break; } else { -- cgit From 47bf79eac5c5c23394778b7e20a5263be71a9c66 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 1 May 2006 01:34:04 +0000 Subject: r15370: Fix more dependencies for shared libs (This used to be commit 9a518661fbb76bf1c153afc6f581e888186dc165) --- source4/lib/registry/tools/regpatch.c | 4 ++-- source4/lib/registry/tools/regshell.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 74601d73f9..6e584e90a8 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -42,13 +42,13 @@ int main(int argc, char **argv) POPT_TABLEEND }; - registry_init(); - pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); while((opt = poptGetNextOpt(pc)) != -1) { } + registry_init(); + if (remote) { error = reg_open_remote (&h, NULL, cmdline_credentials, remote, NULL); } else { diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 6bcaf42b6c..dc8ff7723f 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -418,13 +418,13 @@ static char **reg_completion(const char *text, int start, int end) POPT_TABLEEND }; - registry_init(); - pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); while((opt = poptGetNextOpt(pc)) != -1) { } + registry_init(); + if (remote) { error = reg_open_remote (&h, NULL, cmdline_credentials, remote, NULL); } else if (backend) { -- cgit From e595ede02fe9c80a88b5a7da4721c3c01808c276 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 1 May 2006 13:20:05 +0000 Subject: r15375: Rename readline.h to smbreadline.h avoid clashes with system header. (This used to be commit ccc3d8a95441e7a7015f0cf0e622ec9e38347d33) --- source4/lib/registry/tools/regshell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index dc8ff7723f..6da64d14a8 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -25,7 +25,7 @@ #include "lib/events/events.h" #include "lib/registry/reg_backend_rpc.h" #include "system/time.h" -#include "lib/replace/readline.h" +#include "lib/replace/smbreadline.h" #include "librpc/gen_ndr/ndr_security.h" /* -- cgit From 72a5cbadc1498b58bc7873a450de4b50e322a676 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 3 May 2006 09:07:38 +0000 Subject: r15406: Move 'smbreadline' out of libreplace as it doesn't replace functionality not available on some platforms but is a Samba-specific library. (This used to be commit e9d3660fa6678424e5159708a1aa572824926c8e) --- source4/lib/registry/tools/regshell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 6da64d14a8..a1a88378c9 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -25,7 +25,7 @@ #include "lib/events/events.h" #include "lib/registry/reg_backend_rpc.h" #include "system/time.h" -#include "lib/replace/smbreadline.h" +#include "lib/smbreadline/smbreadline.h" #include "librpc/gen_ndr/ndr_security.h" /* -- cgit From bd90da5b60b82c8ddc82fa434aa724fba0749e0c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 5 May 2006 13:16:58 +0000 Subject: r15458: Fix support for Windows XP-style registry files and support for large numbers of subkeys. Patch by Wilco Baan Hofman (This used to be commit 02859870d62b875eca5feff175c489a93fa7ad84) --- source4/lib/registry/reg_backend_nt4.c | 126 ++++++++++++++++++++++++++++++--- source4/lib/registry/regf.idl | 20 +++--- 2 files changed, 126 insertions(+), 20 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index 569b1e1942..1413cb7c5e 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -2,6 +2,7 @@ Samba CIFS implementation Registry backend for REGF files Copyright (C) 2005 Jelmer Vernooij, jelmer@samba.org + Copyright (C) 2006 Wilco Baan Hofman, wilco@baanhofman.nl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -484,8 +485,25 @@ static WERROR regf_get_subkey (TALLOC_CTX *ctx, const struct registry_key *key, } if (!strncmp((char *)data.data, "li", 2)) { - DEBUG(4, ("Subkeys in LI list\n")); - SMB_ASSERT(0); + struct li_block li; + struct tdr_pull pull; + + DEBUG(10, ("Subkeys in LI list\n")); + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { + DEBUG(0, ("Error parsing LI list\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(li.header, "li",2)); + + if (li.key_count != nk->num_subkeys) { + DEBUG(0, ("Subkey counts don't match\n")); + return WERR_GENERAL_FAILURE; + } + key_off = li.nk_offset[idx]; + } else if (!strncmp((char *)data.data, "lf", 2)) { struct lf_block lf; struct tdr_pull pull; @@ -498,19 +516,107 @@ static WERROR regf_get_subkey (TALLOC_CTX *ctx, const struct registry_key *key, DEBUG(0, ("Error parsing LF list\n")); return WERR_GENERAL_FAILURE; } + SMB_ASSERT(!strncmp(lf.header, "lf",2)); if (lf.key_count != nk->num_subkeys) { DEBUG(0, ("Subkey counts don't match\n")); return WERR_GENERAL_FAILURE; } - key_off = lf.hr[idx].nk_off; - } else if (!strncmp((char *)data.data, "ri", 2)) { - DEBUG(4, ("Subkeys in RI list\n")); - SMB_ASSERT(0); + key_off = lf.hr[idx].nk_offset; } else if (!strncmp((char *)data.data, "lh", 2)) { - DEBUG(4, ("Subkeys in LH list\n")); - SMB_ASSERT(0); + struct lh_block lh; + struct tdr_pull pull; + + DEBUG(10, ("Subkeys in LH list")); + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { + DEBUG(0, ("Error parsing LH list\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(lh.header, "lh",2)); + + if (lh.key_count != nk->num_subkeys) { + DEBUG(0, ("Subkey counts don't match\n")); + return WERR_GENERAL_FAILURE; + } + key_off = lh.hr[idx].nk_offset; + } else if (!strncmp((char *)data.data, "ri", 2)) { + struct ri_block ri; + struct tdr_pull pull; + uint16_t i; + uint16_t sublist_count = 0; + + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_ri_block(&pull, nk, &ri))) { + DEBUG(0, ("Error parsing RI list\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(ri.header, "ri",2)); + + for (i = 0; i < ri.key_count; i++) { + DATA_BLOB list_data; + + /* Get sublist data blob */ + list_data = hbin_get(key->hive->backend_data, ri.offset[i]); + if (!list_data.data) { + DEBUG(0, ("Error getting RI list.")); + return WERR_GENERAL_FAILURE; + } + + ZERO_STRUCT(pull); + pull.data = list_data; + + if (!strncmp((char *)list_data.data, "li", 2)) { + struct li_block li; + + if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { + DEBUG(0, ("Error parsing LI list from RI\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(li.header, "li",2)); + + /* Advance to next sublist if necessary */ + if (idx >= sublist_count + li.key_count) { + sublist_count += li.key_count; + continue; + } + key_off = li.nk_offset[idx - sublist_count]; + sublist_count += li.key_count; + break; + } else if (!strncmp((char *)list_data.data, "lh", 2)) { + struct lh_block lh; + + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { + DEBUG(0, ("Error parsing LH list from RI\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(lh.header, "lh",2)); + + + /* Advance to next sublist if necessary */ + if (idx >= sublist_count + lh.key_count) { + sublist_count += lh.key_count; + continue; + } + key_off = lh.hr[idx - sublist_count].nk_offset; + sublist_count += lh.key_count; + break; + } else { + DEBUG(0,("Unknown sublist in ri block\n")); + SMB_ASSERT(0); + } + + } + + if (idx > sublist_count) { + return WERR_NO_MORE_ITEMS; + } + } else { DEBUG(0, ("Unknown type for subkey list (0x%04x): %c%c\n", nk->subkeys_offset, data.data[0], data.data[1])); return WERR_GENERAL_FAILURE; @@ -577,7 +683,7 @@ static uint32_t lf_add_entry (struct regf_data *regf, uint32_t list_offset, cons } lf.hr = talloc_realloc(regf, lf.hr, struct hash_record, lf.key_count+1); - lf.hr[lf.key_count].nk_off = key_offset; + lf.hr[lf.key_count].nk_offset = key_offset; lf.hr[lf.key_count].hash = talloc_strndup(regf, name, 4); lf.key_count++; @@ -736,7 +842,7 @@ static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) regf->hbins = talloc_array(regf, struct hbin_block *, 1); regf->hbins[0] = NULL; - while (pull.offset < pull.data.length) { + while (pull.offset < pull.data.length && pull.offset < regf->header->last_block) { struct hbin_block *hbin = talloc(regf->hbins, struct hbin_block); if (NT_STATUS_IS_ERR(tdr_pull_hbin_block(&pull, hbin, hbin))) { diff --git a/source4/lib/registry/regf.idl b/source4/lib/registry/regf.idl index 8f5db8c236..48a34462e6 100644 --- a/source4/lib/registry/regf.idl +++ b/source4/lib/registry/regf.idl @@ -2,13 +2,13 @@ Definitions for the REGF registry file format as used by Windows NT4 and above. - Written by Jelmer Vernooij, 2005 + Copyright (C) 2005 Jelmer Vernooij, jelmer@samba.org + Copyright (C) 2006 Wilco Baan Hofman, wilco@baanhofman.nl Based on two files from Samba 3: regedit.c by Richard Sharpe regfio.c by Jerry Carter - Thanks to Wilco Baan Hofman for some of the info on li and ri fields. */ interface regf @@ -114,25 +114,25 @@ interface regf uint8 sec_desc[rec_size]; } sk_block; - typedef [noprint,nopush,nopull] struct { - uint32 offset_nk; + typedef [noprint] struct { + uint32 nk_offset; uint32 base37; /* base37 of key name */ } lh_hash; /* Subkey listing with hash of first 4 characters */ - typedef [noprint,nopush,nopull] struct { + typedef [public,noprint] struct { [charset(DOS)] uint8 header[2]; uint16 key_count; - lh_hash hashes[key_count]; + lh_hash hr[key_count]; } lh_block; - typedef [noprint,nopush,nopull] struct { + typedef [public,noprint] struct { [charset(DOS)] uint8 header[2]; uint16 key_count; - uint32 offset_nk[key_count]; + uint32 nk_offset[key_count]; } li_block; - typedef [noprint,nopush,nopull] struct { + typedef [public,noprint] struct { [charset(DOS)] uint8 header[2]; uint16 key_count; uint32 offset[key_count]; /* li/lh offset */ @@ -151,7 +151,7 @@ interface regf } vk_block; typedef [noprint] struct { - uint32 nk_off; + uint32 nk_offset; [charset(DOS)] uint8 hash[4]; } hash_record; -- cgit From 4049bbbea1efafefb0ada396bd1fbd6c6f15431f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 17 May 2006 13:58:53 +0000 Subject: r15659: Implement opening a key by name (significant better performance in some situations). Patch by Wilco Baan Hofman. (This used to be commit dece573d4746bb2df2d129ae6a557a0417e56cda) --- source4/lib/registry/reg_backend_nt4.c | 238 ++++++++++++++++++++++++++++++++- 1 file changed, 236 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index 1413cb7c5e..c5f07e7b19 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -469,7 +469,7 @@ static WERROR regf_get_value (TALLOC_CTX *ctx, const struct registry_key *key, i return WERR_OK; } -static WERROR regf_get_subkey (TALLOC_CTX *ctx, const struct registry_key *key, int idx, struct registry_key **ret) +static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, const struct registry_key *key, int idx, struct registry_key **ret) { DATA_BLOB data; struct nk_block *nk = key->backend_data; @@ -627,6 +627,239 @@ static WERROR regf_get_subkey (TALLOC_CTX *ctx, const struct registry_key *key, return WERR_OK; } +static WERROR regf_match_subkey_by_name (TALLOC_CTX *ctx, const struct registry_key *key, uint32_t offset, const char *name, uint32_t *ret) +{ + DATA_BLOB subkey_data; + struct nk_block subkey; + struct tdr_pull pull; + + subkey_data = hbin_get(key->hive->backend_data, offset); + if (!subkey_data.data) { + DEBUG(0, ("Unable to retrieve subkey HBIN\n")); + return WERR_GENERAL_FAILURE; + } + + ZERO_STRUCT(pull); + pull.data = subkey_data; + + if (NT_STATUS_IS_ERR(tdr_pull_nk_block(&pull, ctx, &subkey))) { + DEBUG(0, ("Error parsing NK structure.\n")); + return WERR_GENERAL_FAILURE; + } + if (strncmp(subkey.header, "nk", 2)) { + DEBUG(0, ("Not an NK structure.\n")); + return WERR_GENERAL_FAILURE; + } + if (!strcasecmp(subkey.key_name, name)) { + *ret = offset; + } else { + *ret = 0; + } + return WERR_OK; +} + +static WERROR regf_get_subkey_by_name (TALLOC_CTX *ctx, const struct registry_key *key, const char *name, struct registry_key **ret) +{ + DATA_BLOB data; + struct nk_block *nk = key->backend_data; + uint32_t key_off = 0; + + data = hbin_get(key->hive->backend_data, nk->subkeys_offset); + if (!data.data) { + DEBUG(0, ("Unable to find subkey list\n")); + return WERR_GENERAL_FAILURE; + } + + if (!strncmp((char *)data.data, "li",2)) { + struct li_block li; + struct tdr_pull pull; + uint16_t i; + + DEBUG(10, ("Subkeys in LI list\n")); + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { + DEBUG(0, ("Error parsing LI list\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(li.header, "li",2)); + + if (li.key_count != nk->num_subkeys) { + DEBUG(0, ("Subkey counts don't match\n")); + return WERR_GENERAL_FAILURE; + } + + for (i = 0; i < li.key_count; i++) { + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, li.nk_offset[i], name, &key_off)); + if (key_off) { + break; + } + } + if (!key_off) { + return WERR_DEST_NOT_FOUND; + } + } else if (!strncmp((char *)data.data, "lf",2)) { + struct lf_block lf; + struct tdr_pull pull; + uint16_t i; + + DEBUG(10, ("Subkeys in LF list\n")); + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, nk, &lf))) { + DEBUG(0, ("Error parsing LF list\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(lf.header, "lf",2)); + + if (lf.key_count != nk->num_subkeys) { + DEBUG(0, ("Subkey counts don't match\n")); + return WERR_GENERAL_FAILURE; + } + + for (i = 0; i < lf.key_count; i++) { + if (strncmp(lf.hr[i].hash, name, 4)) { + continue; + } + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, lf.hr[i].nk_offset, name, &key_off)); + if (key_off) { + break; + } + } + if (!key_off) { + return WERR_DEST_NOT_FOUND; + } + } else if (!strncmp((char *)data.data, "lh",2)) { + struct lh_block lh; + struct tdr_pull pull; + uint16_t i; + uint32_t hash = 0; + char *hash_name; + + DEBUG(10, ("Subkeys in LH list\n")); + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { + DEBUG(0, ("Error parsing LH list\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(lh.header, "lh",2)); + + if (lh.key_count != nk->num_subkeys) { + DEBUG(0, ("Subkey counts don't match\n")); + return WERR_GENERAL_FAILURE; + } + + /* Compute hash for the name */ + hash_name = strupper_talloc(nk, name); + for (i = 0; *(hash_name + i) != 0; i++) { + hash *= 37; + hash += *(hash_name + i); + } + for (i = 0; i < lh.key_count; i++) { + if (lh.hr[i].base37 != hash) { + continue; + } + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, lh.hr[i].nk_offset, name, &key_off)); + if (key_off) { + break; + } + } + if (!key_off) { + return WERR_DEST_NOT_FOUND; + } + } else if (!strncmp((char *)data.data, "ri", 2)) { + struct ri_block ri; + struct tdr_pull pull; + uint16_t i, j; + + DEBUG(10, ("Subkeys in RI list\n")); + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_ri_block(&pull, nk, &ri))) { + DEBUG(0, ("Error parsing RI list\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(ri.header, "ri",2)); + + + for (i = 0; i < ri.key_count; i++) { + DATA_BLOB list_data; + + /* Get sublist data blob */ + list_data = hbin_get(key->hive->backend_data, ri.offset[i]); + if (!list_data.data) { + DEBUG(0, ("Error getting RI list.")); + return WERR_GENERAL_FAILURE; + } + + ZERO_STRUCT(pull); + pull.data = list_data; + + if (!strncmp((char *)list_data.data, "li", 2)) { + struct li_block li; + + if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { + DEBUG(0, ("Error parsing LI list from RI\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(li.header, "li",2)); + + for (j = 0; j < li.key_count; j++) { + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, + li.nk_offset[j], name, &key_off)); + if (key_off) { + break; + } + } + } else if (!strncmp((char *)list_data.data, "lh", 2)) { + struct lh_block lh; + uint32_t hash = 0; + char *hash_name; + + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { + DEBUG(0, ("Error parsing LH list from RI\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(lh.header, "lh",2)); + + /* Compute hash for the name */ + hash_name = strupper_talloc(nk, name); + for (j = 0; *(hash_name + j) != 0; j++) { + hash *= 37; + hash += *(hash_name + j); + } + for (j = 0; j < lh.key_count; j++) { + if (lh.hr[j].base37 != hash) { + continue; + } + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, + lh.hr[j].nk_offset, name, &key_off)); + if (key_off) { + break; + } + } + } + if (key_off) { + break; + } + + } + if (!key_off) { + return WERR_DEST_NOT_FOUND; + } + } else { + DEBUG(0, ("Unknown subkey list type.\n")); + return WERR_GENERAL_FAILURE; + } + + *ret = regf_get_key (ctx, key->hive->backend_data, key_off); + return WERR_OK; +} static WERROR regf_set_sec_desc (const struct registry_key *key, const struct security_descriptor *sec_desc) { @@ -873,7 +1106,8 @@ static struct hive_operations reg_backend_nt4 = { .open_hive = nt_open_hive, .num_subkeys = regf_num_subkeys, .num_values = regf_num_values, - .get_subkey_by_index = regf_get_subkey, + .get_subkey_by_index = regf_get_subkey_by_index, + .get_subkey_by_name = regf_get_subkey_by_name, .get_value_by_index = regf_get_value, .key_get_sec_desc = regf_get_sec_desc, .key_set_sec_desc = regf_set_sec_desc, -- cgit From 9727b061f330ba8f500a29bf4b94992e2bceffbc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 21 May 2006 12:58:39 +0000 Subject: r15776: Don't generate ref pointers in Samba4-generated code. There is no point in having pointers for outgoing data when you can already modify the top-level element. This can be overridden (temporarily) by specifying the new "keepref" attribute. Once we've removed keepref from all IDL files, I'll remove this attribute as well. (This used to be commit bdc6dd37503ced8322a671d225122ccffbb8bfec) --- source4/lib/registry/reg_backend_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 79adad1356..8e70998778 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -280,7 +280,7 @@ static WERROR rpc_query_key(const struct registry_key *k) struct rpc_key_data *mykeydata = k->backend_data; TALLOC_CTX *mem_ctx = talloc_init("query_key"); - init_winreg_String(&r.in.class, NULL); + init_winreg_String(&r.in.class_in, NULL); r.in.handle = &mykeydata->pol; status = dcerpc_winreg_QueryInfoKey((struct dcerpc_pipe *)(k->hive->backend_data), mem_ctx, &r); -- cgit From 73da6bf6dad7e047fbadf22a04b2f62d22ede4bf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 22 May 2006 16:21:52 +0000 Subject: r15806: Remove some unnecessary nesting making the function harder to read. (This used to be commit 2e1ce0189961335f654202074101819d8d933748) --- source4/lib/registry/tools/regshell.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index a1a88378c9..5aa16d2e98 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -90,19 +90,23 @@ static struct registry_key *cmd_pwd(TALLOC_CTX *mem_ctx, struct registry_context static struct registry_key *cmd_set(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) { + struct registry_value val; + WERROR error; + 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.data_type, &val.data)) { - WERROR error = reg_val_set(cur, argv[1], val.data_type, val.data); - 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; + } + + if (!reg_string_to_val(mem_ctx, argv[2], argv[3], &val.data_type, &val.data)) { + fprintf(stderr, "Unable to interpret data\n"); + return cur; + } + + error = reg_val_set(cur, argv[1], val.data_type, val.data); + if (!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Error setting value: %s\n", win_errstr(error)); + return NULL; } return cur; } -- cgit From 029cf10ff839cb4dde25ce1eeb27f24fc637ed28 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 22 May 2006 16:22:38 +0000 Subject: r15807: Fix incorrect initialization. Very nice catch by the IBM Checker. (This used to be commit 2b65c490e40241fb4d4f938a867e33780295ad05) --- source4/lib/registry/common/reg_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index da18102d1f..3d0cdf5a6a 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -122,7 +122,7 @@ _PUBLIC_ BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const break; case REG_NONE: - ZERO_STRUCT(data); + ZERO_STRUCTP(data); break; case REG_BINARY: -- cgit From ab5cbd881307456881b04d13d13e7edfee8e366c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 22 May 2006 16:32:41 +0000 Subject: r15810: Fix uninitialized variable error, caught by the IBM checker. (This used to be commit 1354333fd192e83242e6618458704c1820efac49) --- source4/lib/registry/tools/regtree.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index dae8c389c2..e606e09add 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -122,7 +122,7 @@ int main(int argc, char **argv) error = WERR_OK; - if (!h) { + if (root != NULL) { print_tree(0, root, fullpath, no_values); } else { for(i = 0; reg_predefined_keys[i].handle; i++) { @@ -131,6 +131,7 @@ int main(int argc, char **argv) fprintf(stderr, "Skipping %s\n", reg_predefined_keys[i].name); continue; } + SMB_ASSERT(root); print_tree(0, root, fullpath, no_values); } } -- cgit From 971d30bb201f5c3faff5f575d26882eb79f7955a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 May 2006 07:34:11 +0000 Subject: r15854: more talloc_set_destructor() typesafe fixes (This used to be commit 61c6100617589ac6df4f527877241464cacbf8b3) --- source4/lib/registry/reg_backend_ldb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index ec185cd65b..a8c054cc16 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -32,9 +32,8 @@ struct ldb_key_data int subkey_count, value_count; }; -static int ldb_free_hive (void *_hive) +static int ldb_free_hive (struct registry_hive *hive) { - struct registry_hive *hive = _hive; talloc_free(hive->backend_data); hive->backend_data = NULL; return 0; @@ -96,9 +95,8 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, TALLOC_CT } -static int reg_close_ldb_key (void *data) +static int reg_close_ldb_key(struct registry_key *key) { - struct registry_key *key = data; struct ldb_key_data *kd = talloc_get_type(key->backend_data, struct ldb_key_data); /* struct ldb_context *c = key->hive->backend_data; */ -- cgit From 1bd7f6ae63566f34a78f82712bb005e507968187 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 24 May 2006 22:57:14 +0000 Subject: r15877: Fix error message - caught by the IBM checker (This used to be commit dd0b912fdd107817273391cab223304f0399c3b5) --- source4/lib/registry/tools/regtree.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index e606e09add..c239a11ed4 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -108,16 +108,29 @@ int main(int argc, char **argv) if (remote) { error = reg_open_remote(&h, NULL, cmdline_credentials, remote, NULL); + + if(!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Unable to open remote registry at %s:%s \n", remote, win_errstr(error)); + return 1; + } + } else if (backend) { error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, cmdline_credentials, &root); + + if(!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Unable to open '%s' with backend '%s':%s \n", poptGetArg(pc), backend, win_errstr(error)); + return 1; + } } else { error = reg_open_local (&h, NULL, cmdline_credentials); - } - if(!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Unable to open '%s' with backend '%s':%s \n", poptGetArg(pc), backend, win_errstr(error)); - return 1; + if(!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Unable to open local registry:%s \n", win_errstr(error)); + return 1; + } + } + poptFreeContext(pc); error = WERR_OK; -- cgit From 26875d59ba6d5d6fb9ac75f461953e0ebee6a8f3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 24 May 2006 23:09:29 +0000 Subject: r15878: Add explicit initialization to make the IBM checker happy. (This used to be commit 3a5d3eb62c61d264fb583d2c94e3b3446988051b) --- source4/lib/registry/reg_backend_nt4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index c5f07e7b19..d1d19f904b 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -903,11 +903,11 @@ static uint32_t lf_add_entry (struct regf_data *regf, uint32_t list_offset, cons uint32_t ret; struct lf_block lf; + ZERO_STRUCT(lf); + /* Add to subkeys list */ if (list_offset == -1) { /* Need to create subkeys list */ lf.header = "lf"; - lf.key_count = 0; - lf.hr = NULL; } else { if (!hbin_get_tdr(regf, list_offset, regf, (tdr_pull_fn_t)tdr_pull_lf_block, &lf)) { DEBUG(0, ("Can't get subkeys list\n")); -- cgit From e3a6c6be79326578a1e9c7cb8547234eab62235f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 8 Jun 2006 15:20:05 +0000 Subject: r16100: Patch from Michael Wood : s/then/than/ for correct grammar (This used to be commit 26a2fa97e4c819e630bc9b50e11c8d5328c7b8c8) --- source4/lib/registry/TODO | 2 +- source4/lib/registry/man/regtree.1.xml | 2 +- source4/lib/registry/reg_backend_nt4.c | 2 +- source4/lib/registry/registry.h | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/TODO b/source4/lib/registry/TODO index 518edf6795..562ed5657e 100644 --- a/source4/lib/registry/TODO +++ b/source4/lib/registry/TODO @@ -29,6 +29,6 @@ gregedit.c: - support for adding/deleting keys - support for security descriptors -- pass parsed paths around rather then strings (i.e. just a list of strings) +- pass parsed paths around rather than strings (i.e. just a list of strings) - integrate various registry tools ? - finish new patchfile code diff --git a/source4/lib/registry/man/regtree.1.xml b/source4/lib/registry/man/regtree.1.xml index 98e58070d1..aa31855a2b 100644 --- a/source4/lib/registry/man/regtree.1.xml +++ b/source4/lib/registry/man/regtree.1.xml @@ -30,7 +30,7 @@ The regtree utility prints out all the contents of a Windows registry file. Subkeys are printed with one level - more indentation then their parents. + more indentation than their parents. diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index d1d19f904b..a9759b8e68 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -463,7 +463,7 @@ static WERROR regf_get_value (TALLOC_CTX *ctx, const struct registry_key *key, i } if ((*ret)->data.length < vk->data_length) { - DEBUG(1, ("Read data less then indicated data length!\n")); + DEBUG(1, ("Read data less than indicated data length!\n")); } return WERR_OK; diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 80b412a314..6b3675b0ee 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -103,11 +103,11 @@ struct hive_operations { WERROR (*num_values) (const struct registry_key *, uint32_t *count); WERROR (*get_subkey_by_index) (TALLOC_CTX *, const struct registry_key *, int idx, struct registry_key **); - /* Can not contain more then one level */ + /* Can not contain more than one level */ WERROR (*get_subkey_by_name) (TALLOC_CTX *, const struct registry_key *, const char *name, struct registry_key **); WERROR (*get_value_by_index) (TALLOC_CTX *, const struct registry_key *, int idx, struct registry_value **); - /* Can not contain more then one level */ + /* Can not contain more than one level */ WERROR (*get_value_by_name) (TALLOC_CTX *, const struct registry_key *, const char *name, struct registry_value **); /* Security control */ -- cgit From a23b63a8e54db7d0ec98ad95cdca11dd4d039e17 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 13 Aug 2006 08:00:36 +0000 Subject: r17516: Change helper function names to make more clear what they are meant to do (This used to be commit ad75cf869550af66119d0293503024d41d834e02) --- source4/lib/registry/reg_backend_ldb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index a8c054cc16..f4ed80fa7b 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -42,8 +42,8 @@ static int ldb_free_hive (struct registry_hive *hive) static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, char **name, uint32_t *type, DATA_BLOB *data) { const struct ldb_val *val; - *name = talloc_strdup(mem_ctx, ldb_msg_find_string(msg, "value", NULL)); - *type = ldb_msg_find_uint(msg, "type", 0); + *name = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(msg, "value", NULL)); + *type = ldb_msg_find_attr_as_uint(msg, "type", 0); val = ldb_msg_find_ldb_val(msg, "data"); switch (*type) -- cgit From 1cecad25224a13de3b561ae36b8e530b152c81be Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Aug 2006 18:50:03 +0000 Subject: r17713: fix compiler warnings metze (This used to be commit 21142ad7a2d37489e295d725c8700be0bb921091) --- source4/lib/registry/reg_backend_ldb.c | 2 +- source4/lib/registry/registry.h | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index f4ed80fa7b..d723b1dbe4 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -39,7 +39,7 @@ static int ldb_free_hive (struct registry_hive *hive) return 0; } -static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, char **name, uint32_t *type, DATA_BLOB *data) +static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char **name, uint32_t *type, DATA_BLOB *data) { const struct ldb_val *val; *name = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(msg, "value", NULL)); diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 6b3675b0ee..e5cf7d9111 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -55,9 +55,9 @@ extern const struct reg_predefined_key reg_predefined_keys[]; /* structure to store the registry handles */ struct registry_key { - char *name; + const char *name; const char *path; - char *class_name; + const char *class_name; NTTIME last_mod; struct registry_hive *hive; void *backend_data; @@ -65,7 +65,7 @@ struct registry_key struct registry_value { - char *name; + const char *name; unsigned int data_type; DATA_BLOB data; }; @@ -156,7 +156,7 @@ struct reg_init_function_entry { struct reg_diff_value { - char *name; + const char *name; enum { REG_DIFF_DEL_VAL, REG_DIFF_SET_VAL } changetype; uint32_t type; DATA_BLOB data; @@ -164,7 +164,7 @@ struct reg_diff_value struct reg_diff_key { - char *name; + const char *name; enum { REG_DIFF_CHANGE_KEY, REG_DIFF_DEL_KEY } changetype; uint32_t numvalues; struct reg_diff_value *values; @@ -172,7 +172,7 @@ struct reg_diff_key struct reg_diff { - char *format; + const char *format; uint32_t numkeys; struct reg_diff_key *keys; }; -- cgit From b49f18f0e5e02f6959e3589c65016946eedcaa94 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 24 Aug 2006 08:17:31 +0000 Subject: r17773: this macros are unsed, with compiler warnings metze (This used to be commit 3953d3566e41d0a189be38aee3d99805dd71961a) --- source4/lib/registry/reg_backend_w95.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95.c index 1d3781c583..6624f3c8a0 100644 --- a/source4/lib/registry/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95.c @@ -123,8 +123,10 @@ typedef struct creg_struct_s { RGDB_KEY ***rgdb_keys; } CREG; +#if 0 /* unused */ #define RGKN_START_SIZE 0x2000 #define RGKN_INC_SIZE 0x1000 +#endif #define LOCN_RGKN(creg, o) ((RGKN_KEY *)((creg)->base + sizeof(CREG_HDR) + o)) #define LOCN_RGDB_BLOCK(creg, o) (((creg)->base + (creg)->creg_hdr->rgdb_offset + o)) -- cgit From 0329d755a7611ba3897fc1ee9bdce410cc33d7f8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 30 Aug 2006 11:29:34 +0000 Subject: r17930: Merge noinclude branch: * Move dlinklist.h, smb.h to subsystem-specific directories * Clean up ads.h and move what is left of it to dsdb/ (only place where it's used) (This used to be commit f7afa1cb77f3cfa7020b57de12e6003db7cfcc42) --- source4/lib/registry/common/reg_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index 7d65d31d0f..e0f06ef795 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -19,7 +19,7 @@ */ #include "includes.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "lib/registry/registry.h" #include "build.h" -- cgit From b7477fb3881ac4490da040b054094a865128b951 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Sep 2006 00:35:29 +0000 Subject: r18117: first steps in making samba4 use libreplace (This used to be commit c079cedb084d621c5a0aac59310b237ba375df20) --- source4/lib/registry/config.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 89a77c231e..d979f9fb99 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -110,7 +110,7 @@ PUBLIC_HEADERS = registry.h INSTALLDIR = BINDIR OBJ_FILES = tools/regdiff.o PRIVATE_DEPENDENCIES = \ - LIBSAMBA-CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS + LIBSAMBA-CONFIG registry POPT_EXT POPT_SAMBA POPT_CREDENTIALS MANPAGE = man/regdiff.1 # End BINARY regdiff ################################################ @@ -121,7 +121,7 @@ MANPAGE = man/regdiff.1 INSTALLDIR = BINDIR OBJ_FILES = tools/regpatch.o PRIVATE_DEPENDENCIES = \ - LIBSAMBA-CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS + LIBSAMBA-CONFIG registry POPT_EXT POPT_SAMBA POPT_CREDENTIALS MANPAGE = man/regpatch.1 # End BINARY regpatch ################################################ @@ -132,7 +132,7 @@ MANPAGE = man/regpatch.1 INSTALLDIR = BINDIR OBJ_FILES = tools/regshell.o PRIVATE_DEPENDENCIES = \ - LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \ + LIBSAMBA-CONFIG POPT_EXT registry POPT_SAMBA POPT_CREDENTIALS \ SMBREADLINE MANPAGE = man/regshell.1 # End BINARY regshell @@ -144,7 +144,7 @@ MANPAGE = man/regshell.1 INSTALLDIR = BINDIR OBJ_FILES = tools/regtree.o PRIVATE_DEPENDENCIES = \ - LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS + LIBSAMBA-CONFIG POPT_EXT registry POPT_SAMBA POPT_CREDENTIALS MANPAGE = man/regtree.1 # End BINARY regtree ################################################ -- cgit From a59706f721c70e9a4f78eb2296bb746b912ce9d0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 6 Sep 2006 01:36:02 +0000 Subject: r18121: Simplify m4 code, hopefully fix Samba4 build problems. (This used to be commit 1adf65b4d7c5d2d4f65d4b28575bdf2368a42139) --- source4/lib/registry/config.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index d979f9fb99..89a77c231e 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -110,7 +110,7 @@ PUBLIC_HEADERS = registry.h INSTALLDIR = BINDIR OBJ_FILES = tools/regdiff.o PRIVATE_DEPENDENCIES = \ - LIBSAMBA-CONFIG registry POPT_EXT POPT_SAMBA POPT_CREDENTIALS + LIBSAMBA-CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS MANPAGE = man/regdiff.1 # End BINARY regdiff ################################################ @@ -121,7 +121,7 @@ MANPAGE = man/regdiff.1 INSTALLDIR = BINDIR OBJ_FILES = tools/regpatch.o PRIVATE_DEPENDENCIES = \ - LIBSAMBA-CONFIG registry POPT_EXT POPT_SAMBA POPT_CREDENTIALS + LIBSAMBA-CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS MANPAGE = man/regpatch.1 # End BINARY regpatch ################################################ @@ -132,7 +132,7 @@ MANPAGE = man/regpatch.1 INSTALLDIR = BINDIR OBJ_FILES = tools/regshell.o PRIVATE_DEPENDENCIES = \ - LIBSAMBA-CONFIG POPT_EXT registry POPT_SAMBA POPT_CREDENTIALS \ + LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \ SMBREADLINE MANPAGE = man/regshell.1 # End BINARY regshell @@ -144,7 +144,7 @@ MANPAGE = man/regshell.1 INSTALLDIR = BINDIR OBJ_FILES = tools/regtree.o PRIVATE_DEPENDENCIES = \ - LIBSAMBA-CONFIG POPT_EXT registry POPT_SAMBA POPT_CREDENTIALS + LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS MANPAGE = man/regtree.1 # End BINARY regtree ################################################ -- cgit From 014f70008fcfdb631031c48aa9654ad5b42e62f9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Sep 2006 04:58:06 +0000 Subject: r18130: the move to system/ in libreplace broke some things ... should be happier now (This used to be commit 18542f184f75074e56a9793a9e3b6c6d747bb9e6) --- source4/lib/registry/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 89a77c231e..4f719a9c07 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -34,6 +34,7 @@ INIT_FUNCTION = registry_w95_init SUBSYSTEM = registry OBJ_FILES = \ reg_backend_w95.o +PUBLIC_DEPENDENCIES = LIBREPLACE # End MODULE registry_w95 ################################################ -- cgit From 873749f2189ecf1fbfdc681df4dd304a17716279 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 6 Sep 2006 12:28:01 +0000 Subject: r18168: Use {NULL} rather than POPT_TABLEEND, which is not always available. (This used to be commit 8b622c5ded0732df0eaf9f6226f52a27b6eacd73) --- source4/lib/registry/tools/regdiff.c | 2 +- source4/lib/registry/tools/regpatch.c | 2 +- source4/lib/registry/tools/regshell.c | 2 +- source4/lib/registry/tools/regtree.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index c7e6f87792..dbbe555ad6 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -43,7 +43,7 @@ int main(int argc, char **argv) POPT_COMMON_SAMBA POPT_COMMON_CREDENTIALS POPT_COMMON_VERSION - POPT_TABLEEND + { NULL } }; registry_init(); diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 6e584e90a8..7ed246566c 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -39,7 +39,7 @@ int main(int argc, char **argv) {"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL}, POPT_COMMON_SAMBA POPT_COMMON_CREDENTIALS - POPT_TABLEEND + { NULL } }; pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 5aa16d2e98..0bc1cfe324 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -419,7 +419,7 @@ static char **reg_completion(const char *text, int start, int end) POPT_COMMON_SAMBA POPT_COMMON_CREDENTIALS POPT_COMMON_VERSION - POPT_TABLEEND + { NULL } }; pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index c239a11ed4..31f5a89a1b 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -96,7 +96,7 @@ int main(int argc, char **argv) {"no-values", 'V', POPT_ARG_NONE, &no_values, 0, "don't show values", NULL}, POPT_COMMON_SAMBA POPT_COMMON_CREDENTIALS - POPT_TABLEEND + { NULL } }; pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); -- cgit From 78eaffd5a009d62a272c9647520ba76d720bb494 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Sep 2006 13:15:37 +0000 Subject: r18176: reg_util.c needs LIBREPLACE for strndup (This used to be commit dc1369b2ad1f55e1acfcc2ddd99ec6ac8b115da9) --- source4/lib/registry/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 4f719a9c07..599fade97f 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -99,7 +99,7 @@ OBJ_FILES = \ reg_samba.o \ patchfile.o PUBLIC_DEPENDENCIES = \ - LIBSAMBA-UTIL CHARSET + LIBSAMBA-UTIL CHARSET LIBREPLACE PRIVATE_PROTO_HEADER = registry_proto.h PUBLIC_HEADERS = registry.h # End MODULE registry_ldb -- cgit From a46e12d0e07e1630f8ef15aff0f97cb2f1f4c273 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 7 Sep 2006 10:02:32 +0000 Subject: r18213: don't list LIBREPLACE depdendecies explicit and always at it as first private dependencies metze (This used to be commit 135d096776b53ae09ffc2b4f767dfbd18139570f) --- source4/lib/registry/config.mk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 599fade97f..89a77c231e 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -34,7 +34,6 @@ INIT_FUNCTION = registry_w95_init SUBSYSTEM = registry OBJ_FILES = \ reg_backend_w95.o -PUBLIC_DEPENDENCIES = LIBREPLACE # End MODULE registry_w95 ################################################ @@ -99,7 +98,7 @@ OBJ_FILES = \ reg_samba.o \ patchfile.o PUBLIC_DEPENDENCIES = \ - LIBSAMBA-UTIL CHARSET LIBREPLACE + LIBSAMBA-UTIL CHARSET PRIVATE_PROTO_HEADER = registry_proto.h PUBLIC_HEADERS = registry.h # End MODULE registry_ldb -- cgit From d6c4147a41fb37ea78c62cd10173f100c9a9e9c3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 9 Sep 2006 09:20:26 +0000 Subject: r18298: fixed mmap failure test (This used to be commit dee6551dc36789506a59bcd3242f208d5bfd5d6f) --- source4/lib/registry/reg_backend_w95.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95.c index 6624f3c8a0..05b84fdc61 100644 --- a/source4/lib/registry/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95.c @@ -204,7 +204,7 @@ static WERROR w95_open_reg (struct registry_hive *h, struct registry_key **root) creg->base = mmap(0, creg->sbuf.st_size, PROT_READ, MAP_SHARED, creg->fd, 0); - if ((int)creg->base == 1) { + if (creg->base == (void *)-1) { DEBUG(0,("Could not mmap file: %s, %s\n", h->location, strerror(errno))); return WERR_FOOBAR; } -- cgit From cac69cdd743c8ce93631a0ddd37a8d3344ce8259 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 10 Sep 2006 10:30:33 +0000 Subject: r18324: fixed a uninitialised variable (This used to be commit 08562d6ebe6b2c48026f0d1e97ec4dd8ea215b2c) --- source4/lib/registry/reg_backend_nt4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index a9759b8e68..bf08bc6077 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -473,7 +473,7 @@ static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, const struct registry_k { DATA_BLOB data; struct nk_block *nk = key->backend_data; - uint32_t key_off; + uint32_t key_off=0; if (idx >= nk->num_subkeys) return WERR_NO_MORE_ITEMS; -- cgit From 2696cc312021ce927012228c9ce199dba4775b9e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 10 Sep 2006 11:16:26 +0000 Subject: r18328: when we bail out early, set *offset to 0 (This used to be commit 81230464600bd3a2bb283303b2b9c71f6409675b) --- source4/lib/registry/reg_backend_nt4.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index bf08bc6077..758d1c2453 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -133,6 +133,8 @@ static DATA_BLOB hbin_alloc (struct regf_data *data, uint32_t size, uint32_t *of struct hbin_block *hbin = NULL; int i; + *offset = 0; + if (size == 0) return data_blob(NULL, 0); -- cgit From dce0c9e4fd6c47f44694fd276c3a91b689312ccd Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 15 Sep 2006 18:34:03 +0000 Subject: r18561: Fix [out] pointers in winreg IDL (This used to be commit 694677dafefdd94fa0a9bed93efab70c528dcb26) --- source4/lib/registry/reg_backend_rpc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 8e70998778..5e0cf303e0 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -152,7 +152,7 @@ static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, const struct registry_key *h, co /* Then, open the handle using the hive */ memset(&r, 0, sizeof(struct winreg_OpenKey)); - r.in.handle = &(((struct rpc_key_data *)h->backend_data)->pol); + r.in.parent_handle = &(((struct rpc_key_data *)h->backend_data)->pol); init_winreg_String(&r.in.keyname, name); r.in.unknown = 0x00000000; r.in.access_mask = 0x02000000; @@ -230,7 +230,7 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, const struct registry r.in.handle = &mykeydata->pol; r.in.enum_index = n; r.in.name = &namebuf; - r.in.class = &classbuf; + r.in.keyclass = &classbuf; r.in.last_changed_time = &change_time; r.out.name = &namebuf; @@ -249,7 +249,7 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, const struct registry_key *parent struct winreg_CreateKey r; init_winreg_String(&r.in.name, name); - init_winreg_String(&r.in.class, NULL); + init_winreg_String(&r.in.keyclass, NULL); r.in.handle = parent->backend_data; r.out.new_handle = talloc(mem_ctx, struct policy_handle); @@ -292,10 +292,10 @@ static WERROR rpc_query_key(const struct registry_key *k) } if (W_ERROR_IS_OK(r.out.result)) { - mykeydata->num_subkeys = r.out.num_subkeys; - mykeydata->num_values = r.out.num_values; - mykeydata->max_valnamelen = r.out.max_valnamelen; - mykeydata->max_valdatalen = r.out.max_valbufsize; + mykeydata->num_subkeys = *r.out.num_subkeys; + mykeydata->num_values = *r.out.num_values; + mykeydata->max_valnamelen = *r.out.max_valnamelen; + mykeydata->max_valdatalen = *r.out.max_valbufsize; } return r.out.result; -- cgit From 655b710204e7a7d8e486da7ba675fcbeed116fea Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 16 Sep 2006 16:59:37 +0000 Subject: r18584: found one of the fd leaks. The registry backend was using a talloc(NULL, xxx) to allocate the registry context. That had two consequences 1) it was a massive memory leak, as all winreg operations leaked their entire context (including an open ldb database) every time 2) event_context_find() never found the exsting event context, so we used a new event context each time, which called epoll_create() each time, which caused a fd to be allocated (This used to be commit 1c0a3de39828b43149d8981fc7f10e7c8b59a392) --- source4/lib/registry/reg_samba.c | 7 +++++-- source4/lib/registry/tools/regdiff.c | 4 ++-- source4/lib/registry/tools/regpatch.c | 2 +- source4/lib/registry/tools/regshell.c | 2 +- source4/lib/registry/tools/regtree.c | 2 +- 5 files changed, 10 insertions(+), 7 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_samba.c b/source4/lib/registry/reg_samba.c index 4a88d96042..3553c4cb6d 100644 --- a/source4/lib/registry/reg_samba.c +++ b/source4/lib/registry/reg_samba.c @@ -68,9 +68,12 @@ static WERROR reg_samba_get_predef (struct registry_context *ctx, uint32_t hkey, return error; } -_PUBLIC_ WERROR reg_open_local (struct registry_context **ctx, struct auth_session_info *session_info, struct cli_credentials *credentials) +_PUBLIC_ WERROR reg_open_local (TALLOC_CTX *mem_ctx, + struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials) { - *ctx = talloc(NULL, struct registry_context); + *ctx = talloc(mem_ctx, struct registry_context); (*ctx)->credentials = talloc_reference(*ctx, credentials); (*ctx)->session_info = talloc_reference(*ctx, session_info); (*ctx)->get_predefined_key = reg_samba_get_predef; diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index dbbe555ad6..b8bf654a6b 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -54,8 +54,8 @@ int main(int argc, char **argv) error = WERR_OK; switch(opt) { case 'L': - if (!h1 && !from_null) error = reg_open_local(&h1, NULL, cmdline_credentials); - else if (!h2) error = reg_open_local(&h2, NULL, cmdline_credentials); + if (!h1 && !from_null) error = reg_open_local(NULL, &h1, NULL, cmdline_credentials); + else if (!h2) error = reg_open_local(NULL, &h2, NULL, cmdline_credentials); break; case 'R': if (!h1 && !from_null) diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 7ed246566c..42cdac860b 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -52,7 +52,7 @@ int main(int argc, char **argv) if (remote) { error = reg_open_remote (&h, NULL, cmdline_credentials, remote, NULL); } else { - error = reg_open_local (&h, NULL, cmdline_credentials); + error = reg_open_local (NULL, &h, NULL, cmdline_credentials); } if (W_ERROR_IS_OK(error)) { diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 0bc1cfe324..8436a3f505 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -434,7 +434,7 @@ static char **reg_completion(const char *text, int start, int end) } else if (backend) { error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, cmdline_credentials, &curkey); } else { - error = reg_open_local(&h, NULL, cmdline_credentials); + error = reg_open_local(NULL, &h, NULL, cmdline_credentials); } if(!W_ERROR_IS_OK(error)) { diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 31f5a89a1b..6b3c20eae3 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -122,7 +122,7 @@ int main(int argc, char **argv) return 1; } } else { - error = reg_open_local (&h, NULL, cmdline_credentials); + error = reg_open_local (NULL, &h, NULL, cmdline_credentials); if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open local registry:%s \n", win_errstr(error)); -- cgit From 318682b00377605a26d0b7fd4b59713c6c429b81 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 28 Sep 2006 06:44:47 +0000 Subject: r18971: avoid strndup is a few places. Fixes a minor memory leak, and should fix RPC-LSA on AIX. (This used to be commit 6cce709d08579f4e00b44b692332a557b0ea3b86) --- source4/lib/registry/common/reg_util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index 3d0cdf5a6a..a8d7accb3d 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -171,9 +171,9 @@ WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, co if(strchr(name, '\\')) predeflength = strchr(name, '\\')-name; else predeflength = strlen(name); - predefname = strndup(name, predeflength); + predefname = talloc_strndup(mem_ctx, name, predeflength); error = reg_get_predefined_key_by_name(handle, predefname, &predef); - SAFE_FREE(predefname); + talloc_free(predefname); if(!W_ERROR_IS_OK(error)) { return error; -- cgit From 59b66744f7318d8197f0d2029bf3b641dafa327e Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 15 Oct 2006 23:14:19 +0000 Subject: r19299: Fix possible memleaks (This used to be commit 6fad80bb09113a60689061a2de67711c9924708b) --- source4/lib/registry/reg_backend_ldb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index d723b1dbe4..8edbc5a085 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -240,6 +240,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct registry_key *h, co DEBUG(0, ("Error opening key '%s': %s\n", ldb_dn_linearize(ldap_path, ldap_path), ldb_errstring(c))); return WERR_FOOBAR; } else if (res->count == 0) { + talloc_free(res); return WERR_BADFILE; } -- cgit From 403f0c92a734a9bf7709a0af0a0aa9cc89bf3144 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 18 Oct 2006 21:37:37 +0000 Subject: r19400: fixed a valgrind error in the directory registry backend (name was used after closedir(), which invalidates the name) (This used to be commit d8af519c2d2fcab3baa822c5fd4c1079dcbd1de3) --- source4/lib/registry/reg_backend_dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_dir.c b/source4/lib/registry/reg_backend_dir.c index beedc0615b..8348f6c38a 100644 --- a/source4/lib/registry/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir.c @@ -99,9 +99,9 @@ static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, const struct registry_ke if(S_ISDIR(stbuf.st_mode)) { if(i == idx) { (*key) = talloc(mem_ctx, struct registry_key); - (*key)->name = e->d_name; + (*key)->name = talloc_strdup(*key, e->d_name); (*key)->path = NULL; - (*key)->backend_data = talloc_strdup(mem_ctx, thispath); + (*key)->backend_data = talloc_strdup(*key, thispath); SAFE_FREE(thispath); closedir(d); return WERR_OK; -- cgit From 7f833458ca0083654e34cbfde1c6c6510cab1826 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 25 Oct 2006 01:42:59 +0000 Subject: r19489: Change ldb_msg_add_value and ldb_msg_add_empty to take a foruth argument. This is a pointer to an element pointer. If it is not null it will be filled with the pointer of the manipulated element. Will avoid double searches on the elements list in some cases. (This used to be commit 0fa5d4bc225b83e9f63ac6d75bffc4c08eb6b620) --- source4/lib/registry/reg_backend_ldb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 8edbc5a085..b9bfe8a230 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -77,14 +77,14 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, TALLOC_CT case REG_SZ: case REG_EXPAND_SZ: val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8, (void *)data.data, data.length, (void **)&val.data); - ldb_msg_add_value(msg, "data", &val); + ldb_msg_add_value(msg, "data", &val, NULL); break; case REG_DWORD: ldb_msg_add_string(msg, "data", talloc_asprintf(mem_ctx, "0x%x", IVAL(data.data, 0))); break; default: - ldb_msg_add_value(msg, "data", &data); + ldb_msg_add_value(msg, "data", &data, NULL); } -- cgit From 13dbee3ffea6065a826f010e50c9b4eb2c6ad109 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 7 Nov 2006 00:48:36 +0000 Subject: r19598: Ahead of a merge to current lorikeet-heimdal: Break up auth/auth.h not to include the world. Add credentials_krb5.h with the kerberos dependent prototypes. Andrew Bartlett (This used to be commit 2b569c42e0fbb596ea82484d0e1cb22e193037b9) --- source4/lib/registry/registry.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index e5cf7d9111..4c1eb8f39e 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -23,7 +23,6 @@ #define _REGISTRY_H #include "librpc/gen_ndr/security.h" -#include "auth/credentials/credentials.h" /* Handles for the predefined keys */ #define HKEY_CLASSES_ROOT 0x80000000 @@ -128,6 +127,8 @@ struct hive_operations { WERROR (*del_value)(const struct registry_key *, const char *valname); }; +struct cli_credentials; + struct registry_hive { const struct hive_operations *functions; -- cgit From 4889eb9f7aae9349e426d0f6d2217adff67eaebd Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 22 Nov 2006 00:59:34 +0000 Subject: r19831: Big ldb_dn optimization and interfaces enhancement patch This patch changes a lot of the code in ldb_dn.c, and also removes and add a number of manipulation functions around. The aim is to avoid validating a dn if not necessary as the validation code is necessarily slow. This is mainly to speed up internal operations where input is not user generated and so we can assume the DNs need no validation. The code is designed to keep the data as a string if possible. The code is not yet 100% perfect, but pass all the tests so far. A memleak is certainly present, I'll work on that next. Simo. (This used to be commit a580c871d3784602a9cce32d33419e63c8236e63) --- source4/lib/registry/reg_backend_ldb.c | 39 ++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 13 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index b9bfe8a230..5f9481fa67 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -27,7 +27,7 @@ struct ldb_key_data { - const struct ldb_dn *dn; + struct ldb_dn *dn; struct ldb_message **subkeys, **values; int subkey_count, value_count; }; @@ -115,15 +115,24 @@ static int reg_close_ldb_key(struct registry_key *key) static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const struct registry_key *from, const char *path, const char *add) { TALLOC_CTX *local_ctx; - struct ldb_dn *ret = ldb_dn_new(mem_ctx); + struct ldb_dn *ret; char *mypath = talloc_strdup(mem_ctx, path); char *begin; struct ldb_key_data *kd = talloc_get_type(from->backend_data, struct ldb_key_data); + struct ldb_context *ldb = talloc_get_type(from->hive->backend_data, struct ldb_context); local_ctx = talloc_new(mem_ctx); - if (add) - ret = ldb_dn_compose(local_ctx, ret, ldb_dn_explode(mem_ctx, add)); + if (add) { + ret = ldb_dn_new(mem_ctx, ldb, add); + } else { + ret = ldb_dn_new(mem_ctx, ldb, NULL); + } + if ( ! ldb_dn_validate(ret)) { + talloc_free(ret); + talloc_free(local_ctx); + return NULL; + } while(mypath) { char *keyname; @@ -134,10 +143,7 @@ static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const struct registry else keyname = mypath; if(strlen(keyname)) { - struct ldb_dn *base; - - base = ldb_dn_build_child(local_ctx, "key", keyname, NULL); - ret = ldb_dn_compose(local_ctx, ret, base); + ldb_dn_add_base_fmt(ret, "key=%s", keyname); } if(begin) { @@ -147,7 +153,7 @@ static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const struct registry } } - ret = ldb_dn_compose(mem_ctx, ret, kd->dn); + ldb_dn_add_base(ret, kd->dn); talloc_free(local_ctx); @@ -277,7 +283,7 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) talloc_set_destructor (hive, ldb_free_hive); (*k)->name = talloc_strdup(*k, ""); (*k)->backend_data = kd = talloc_zero(*k, struct ldb_key_data); - kd->dn = ldb_dn_explode(*k, "hive=NONE"); + kd->dn = ldb_dn_new(*k, wrap, "hive=NONE"); return WERR_OK; @@ -316,7 +322,10 @@ static WERROR ldb_del_key (const struct registry_key *key, const char *child) struct ldb_context *ctx = talloc_get_type(key->hive->backend_data, struct ldb_context); int ret; struct ldb_key_data *kd = talloc_get_type(key->backend_data, struct ldb_key_data); - struct ldb_dn *childdn = ldb_dn_build_child(ctx, "key", child, kd->dn); + struct ldb_dn *childdn; + + childdn = ldb_dn_copy(ctx, kd->dn); + ldb_dn_add_child_fmt(childdn, "key=%s", child); ret = ldb_delete(ctx, childdn); @@ -335,7 +344,10 @@ static WERROR ldb_del_value (const struct registry_key *key, const char *child) int ret; struct ldb_context *ctx = talloc_get_type(key->hive->backend_data, struct ldb_context); struct ldb_key_data *kd = talloc_get_type(key->backend_data, struct ldb_key_data); - struct ldb_dn *childdn = ldb_dn_build_child(ctx, "value", child, kd->dn); + struct ldb_dn *childdn; + + childdn = ldb_dn_copy(ctx, kd->dn); + ldb_dn_add_child_fmt(childdn, "value=%s", child); ret = ldb_delete(ctx, childdn); @@ -359,7 +371,8 @@ static WERROR ldb_set_value (const struct registry_key *parent, const char *name msg = reg_ldb_pack_value(ctx, mem_ctx, name, type, data); - msg->dn = ldb_dn_build_child(msg, "value", name, kd->dn); + msg->dn = ldb_dn_copy(msg, kd->dn); + ldb_dn_add_child_fmt(msg->dn, "value=%s", name); ret = ldb_add(ctx, msg); if (ret < 0) { -- cgit From a9e31b33b55a873c2f01db5e348560176adf863d Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 22 Nov 2006 02:05:19 +0000 Subject: r19832: better prototypes for the linearization functions: - ldb_dn_get_linearized returns a const string - ldb_dn_alloc_linearized allocs astring with the linearized dn (This used to be commit 3929c086d5d0b3f08b1c4f2f3f9602c3f4a9a4bd) --- source4/lib/registry/reg_backend_ldb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 5f9481fa67..5d72eabfdd 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -176,7 +176,7 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, const struct registry_ke ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &res); if (ret != LDB_SUCCESS) { - DEBUG(0, ("Error getting subkeys for '%s': %s\n", ldb_dn_linearize(mem_ctx, kd->dn), ldb_errstring(c))); + DEBUG(0, ("Error getting subkeys for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); return WERR_FOOBAR; } @@ -213,7 +213,7 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct registry_key ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(value=*)", NULL, &res); if (ret != LDB_SUCCESS) { - DEBUG(0, ("Error getting values for '%s': %s\n", ldb_dn_linearize(mem_ctx, kd->dn), ldb_errstring(c))); + DEBUG(0, ("Error getting values for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); return WERR_FOOBAR; } kd->value_count = res->count; @@ -243,7 +243,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct registry_key *h, co ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL, &res); if (ret != LDB_SUCCESS) { - DEBUG(0, ("Error opening key '%s': %s\n", ldb_dn_linearize(ldap_path, ldap_path), ldb_errstring(c))); + DEBUG(0, ("Error opening key '%s': %s\n", ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); return WERR_FOOBAR; } else if (res->count == 0) { talloc_free(res); -- cgit From 97416e6b011a3c733d07f83073bf12796c7ecc6b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 12 Feb 2007 12:12:12 +0000 Subject: r21297: Remove the GTK+ tools and library from the main repository. They are now maintained separately in bzr at http://people.samba.org/bzr/jelmer/samba-gtk This also adds some more headers to the list that is installed and a couple of extra #include lines so these headers can be used externally without problems. (This used to be commit 07652f65ce7a5b19130f1a27cbf0e1e5fae13454) --- source4/lib/registry/config.mk | 4 ++-- source4/lib/registry/registry.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 89a77c231e..8d6761e6c7 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -52,7 +52,7 @@ PUBLIC_DEPENDENCIES = LIBTALLOC # Start MODULE registry_rpc [MODULE::registry_rpc] INIT_FUNCTION = registry_rpc_init -PRIVATE_PROTO_HEADER = reg_backend_rpc.h +PUBLIC_PROTO_HEADER = reg_backend_rpc.h OUTPUT_TYPE = INTEGRATED SUBSYSTEM = registry OBJ_FILES = \ @@ -99,7 +99,7 @@ OBJ_FILES = \ patchfile.o PUBLIC_DEPENDENCIES = \ LIBSAMBA-UTIL CHARSET -PRIVATE_PROTO_HEADER = registry_proto.h +PUBLIC_PROTO_HEADER = registry_proto.h PUBLIC_HEADERS = registry.h # End MODULE registry_ldb ################################################ diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 4c1eb8f39e..d67f1c2be8 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -22,6 +22,8 @@ #ifndef _REGISTRY_H /* _REGISTRY_H */ #define _REGISTRY_H +#include "core.h" +#include "talloc.h" #include "librpc/gen_ndr/security.h" /* Handles for the predefined keys */ -- cgit From f851eb8dc662c72242388a01dedbfc0f4ec0dfe1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 12 Feb 2007 13:04:09 +0000 Subject: r21299: Fix the build for those that don't have talloc.h installed. (This used to be commit e782035251fd3d51a7a4221d107519fb1ba70ba7) --- source4/lib/registry/registry.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index d67f1c2be8..4bf422d027 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -23,7 +23,7 @@ #define _REGISTRY_H #include "core.h" -#include "talloc.h" +#include "talloc/talloc.h" #include "librpc/gen_ndr/security.h" /* Handles for the predefined keys */ -- cgit From b7a46675fb1157ab235008edf841ae7eed628049 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 16 Feb 2007 15:13:51 +0000 Subject: r21386: Run all NDR tests in the buildfarm, import some functions from Samba3's IDL. (This used to be commit 15a4b81ba0b5eeb25126a0b1a7bea7d3bf921ab2) --- source4/lib/registry/reg_backend_rpc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 5e0cf303e0..7e81023acb 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -280,7 +280,8 @@ static WERROR rpc_query_key(const struct registry_key *k) struct rpc_key_data *mykeydata = k->backend_data; TALLOC_CTX *mem_ctx = talloc_init("query_key"); - init_winreg_String(&r.in.class_in, NULL); + r.in.classname = talloc(mem_ctx, struct winreg_String); + init_winreg_String(r.in.classname, NULL); r.in.handle = &mykeydata->pol; status = dcerpc_winreg_QueryInfoKey((struct dcerpc_pipe *)(k->hive->backend_data), mem_ctx, &r); -- cgit From 0515f728e64dde0c197aee6180dce79ad281d5f8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 Feb 2007 18:44:56 +0000 Subject: r21433: Get rid of the COM support code - it's not used and unmaintained. We can always bring it back if we need to. This code was getting in the way while refactoring. Add some tests for TDR. Get rid of typedef in lib/registry/tdr_regf.idl and fix the TDR code to be able to deal with it. (This used to be commit 1ad0f99a439f0d52a735b391bf9900d50171aca5) --- source4/lib/registry/regf.idl | 52 +++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/regf.idl b/source4/lib/registry/regf.idl index 48a34462e6..e313dfc4da 100644 --- a/source4/lib/registry/regf.idl +++ b/source4/lib/registry/regf.idl @@ -22,12 +22,12 @@ interface regf * 1.5.0.1 for WinXP */ - typedef [noprint] struct { + [noprint] struct regf_version { [value(1)] uint32 major; [value(3)] uint32 minor; [value(0)] uint32 release; [value(1)] uint32 build; - } regf_version; + }; /* "regf" is obviously the abbreviation for "Registry file". "regf" is the @@ -36,7 +36,7 @@ interface regf the first 0x200 bytes only! */ - typedef [public,noprint] struct { + [public,noprint] struct regf_hdr { [charset(DOS)] uint8 REGF_ID[4]; /* 'regf' */ uint32 update_counter1; uint32 update_counter2; @@ -49,14 +49,14 @@ interface regf uint32 padding[83]; /* Padding */ /* Checksum of first 0x200 bytes XOR-ed */ uint32 chksum; - } regf_hdr; + }; /* hbin probably means hive-bin (i.e. hive-container) This block is always a multiple of 4kb in size. */ - typedef [public,noprint] struct { + [public,noprint] struct hbin_block { [charset(DOS)] uint8 HBIN_ID[4]; /* hbin */ uint32 offset_from_first; /* Offset from 1st hbin-Block */ uint32 offset_to_next; /* Offset to the next hbin-Block */ @@ -71,19 +71,19 @@ interface regf uint8_t data[length]; Free space marker if 0xffffffff */ - } hbin_block; + }; - typedef [base_type(uint16),noprint] enum { + [base_type(uint16),noprint] enum reg_key_type { REG_ROOT_KEY = 0x20, REG_SUB_KEY = 0x2C, REG_SYM_LINK = 0x10 - } reg_key_type; + }; /* The nk-record can be treated as a combination of tree-record and key-record of the win 95 registry. */ - typedef [public,noprint] struct { + [public,noprint] struct nk_block { [charset(DOS)] uint8 header[2]; reg_key_type type; NTTIME last_change; @@ -101,10 +101,10 @@ interface regf [value(strlen(key_name))] uint16 name_length; uint16 clsname_length; [charset(DOS)] uint8 key_name[name_length]; - } nk_block; + }; /* sk (? Security Key ?) is the ACL of the registry. */ - typedef [noprint,public] struct { + [noprint,public] struct sk_block { [charset(DOS)] uint8 header[2]; uint16 tag; uint32 prev_offset; @@ -112,34 +112,34 @@ interface regf uint32 ref_cnt; uint32 rec_size; uint8 sec_desc[rec_size]; - } sk_block; + }; - typedef [noprint] struct { + [noprint] struct lh_hash { uint32 nk_offset; uint32 base37; /* base37 of key name */ - } lh_hash; + }; /* Subkey listing with hash of first 4 characters */ - typedef [public,noprint] struct { + [public,noprint] struct lh_block { [charset(DOS)] uint8 header[2]; uint16 key_count; lh_hash hr[key_count]; - } lh_block; + }; - typedef [public,noprint] struct { + [public,noprint] struct li_block { [charset(DOS)] uint8 header[2]; uint16 key_count; uint32 nk_offset[key_count]; - } li_block; + }; - typedef [public,noprint] struct { + [public,noprint] struct ri_block { [charset(DOS)] uint8 header[2]; uint16 key_count; uint32 offset[key_count]; /* li/lh offset */ - } ri_block; + }; /* The vk-record consists information to a single value (value key). */ - typedef [public,noprint] struct { + [public,noprint] struct vk_block { [charset(DOS)] uint8 header[2]; [value(strlen(data_name))] uint16 name_length; uint32 data_length; /* If top-bit set, offset contains the data */ @@ -148,20 +148,20 @@ interface regf uint16 flag; /* =1, has name, else no name (=Default). */ uint16 unk1; [charset(DOS)] uint8 data_name[name_length]; - } vk_block; + }; - typedef [noprint] struct { + [noprint] struct hash_record { uint32 nk_offset; [charset(DOS)] uint8 hash[4]; - } hash_record; + }; /* The lf-record is the counterpart to the RGKN-record (the hash-function) */ - typedef [public,noprint] struct { + [public,noprint] struct lf_block { [charset(DOS)] uint8 header[2]; uint16 key_count; hash_record hr[key_count]; /* Array of hash records, depending on key_count */ - } lf_block; + }; } -- cgit From 1afda7bdde90948027e3230c19753280afb16e96 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 2 Mar 2007 14:53:09 +0000 Subject: r21656: Move tests a bit closer to the things they test, should make syncing with samba3 easier. (This used to be commit 4d755fb5d7adedd1dd8bad917b921324411bfd59) --- source4/lib/registry/tests/generic.c | 93 ++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 source4/lib/registry/tests/generic.c (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/generic.c b/source4/lib/registry/tests/generic.c new file mode 100644 index 0000000000..d200ba6e1b --- /dev/null +++ b/source4/lib/registry/tests/generic.c @@ -0,0 +1,93 @@ +/* + Unix SMB/CIFS implementation. + + local testing of registry library + + Copyright (C) Jelmer Vernooij 2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "lib/registry/registry.h" +#include "lib/cmdline/popt_common.h" +#include "torture/torture.h" + +const static struct test_backend_settings { + const char *name; + const char *location; +} backends[] = { + { "nt4", "TEST.DAT" }, + { "ldb", "test.ldb" }, + { "gconf", "." }, + { "dir", "." }, + { NULL, NULL } +}; + +static bool test_hive(struct torture_context *tctx, + const void *test_data) +{ + WERROR error; + struct registry_key *root, *subkey; + uint32_t count; + const struct test_backend_settings *backend = test_data; + TALLOC_CTX *mem_ctx = tctx; + + if (!reg_has_backend(backend->name)) { + torture_skip(tctx, talloc_asprintf(tctx, + "Backend '%s' support not compiled in", backend->name)); + } + + error = reg_open_hive(mem_ctx, backend->name, + backend->location, NULL, cmdline_credentials, &root); + torture_assert_werr_ok(tctx, error, "reg_open_hive()"); + + /* This is a new backend. There should be no subkeys and no + * values */ + error = reg_key_num_subkeys(root, &count); + torture_assert_werr_ok(tctx, error, "reg_key_num_subkeys()"); + + torture_assert(tctx, count != 0, "New key has non-zero subkey count"); + + error = reg_key_num_values(root, &count); + torture_assert_werr_ok(tctx, error, "reg_key_num_values"); + + torture_assert(tctx, count != 0, "New key has non-zero value count"); + + error = reg_key_add_name(mem_ctx, root, "Nested\\Key", SEC_MASK_GENERIC, NULL, &subkey); + torture_assert_werr_ok(tctx, error, "reg_key_add_name"); + + error = reg_key_del(root, "Nested\\Key"); + torture_assert_werr_ok(tctx, error, "reg_key_del"); + + talloc_free(root); + return true; +} + + +struct torture_suite *torture_registry(TALLOC_CTX *mem_ctx) +{ + struct torture_suite *suite = torture_suite_create(mem_ctx, + "REGISTRY"); + int i; + + registry_init(); + + for (i = 0; backends[i].name; i++) { + torture_suite_add_simple_tcase(suite, backends[i].name, test_hive, &backends[i]); + } + + return suite; +} -- cgit From e4659536626b758adb884005d1bf60290481a1e9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 4 Mar 2007 18:21:59 +0000 Subject: r21683: Remove the gconf registry backend. It's already been disabled for a while, as it required some compile flags that broke other things. While this backend was an interesting proof-of-concept, this module doesn't really add any value. It's not possible to map between windows registry and gconf semantics and I can't think of any reason why you would want to do so. (This used to be commit 02481df3e8653ab366cb73d124e52bc9551bb717) --- source4/lib/registry/config.m4 | 12 -- source4/lib/registry/config.mk | 13 -- source4/lib/registry/reg_backend_gconf.c | 197 ------------------------------- 3 files changed, 222 deletions(-) delete mode 100644 source4/lib/registry/config.m4 delete mode 100644 source4/lib/registry/reg_backend_gconf.c (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.m4 b/source4/lib/registry/config.m4 deleted file mode 100644 index 852c74b4ab..0000000000 --- a/source4/lib/registry/config.m4 +++ /dev/null @@ -1,12 +0,0 @@ -# Registry backends -SMB_ENABLE(registry_gconf, NO) - -SMB_EXT_LIB_FROM_PKGCONFIG(gconf, gconf-2.0) - -AC_ARG_ENABLE(reg-gconf, -[ --enable-reg-gconf Enable support for GConf registry backend], -[ - if test t$enable = tyes; then - SMB_ENABLE(registry_gconf, $SMB_ENABLE_gconf) - fi -]) diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 8d6761e6c7..a7fe1113c7 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -61,19 +61,6 @@ PUBLIC_DEPENDENCIES = RPC_NDR_WINREG # End MODULE registry_rpc ################################################ - - -################################################ -# Start MODULE registry_gconf -[MODULE::registry_gconf] -INIT_FUNCTION = registry_gconf_init -SUBSYSTEM = registry -OBJ_FILES = \ - reg_backend_gconf.o -PUBLIC_DEPENDENCIES = gconf -# End MODULE registry_gconf -################################################ - ################################################ # Start MODULE registry_ldb [MODULE::registry_ldb] diff --git a/source4/lib/registry/reg_backend_gconf.c b/source4/lib/registry/reg_backend_gconf.c deleted file mode 100644 index 9986f6f71a..0000000000 --- a/source4/lib/registry/reg_backend_gconf.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Registry interface - Copyright (C) Jelmer Vernooij 2004. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" -#include "registry.h" -#include - -static WERROR gerror_to_werror(GError *error) -{ - if(error == NULL) return WERR_OK; - /* FIXME */ - return WERR_FOOBAR; -} - -static WERROR reg_open_gconf_hive(struct registry_hive *h, struct registry_key **k) -{ - g_type_init(); - h->backend_data = (void *)gconf_client_get_default(); - if(!h->backend_data) return WERR_FOOBAR; - - *k = talloc(h, struct registry_key); - (*k)->name = talloc_strdup(*k, ""); - (*k)->path = talloc_strdup(*k, ""); - (*k)->backend_data = talloc_strdup(*k, "/"); - return WERR_OK; -} - -static WERROR gconf_open_key (TALLOC_CTX *mem_ctx, struct registry_key *h, const char *name, struct registry_key **key) -{ - struct registry_key *ret; - char *fullpath; - - fullpath = talloc_asprintf(mem_ctx, "%s%s%s", - (char *)h->backend_data, - strlen((char *)h->backend_data) == 1?"":"/", - reg_path_win2unix(talloc_strdup(mem_ctx, name))); - - /* Check if key exists */ - if(!gconf_client_dir_exists((GConfClient *)h->hive->backend_data, fullpath, NULL)) { - return WERR_DEST_NOT_FOUND; - } - - ret = talloc(mem_ctx, struct registry_key); - ret->backend_data = fullpath; - - *key = ret; - return WERR_OK; -} - -static WERROR gconf_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *p, int idx, struct registry_value **val) -{ - GSList *entries; - GSList *cur; - GConfEntry *entry; - GConfValue *value; - struct registry_value *newval; - char *fullpath = p->backend_data; - const char *tmp; - int i; - cur = entries = gconf_client_all_entries((GConfClient*)p->hive->backend_data, fullpath, NULL); - - for(i = 0; i < idx && cur; i++) cur = cur->next; - - if(!cur) return WERR_NO_MORE_ITEMS; - - entry = cur->data; - value = gconf_entry_get_value(entry); - - newval = talloc(mem_ctx, struct registry_value); - newval->name = talloc_strdup(mem_ctx, strrchr(gconf_entry_get_key(entry), '/')+1); - if(value) { - switch(value->type) { - case GCONF_VALUE_INVALID: - newval->data_type = REG_NONE; - break; - - case GCONF_VALUE_STRING: - newval->data_type = REG_SZ; - tmp = gconf_value_get_string(value); - newval->data_len = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, tmp, strlen(tmp), &(newval->data_blk)); - break; - - case GCONF_VALUE_INT: - newval->data_type = REG_DWORD; - newval->data_blk = talloc(mem_ctx, long); - *((long *)newval->data_blk) = gconf_value_get_int(value); - newval->data_len = sizeof(long); - break; - - case GCONF_VALUE_FLOAT: - newval->data_blk = talloc(mem_ctx, double); - newval->data_type = REG_BINARY; - *((double *)newval->data_blk) = gconf_value_get_float(value); - newval->data_len = sizeof(double); - break; - - case GCONF_VALUE_BOOL: - newval->data_blk = talloc(mem_ctx, BOOL); - newval->data_type = REG_BINARY; - *((BOOL *)newval->data_blk) = gconf_value_get_bool(value); - newval->data_len = sizeof(BOOL); - break; - - default: - newval->data_type = REG_NONE; - DEBUG(0, ("Not implemented..\n")); - break; - } - } else newval->data_type = REG_NONE; - - g_slist_free(entries); - *val = newval; - return WERR_OK; -} - -static WERROR gconf_get_subkey_by_id(TALLOC_CTX *mem_ctx, struct registry_key *p, int idx, struct registry_key **sub) -{ - GSList *dirs; - GSList *cur; - int i; - char *fullpath = p->backend_data; - cur = dirs = gconf_client_all_dirs((GConfClient*)p->hive->backend_data, fullpath,NULL); - - for(i = 0; i < idx && cur; i++) cur = cur->next; - - if(!cur) return WERR_NO_MORE_ITEMS; - - *sub = talloc(mem_ctx, struct registry_key); - (*sub)->name = talloc_strdup(mem_ctx, strrchr((char *)cur->data, '/')+1); - (*sub)->backend_data = talloc_strdup(mem_ctx, cur->data); - - g_slist_free(dirs); - return WERR_OK; -} - -static WERROR gconf_set_value(struct registry_key *key, const char *valname, uint32_t type, void *data, int len) -{ - GError *error = NULL; - char *valpath; - asprintf(&valpath, "%s/%s", key->path, valname); - - switch(type) { - case REG_SZ: - case REG_EXPAND_SZ: - gconf_client_set_string((GConfClient *)key->hive->backend_data, valpath, data, &error); - SAFE_FREE(valpath); - return gerror_to_werror(error); - - case REG_DWORD: - gconf_client_set_int((GConfClient *)key->hive->backend_data, valpath, - *((int *)data), &error); - SAFE_FREE(valpath); - return gerror_to_werror(error); - default: - DEBUG(0, ("Unsupported type: %d\n", type)); - SAFE_FREE(valpath); - return WERR_NOT_SUPPORTED; - } - - return WERR_NOT_SUPPORTED; -} - -static struct hive_operations reg_backend_gconf = { - .name = "gconf", - .open_hive = reg_open_gconf_hive, - .open_key = gconf_open_key, - .get_subkey_by_index = gconf_get_subkey_by_id, - .get_value_by_index = gconf_get_value_by_id, - .set_value = gconf_set_value, - - /* Note: - * since GConf uses schemas for what keys and values are allowed, there - * is no way of 'emulating' add_key and del_key here. - */ -}; - -NTSTATUS registry_gconf_init(void) -{ - return registry_register(®_backend_gconf); -} -- cgit From d693c2707ba77405fbe42bf6441cc397dd9007a1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 4 Mar 2007 19:52:16 +0000 Subject: r21685: Add some unit tests for the registry utility functions. (This used to be commit 0ae6d18ebe382a378ff1dc65069c629d8060ac2b) --- source4/lib/registry/tests/generic.c | 109 ++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 46 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/generic.c b/source4/lib/registry/tests/generic.c index d200ba6e1b..ac4ab98fc0 100644 --- a/source4/lib/registry/tests/generic.c +++ b/source4/lib/registry/tests/generic.c @@ -24,70 +24,87 @@ #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" #include "torture/torture.h" +#include "librpc/gen_ndr/winreg.h" -const static struct test_backend_settings { - const char *name; - const char *location; -} backends[] = { - { "nt4", "TEST.DAT" }, - { "ldb", "test.ldb" }, - { "gconf", "." }, - { "dir", "." }, - { NULL, NULL } -}; - -static bool test_hive(struct torture_context *tctx, - const void *test_data) +static bool test_str_regtype(struct torture_context *ctx) { - WERROR error; - struct registry_key *root, *subkey; - uint32_t count; - const struct test_backend_settings *backend = test_data; - TALLOC_CTX *mem_ctx = tctx; + torture_assert_str_equal(ctx, str_regtype(1), "REG_SZ", "REG_SZ failed"); + torture_assert_str_equal(ctx, str_regtype(4), "REG_DWORD", "REG_DWORD failed"); - if (!reg_has_backend(backend->name)) { - torture_skip(tctx, talloc_asprintf(tctx, - "Backend '%s' support not compiled in", backend->name)); - } - - error = reg_open_hive(mem_ctx, backend->name, - backend->location, NULL, cmdline_credentials, &root); - torture_assert_werr_ok(tctx, error, "reg_open_hive()"); + return true; +} - /* This is a new backend. There should be no subkeys and no - * values */ - error = reg_key_num_subkeys(root, &count); - torture_assert_werr_ok(tctx, error, "reg_key_num_subkeys()"); - torture_assert(tctx, count != 0, "New key has non-zero subkey count"); +static bool test_reg_val_data_string_dword(struct torture_context *ctx) +{ + uint32_t d = 0x20; + DATA_BLOB db = { (uint8_t *)&d, sizeof(d) }; + torture_assert_str_equal(ctx, "0x20", reg_val_data_string(ctx, REG_DWORD, &db), "dword failed"); + return true; +} - error = reg_key_num_values(root, &count); - torture_assert_werr_ok(tctx, error, "reg_key_num_values"); +static bool test_reg_val_data_string_sz(struct torture_context *ctx) +{ + DATA_BLOB db; + db.length = convert_string_talloc(ctx, CH_UNIX, CH_UTF16, "bla", 3, (void **)&db.data); + torture_assert_str_equal(ctx, "bla", reg_val_data_string(ctx, REG_SZ, &db), "sz failed"); + db.length = 4; + torture_assert_str_equal(ctx, "bl", reg_val_data_string(ctx, REG_SZ, &db), "sz failed"); + return true; +} - torture_assert(tctx, count != 0, "New key has non-zero value count"); +static bool test_reg_val_data_string_binary(struct torture_context *ctx) +{ + uint8_t x[] = { 0x1, 0x2, 0x3, 0x4 }; + DATA_BLOB db = { x, 4 }; + torture_assert_str_equal(ctx, "01020304", reg_val_data_string(ctx, REG_BINARY, &db), "binary failed"); + return true; +} - error = reg_key_add_name(mem_ctx, root, "Nested\\Key", SEC_MASK_GENERIC, NULL, &subkey); - torture_assert_werr_ok(tctx, error, "reg_key_add_name"); - error = reg_key_del(root, "Nested\\Key"); - torture_assert_werr_ok(tctx, error, "reg_key_del"); +static bool test_reg_val_data_string_empty(struct torture_context *ctx) +{ + DATA_BLOB db = { NULL, 0 }; + torture_assert_str_equal(ctx, "", reg_val_data_string(ctx, REG_BINARY, &db), "empty failed"); + return true; +} - talloc_free(root); +static bool test_reg_val_description(struct torture_context *ctx) +{ + struct registry_value val; + val.name = "camel"; + val.data_type = REG_SZ; + val.data.length = convert_string_talloc(ctx, CH_UNIX, CH_UTF16, "stationary traveller", + strlen("stationary traveller"), (void **)&val.data.data); + torture_assert_str_equal(ctx, "camel = REG_SZ : stationary traveller", reg_val_description(ctx, &val), + "reg_val_description failed"); return true; } +static bool test_reg_val_description_nullname(struct torture_context *ctx) +{ + struct registry_value val; + val.name = NULL; + val.data_type = REG_SZ; + val.data.length = convert_string_talloc(ctx, CH_UNIX, CH_UTF16, "west berlin", + strlen("west berlin"), (void **)&val.data.data); + torture_assert_str_equal(ctx, " = REG_SZ : west berlin", reg_val_description(ctx, &val), + "description with null name failed"); + return true; +} + struct torture_suite *torture_registry(TALLOC_CTX *mem_ctx) { struct torture_suite *suite = torture_suite_create(mem_ctx, "REGISTRY"); - int i; - - registry_init(); - - for (i = 0; backends[i].name; i++) { - torture_suite_add_simple_tcase(suite, backends[i].name, test_hive, &backends[i]); - } + torture_suite_add_simple_test(suite, "str_regtype", test_str_regtype); + torture_suite_add_simple_test(suite, "reg_val_data_string dword", test_reg_val_data_string_dword); + torture_suite_add_simple_test(suite, "reg_val_data_string sz", test_reg_val_data_string_sz); + torture_suite_add_simple_test(suite, "reg_val_data_string binary", test_reg_val_data_string_binary); + torture_suite_add_simple_test(suite, "reg_val_data_string empty", test_reg_val_data_string_empty); + torture_suite_add_simple_test(suite, "reg_val_description", test_reg_val_description); + torture_suite_add_simple_test(suite, "reg_val_description null", test_reg_val_description_nullname); return suite; } -- cgit From c1c34c4179f887e42088192bacc984def213d451 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 13 Mar 2007 20:08:44 +0000 Subject: r21828: Hardcode prototypes, as they're a public API. (This used to be commit 02ae0b9cde8a18498bc72583d8cac9b0217da4ad) --- source4/lib/registry/config.mk | 1 - source4/lib/registry/registry.h | 49 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index a7fe1113c7..78752ae988 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -86,7 +86,6 @@ OBJ_FILES = \ patchfile.o PUBLIC_DEPENDENCIES = \ LIBSAMBA-UTIL CHARSET -PUBLIC_PROTO_HEADER = registry_proto.h PUBLIC_HEADERS = registry.h # End MODULE registry_ldb ################################################ diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 4bf422d027..7475720fcf 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -183,6 +183,53 @@ struct reg_diff struct auth_session_info; struct event_context; -#include "lib/registry/registry_proto.h" +_PUBLIC_ WERROR reg_open_local (TALLOC_CTX *mem_ctx, + struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials); + +_PUBLIC_ NTSTATUS registry_register(const void *_hive_ops); +_PUBLIC_ NTSTATUS registry_init(void); +_PUBLIC_ BOOL reg_has_backend(const char *backend); +_PUBLIC_ int reg_list_predefs(TALLOC_CTX *mem_ctx, char ***predefs, uint32_t **hkeys); +_PUBLIC_ const char *reg_get_predef_name(uint32_t hkey); +_PUBLIC_ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, const char *name, struct registry_key **key); +_PUBLIC_ WERROR reg_get_predefined_key(struct registry_context *ctx, uint32_t hkey, struct registry_key **key); +_PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *backend, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, struct registry_key **root); +_PUBLIC_ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, struct registry_key **result); +_PUBLIC_ WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *key, int idx, struct registry_value **val); +_PUBLIC_ WERROR reg_key_num_subkeys(const struct registry_key *key, uint32_t *count); +_PUBLIC_ WERROR reg_key_num_values(const struct registry_key *key, uint32_t *count); +_PUBLIC_ WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *key, int idx, struct registry_key **subkey); +WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char *name, struct registry_key **subkey); +_PUBLIC_ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char *name, struct registry_value **val); +_PUBLIC_ WERROR reg_key_del(struct registry_key *parent, const char *name); +_PUBLIC_ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, const struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *desc, struct registry_key **newkey); +_PUBLIC_ WERROR reg_val_set(struct registry_key *key, const char *value, uint32_t type, DATA_BLOB data); +_PUBLIC_ WERROR reg_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, struct security_descriptor **secdesc); +_PUBLIC_ WERROR reg_del_value(const struct registry_key *key, const char *valname); +_PUBLIC_ WERROR reg_key_flush(const struct registry_key *key); +_PUBLIC_ WERROR reg_key_subkeysizes(const struct registry_key *key, uint32_t *max_subkeylen, uint32_t *max_subkeysize); +_PUBLIC_ WERROR reg_key_valuesizes(const struct registry_key *key, uint32_t *max_valnamelen, uint32_t *max_valbufsize); + +/* Utility functions */ + +_PUBLIC_ const char *str_regtype(int type); +_PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, DATA_BLOB *data); +_PUBLIC_ char *reg_val_description(TALLOC_CTX *mem_ctx, struct registry_value *val) ; +_PUBLIC_ BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data); +char *reg_path_win2unix(char *path) ; +char *reg_path_unix2win(char *path) ; +WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result); +WERROR reg_key_del_abs(struct registry_context *ctx, const char *path); +WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx, const char *path, uint32_t access_mask, struct security_descriptor *sec_desc, struct registry_key **result); + + +/* Patch files */ + +_PUBLIC_ struct reg_diff *reg_generate_diff(TALLOC_CTX *mem_ctx, struct registry_context *ctx1, struct registry_context *ctx2); +_PUBLIC_ WERROR reg_diff_save(const struct reg_diff *diff, const char *filename); +_PUBLIC_ struct reg_diff *reg_diff_load(TALLOC_CTX *ctx, const char *fn); +_PUBLIC_ BOOL reg_diff_apply (const struct reg_diff *diff, struct registry_context *ctx); #endif /* _REGISTRY_H */ -- cgit From 606c0fec4315bf10eb50b8ab656204b086446e3d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 13 Mar 2007 20:44:14 +0000 Subject: r21830: Fix header installation, remove proto header with a single prototype. (This used to be commit 47a17a741af625eb52f611b3d0f3ea0e207f2c3a) --- source4/lib/registry/config.mk | 1 - source4/lib/registry/registry.h | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 78752ae988..fd38d3a4f9 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -52,7 +52,6 @@ PUBLIC_DEPENDENCIES = LIBTALLOC # Start MODULE registry_rpc [MODULE::registry_rpc] INIT_FUNCTION = registry_rpc_init -PUBLIC_PROTO_HEADER = reg_backend_rpc.h OUTPUT_TYPE = INTEGRATED SUBSYSTEM = registry OBJ_FILES = \ diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 7475720fcf..509e66b5fd 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -188,6 +188,11 @@ _PUBLIC_ WERROR reg_open_local (TALLOC_CTX *mem_ctx, struct auth_session_info *session_info, struct cli_credentials *credentials); +_PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + const char *location, struct event_context *ev); + _PUBLIC_ NTSTATUS registry_register(const void *_hive_ops); _PUBLIC_ NTSTATUS registry_init(void); _PUBLIC_ BOOL reg_has_backend(const char *backend); @@ -232,4 +237,6 @@ _PUBLIC_ WERROR reg_diff_save(const struct reg_diff *diff, const char *filename) _PUBLIC_ struct reg_diff *reg_diff_load(TALLOC_CTX *ctx, const char *fn); _PUBLIC_ BOOL reg_diff_apply (const struct reg_diff *diff, struct registry_context *ctx); +NTSTATUS registry_rpc_init(void); + #endif /* _REGISTRY_H */ -- cgit From 4f0c0997ce39ecb2920c1d52b03d77e1d50cd5bf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 13 Mar 2007 22:03:04 +0000 Subject: r21834: Remove unnecessary includes (This used to be commit 7d10e192caa60b816466a9deddf736afd2445080) --- source4/lib/registry/tools/regdiff.c | 1 - source4/lib/registry/tools/regpatch.c | 1 - source4/lib/registry/tools/regshell.c | 1 - source4/lib/registry/tools/regtree.c | 1 - 4 files changed, 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index b8bf654a6b..ab6f7c1a57 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -22,7 +22,6 @@ #include "includes.h" #include "lib/registry/registry.h" #include "lib/events/events.h" -#include "lib/registry/reg_backend_rpc.h" #include "lib/cmdline/popt_common.h" int main(int argc, char **argv) diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 42cdac860b..16fe4f498a 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -23,7 +23,6 @@ #include "lib/events/events.h" #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" -#include "lib/registry/reg_backend_rpc.h" int main(int argc, char **argv) { diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 8436a3f505..ac41a99765 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -23,7 +23,6 @@ #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" #include "lib/events/events.h" -#include "lib/registry/reg_backend_rpc.h" #include "system/time.h" #include "lib/smbreadline/smbreadline.h" #include "librpc/gen_ndr/ndr_security.h" diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 6b3c20eae3..e8291a69c2 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -22,7 +22,6 @@ #include "includes.h" #include "lib/registry/registry.h" #include "lib/events/events.h" -#include "lib/registry/reg_backend_rpc.h" #include "lib/cmdline/popt_common.h" static void print_tree(int l, struct registry_key *p, int fullpath, int novals) -- cgit From 00d74b84e902e4d9ef4874637822d1ae5697275f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 14 Mar 2007 00:44:29 +0000 Subject: r21837: Make dcerpc_mgmt a separate library again, as the linker leaves it out when it's part of dcerpc. (This used to be commit dc4428553ec2749ef1ba24fbffeaabf0af6bf364) --- source4/lib/registry/registry.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 509e66b5fd..29aa226539 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -183,6 +183,10 @@ struct reg_diff struct auth_session_info; struct event_context; +#ifndef _PUBLIC_ +#define _PUBLIC_ +#endif + _PUBLIC_ WERROR reg_open_local (TALLOC_CTX *mem_ctx, struct registry_context **ctx, struct auth_session_info *session_info, -- cgit From 2882b2ba63ea65c806643f86d996513414c827d0 Mon Sep 17 00:00:00 2001 From: James Peach Date: Mon, 2 Apr 2007 17:06:14 +0000 Subject: r22029: Make sure we respect $srcdir correctly for the srcdir != builddir case. (This used to be commit 0db4256a472975c5097135fa87315038a1350a72) --- source4/lib/registry/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index fd38d3a4f9..e63141ba1b 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -20,7 +20,7 @@ lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c $(srcdir)/lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c lib/registry/tdr_regf.h: lib/registry/tdr_regf.c lib/registry/tdr_regf.c: $(srcdir)/lib/registry/regf.idl - @CPP="$(CPP)" $(PERL) $(srcdir)/pidl/pidl $(PIDL_ARGS) \ + @CPP="$(CPP)" srcdir="$(srcdir)" $(PERL) $(srcdir)/pidl/pidl $(PIDL_ARGS) \ --header --outputdir=lib/registry \ --tdr-parser -- $(srcdir)/lib/registry/regf.idl -- cgit From 44760c3e6f206a24a298406f88354a069c36245c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Apr 2007 11:00:20 +0000 Subject: r22404: more dependencies which should be private metze (This used to be commit e0e35965d1eaab182941d17da744b70c4234ca52) --- source4/lib/registry/config.mk | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index e63141ba1b..4f44c3ca1f 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -7,7 +7,7 @@ INIT_FUNCTION = registry_nt4_init SUBSYSTEM = registry OBJ_FILES = \ reg_backend_nt4.o -PUBLIC_DEPENDENCIES = TDR_REGF +PRIVATE_DEPENDENCIES = TDR_REGF # End MODULE registry_nt4 ################################################ @@ -44,7 +44,7 @@ INIT_FUNCTION = registry_dir_init SUBSYSTEM = registry OBJ_FILES = \ reg_backend_dir.o -PUBLIC_DEPENDENCIES = LIBTALLOC +PRIVATE_DEPENDENCIES = LIBTALLOC # End MODULE registry_dir ################################################ @@ -56,7 +56,7 @@ OUTPUT_TYPE = INTEGRATED SUBSYSTEM = registry OBJ_FILES = \ reg_backend_rpc.o -PUBLIC_DEPENDENCIES = RPC_NDR_WINREG +PRIVATE_DEPENDENCIES = RPC_NDR_WINREG # End MODULE registry_rpc ################################################ @@ -67,7 +67,7 @@ INIT_FUNCTION = registry_ldb_init SUBSYSTEM = registry OBJ_FILES = \ reg_backend_ldb.o -PUBLIC_DEPENDENCIES = \ +PRIVATE_DEPENDENCIES = \ ldb # End MODULE registry_ldb ################################################ @@ -83,7 +83,7 @@ OBJ_FILES = \ common/reg_util.o \ reg_samba.o \ patchfile.o -PUBLIC_DEPENDENCIES = \ +PRIVATE_DEPENDENCIES = \ LIBSAMBA-UTIL CHARSET PUBLIC_HEADERS = registry.h # End MODULE registry_ldb -- cgit From cc26fe9b749d00bc7c002f6a5a24ff67af497c49 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 8 May 2007 21:17:58 +0000 Subject: r22762: Some ldb_map changes: * Change license to LGPL, so it can be used by non-Samba users of LDB (cleared with Martin as well). * Include ldb_map in standalone build. * Move ldb_map to its own directory (This used to be commit a90202abca26c0da5425a2f3dd8494077c3290fd) --- source4/lib/registry/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 4f44c3ca1f..cea37e7e2f 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -68,7 +68,7 @@ SUBSYSTEM = registry OBJ_FILES = \ reg_backend_ldb.o PRIVATE_DEPENDENCIES = \ - ldb + LIBLDB # End MODULE registry_ldb ################################################ -- cgit From d291b8bf933e7595ac2967602d90918c286e3429 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 20 Jun 2007 04:15:39 +0000 Subject: r23551: Change data_blob_equal to data_blob_cmp, suitable for sorting with qsort(). Andrew Bartlett (This used to be commit 96ef5259c63ad6245c94c40d6059d736b1534183) --- source4/lib/registry/patchfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index bb37e4bb6a..8bbca07962 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -125,7 +125,7 @@ static WERROR reg_generate_diff_key(struct reg_diff *diff, struct registry_key * return error2; } - if (W_ERROR_IS_OK(error2) && data_blob_equal(&v1->data, &v2->data)) + if (W_ERROR_IS_OK(error2) && data_blob_cmp(&v1->data, &v2->data) == 0) continue; thiskey = diff_find_add_key(diff, oldkey->path); -- cgit From 0479a2f1cbae51fcd8dbdc3c148c808421fb4d25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:07:03 +0000 Subject: r23792: convert Samba4 to GPLv3 There are still a few tidyups of old FSF addresses to come (in both s3 and s4). More commits soon. (This used to be commit fcf38a38ac691abd0fa51b89dc951a08e89fdafa) --- source4/lib/registry/common/reg_interface.c | 5 ++--- source4/lib/registry/common/reg_util.c | 5 ++--- source4/lib/registry/patchfile.c | 5 ++--- source4/lib/registry/reg_backend_dir.c | 5 ++--- source4/lib/registry/reg_backend_ldb.c | 5 ++--- source4/lib/registry/reg_backend_nt4.c | 5 ++--- source4/lib/registry/reg_backend_rpc.c | 5 ++--- source4/lib/registry/reg_backend_w95.c | 5 ++--- source4/lib/registry/reg_backend_wine.c | 5 ++--- source4/lib/registry/reg_samba.c | 5 ++--- source4/lib/registry/registry.h | 5 ++--- source4/lib/registry/tests/generic.c | 5 ++--- source4/lib/registry/tools/regdiff.c | 5 ++--- source4/lib/registry/tools/regpatch.c | 5 ++--- source4/lib/registry/tools/regshell.c | 5 ++--- source4/lib/registry/tools/regtree.c | 5 ++--- 16 files changed, 32 insertions(+), 48 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c index e0f06ef795..6ee8a726dc 100644 --- a/source4/lib/registry/common/reg_interface.c +++ b/source4/lib/registry/common/reg_interface.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c index a8d7accb3d..696336161e 100644 --- a/source4/lib/registry/common/reg_util.c +++ b/source4/lib/registry/common/reg_util.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index 8bbca07962..12847eedd8 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/lib/registry/reg_backend_dir.c b/source4/lib/registry/reg_backend_dir.c index 8348f6c38a..c2dd3dad00 100644 --- a/source4/lib/registry/reg_backend_dir.c +++ b/source4/lib/registry/reg_backend_dir.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index 5d72eabfdd..ca9327c174 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c index 758d1c2453..74261c57a9 100644 --- a/source4/lib/registry/reg_backend_nt4.c +++ b/source4/lib/registry/reg_backend_nt4.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + along with this program. If not, see . */ #include "includes.h" #include "lib/registry/registry.h" diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index 7e81023acb..dc6a2d86f1 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + along with this program. If not, see . */ #include "includes.h" #include "registry.h" diff --git a/source4/lib/registry/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95.c index 05b84fdc61..a0b6e0164a 100644 --- a/source4/lib/registry/reg_backend_w95.c +++ b/source4/lib/registry/reg_backend_w95.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + along with this program. If not, see . */ #include "includes.h" #include "registry.h" diff --git a/source4/lib/registry/reg_backend_wine.c b/source4/lib/registry/reg_backend_wine.c index 8a3458b52c..7184a602d1 100644 --- a/source4/lib/registry/reg_backend_wine.c +++ b/source4/lib/registry/reg_backend_wine.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/lib/registry/reg_samba.c b/source4/lib/registry/reg_samba.c index 3553c4cb6d..560e1ded31 100644 --- a/source4/lib/registry/reg_samba.c +++ b/source4/lib/registry/reg_samba.c @@ -4,7 +4,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -13,8 +13,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 29aa226539..09d61c6b4f 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #ifndef _REGISTRY_H /* _REGISTRY_H */ diff --git a/source4/lib/registry/tests/generic.c b/source4/lib/registry/tests/generic.c index ac4ab98fc0..1f0c89e058 100644 --- a/source4/lib/registry/tests/generic.c +++ b/source4/lib/registry/tests/generic.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index ab6f7c1a57..6eb8a78caf 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 16fe4f498a..83ad5575ef 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index ac41a99765..f431c81bf8 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index e8291a69c2..d026d2824f 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From 8c9abc4be738fc17691f8a36827d50bb5dd3bbb6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Aug 2007 13:40:41 +0000 Subject: r24491: base_type() isn't supported anymore and the default for enums is now uint16... metze (This used to be commit 82aad0e42c44f5b277aed743595795fcc4bad0d4) --- source4/lib/registry/regf.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/regf.idl b/source4/lib/registry/regf.idl index e313dfc4da..46af4ffdc5 100644 --- a/source4/lib/registry/regf.idl +++ b/source4/lib/registry/regf.idl @@ -73,7 +73,7 @@ interface regf */ }; - [base_type(uint16),noprint] enum reg_key_type { + [noprint] enum reg_key_type { REG_ROOT_KEY = 0x20, REG_SUB_KEY = 0x2C, REG_SYM_LINK = 0x10 -- cgit From f14bd1a90ab47a418c0ec2492990a417a0bb3bf6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 19 Aug 2007 21:23:03 +0000 Subject: r24557: rename 'dcerpc_table_' -> 'ndr_table_' metze (This used to be commit 84651aee81aaabbebf52ffc3fbcbabb2eec6eed5) --- source4/lib/registry/reg_backend_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c index dc6a2d86f1..50489aced2 100644 --- a/source4/lib/registry/reg_backend_rpc.c +++ b/source4/lib/registry/reg_backend_rpc.c @@ -372,7 +372,7 @@ _PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, struct auth_sessi status = dcerpc_pipe_connect(*ctx /* TALLOC_CTX */, &p, location, - &dcerpc_table_winreg, + &ndr_table_winreg, credentials, ev); (*ctx)->backend_data = p; -- cgit From b409d4120f9ae451f93a2322267c0f346531d9f3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 26 Aug 2007 15:16:40 +0000 Subject: r24667: Finally merge the registry improvements that Wilco Baan Hofman and I have been working on for at least half a year now. Contains the following improvements: * proper layering (finally!) for the registry library. Distinction is now made between 'real' backends (local, remote, wine, etc) and the low-level hive backends (regf, creg, ldb, ...) that are only used by the local registry backend * tests for all important hive and registry operations * re-enable RPC-WINREG tests (still needs more work though, as some return values aren't checked yet) * write support for REGF files * dir backend now supports setting/reading values, creating keys * support for storing security descriptors * remove CREG backend as it was incomplete, didn't match the data model and wasn't used at all anyway * support for parsing ADM files as used by the policy editor (see lib/policy) * support for parsing PREG files (format used by .POL files) * new streaming interface for registry diffs (improves speed and memory usage for regdiff/regpatch significantly) ... and fixes a large number of bugs in the registry code (This used to be commit 7a1eec6358bc863dfc671c542b7185d3e39d7b5a) --- source4/lib/registry/Doxyfile | 2 +- source4/lib/registry/README | 31 +- source4/lib/registry/TODO | 4 +- source4/lib/registry/common/reg_interface.c | 584 -------- source4/lib/registry/common/reg_util.c | 247 ---- source4/lib/registry/config.mk | 96 +- source4/lib/registry/dir.c | 333 +++++ source4/lib/registry/hive.c | 145 ++ source4/lib/registry/hive.h | 197 +++ source4/lib/registry/interface.c | 277 ++++ source4/lib/registry/ldb.c | 501 +++++++ source4/lib/registry/local.c | 333 +++++ source4/lib/registry/man/regdiff.1.xml | 2 +- source4/lib/registry/man/regpatch.1.xml | 2 +- source4/lib/registry/man/regshell.1.xml | 2 +- source4/lib/registry/man/regtree.1.xml | 2 +- source4/lib/registry/patchfile.c | 561 ++++---- source4/lib/registry/patchfile.h | 52 + source4/lib/registry/patchfile_dotreg.c | 247 ++++ source4/lib/registry/patchfile_preg.c | 270 ++++ source4/lib/registry/reg_backend_dir.c | 141 -- source4/lib/registry/reg_backend_ldb.c | 405 ------ source4/lib/registry/reg_backend_nt4.c | 1124 ---------------- source4/lib/registry/reg_backend_rpc.c | 395 ------ source4/lib/registry/reg_backend_w95.c | 356 ----- source4/lib/registry/reg_backend_wine.c | 47 - source4/lib/registry/reg_samba.c | 81 -- source4/lib/registry/regf.c | 1923 +++++++++++++++++++++++++++ source4/lib/registry/regf.idl | 6 +- source4/lib/registry/registry.h | 309 +++-- source4/lib/registry/rpc.c | 399 ++++++ source4/lib/registry/samba.c | 85 ++ source4/lib/registry/tests/diff.c | 105 ++ source4/lib/registry/tests/generic.c | 66 +- source4/lib/registry/tests/hive.c | 383 ++++++ source4/lib/registry/tests/registry.c | 486 +++++++ source4/lib/registry/tools/common.c | 75 ++ source4/lib/registry/tools/regdiff.c | 103 +- source4/lib/registry/tools/regpatch.c | 31 +- source4/lib/registry/tools/regshell.c | 266 ++-- source4/lib/registry/tools/regtree.c | 114 +- source4/lib/registry/util.c | 242 ++++ source4/lib/registry/wine.c | 45 + 43 files changed, 6952 insertions(+), 4123 deletions(-) delete mode 100644 source4/lib/registry/common/reg_interface.c delete mode 100644 source4/lib/registry/common/reg_util.c create mode 100644 source4/lib/registry/dir.c create mode 100644 source4/lib/registry/hive.c create mode 100644 source4/lib/registry/hive.h create mode 100644 source4/lib/registry/interface.c create mode 100644 source4/lib/registry/ldb.c create mode 100644 source4/lib/registry/local.c create mode 100644 source4/lib/registry/patchfile.h create mode 100644 source4/lib/registry/patchfile_dotreg.c create mode 100644 source4/lib/registry/patchfile_preg.c delete mode 100644 source4/lib/registry/reg_backend_dir.c delete mode 100644 source4/lib/registry/reg_backend_ldb.c delete mode 100644 source4/lib/registry/reg_backend_nt4.c delete mode 100644 source4/lib/registry/reg_backend_rpc.c delete mode 100644 source4/lib/registry/reg_backend_w95.c delete mode 100644 source4/lib/registry/reg_backend_wine.c delete mode 100644 source4/lib/registry/reg_samba.c create mode 100644 source4/lib/registry/regf.c create mode 100644 source4/lib/registry/rpc.c create mode 100644 source4/lib/registry/samba.c create mode 100644 source4/lib/registry/tests/diff.c create mode 100644 source4/lib/registry/tests/hive.c create mode 100644 source4/lib/registry/tests/registry.c create mode 100644 source4/lib/registry/tools/common.c create mode 100644 source4/lib/registry/util.c create mode 100644 source4/lib/registry/wine.c (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/Doxyfile b/source4/lib/registry/Doxyfile index ff591b6fe4..efc01cd355 100644 --- a/source4/lib/registry/Doxyfile +++ b/source4/lib/registry/Doxyfile @@ -15,7 +15,7 @@ WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" -INPUT = . common +INPUT = . FILE_PATTERNS = *.c *.h *.dox GENERATE_HTML = YES HTML_OUTPUT = html diff --git a/source4/lib/registry/README b/source4/lib/registry/README index db1fb7a678..07b2c01684 100644 --- a/source4/lib/registry/README +++ b/source4/lib/registry/README @@ -1,30 +1,31 @@ This is the registry library. The registry is basically a bunch of -hives that can be loaded from different places. +hives, each of which is loaded from a file. When using a local registry, +it is possible to specify where hives should be loaded from, etc. -The various registry backends provide support for loading/saving -specific types of hives: +There are separate APIs for accessing the data in a hive and the +data in the registry itself. Each supports different backends. + +The following "full registry" backends are currently provided: + + * Remote (over DCE/RPC) + * Local (allows "mounting" hives) + * Wine (uses the wine plain-text file) + +The following hive backends are supported: - ldb - - w95 (USER.DAT-style files) - - nt4 (NTUSER.DAT-style files) - - gconf (GNOME configuration) + - regf (NTUSER.DAT-style files) - rpc (Remote individual hives) + - directory -Instead of opening individual hives, one can also open a 'complete' -registry by using one of these three functions: - - - reg_open_local() - load local registry, see below - - reg_open_remote() - connect to remote registry over RPC - - reg_open_wine() (not working yet) - -reg_open_local() loads a set of hives based on smb.conf settings. +reg_open_samba() loads a set of hives based on smb.conf settings. Lines in smb.conf should have the following syntax: registry: = : So an example usage could be: -registry:HKEY_CURRENT_USER = nt4:NTUSER.DAT +registry:HKEY_CURRENT_USER = regf:NTUSER.DAT registry:HKEY_LOCAL_MACHINE = ldb:tdb://registry.tdb WERR_NOT_SUPPORTED will be returned for all hives that haven't been set. diff --git a/source4/lib/registry/TODO b/source4/lib/registry/TODO index 562ed5657e..5f1e7d034b 100644 --- a/source4/lib/registry/TODO +++ b/source4/lib/registry/TODO @@ -4,10 +4,10 @@ reg_backend_dir: - value support -reg_backend_w95.c: +reg_backend_creg.c: - write support -reg_backend_nt4: +reg_backend_regf: - write support reg_backend_rpc: diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c deleted file mode 100644 index 6ee8a726dc..0000000000 --- a/source4/lib/registry/common/reg_interface.c +++ /dev/null @@ -1,584 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Transparent registry backend handling - Copyright (C) Jelmer Vernooij 2003-2004. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "lib/util/dlinklist.h" -#include "lib/registry/registry.h" -#include "build.h" - -/** - * @file - * @brief Main registry functions - */ - -/* List of available backends */ -static struct reg_init_function_entry *backends = NULL; - -static struct reg_init_function_entry *reg_find_backend_entry(const char *name); - -/** Register a new backend. */ -_PUBLIC_ NTSTATUS registry_register(const void *_hive_ops) -{ - const struct hive_operations *hive_ops = _hive_ops; - struct reg_init_function_entry *entry = backends; - - DEBUG(5,("Attempting to register registry backend %s\n", hive_ops->name)); - - /* Check for duplicates */ - if (reg_find_backend_entry(hive_ops->name)) { - DEBUG(0,("There already is a registry backend registered with the name %s!\n", hive_ops->name)); - return NT_STATUS_OBJECT_NAME_COLLISION; - } - - entry = talloc(talloc_autofree_context(), struct reg_init_function_entry); - entry->hive_functions = hive_ops; - - DLIST_ADD(backends, entry); - DEBUG(5,("Successfully added registry backend '%s'\n", hive_ops->name)); - return NT_STATUS_OK; -} - -/** Find a backend in the list of available backends */ -static struct reg_init_function_entry *reg_find_backend_entry(const char *name) -{ - struct reg_init_function_entry *entry; - - entry = backends; - - while(entry) { - if (strcmp(entry->hive_functions->name, name) == 0) return entry; - entry = entry->next; - } - - return NULL; -} - -/** Initialize the registry subsystem */ -_PUBLIC_ NTSTATUS registry_init(void) -{ - init_module_fn static_init[] = STATIC_registry_MODULES; - init_module_fn *shared_init = load_samba_modules(NULL, "registry"); - - run_init_functions(static_init); - run_init_functions(shared_init); - - talloc_free(shared_init); - - return NT_STATUS_OK; -} - -/** Check whether a certain backend is present. */ -_PUBLIC_ BOOL reg_has_backend(const char *backend) -{ - return reg_find_backend_entry(backend) != NULL?True:False; -} - -const struct reg_predefined_key reg_predefined_keys[] = { - {HKEY_CLASSES_ROOT,"HKEY_CLASSES_ROOT" }, - {HKEY_CURRENT_USER,"HKEY_CURRENT_USER" }, - {HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" }, - {HKEY_PERFORMANCE_DATA, "HKEY_PERFORMANCE_DATA" }, - {HKEY_USERS, "HKEY_USERS" }, - {HKEY_CURRENT_CONFIG, "HKEY_CURRENT_CONFIG" }, - {HKEY_DYN_DATA, "HKEY_DYN_DATA" }, - {HKEY_PERFORMANCE_TEXT, "HKEY_PERFORMANCE_TEXT" }, - {HKEY_PERFORMANCE_NLSTEXT, "HKEY_PERFORMANCE_NLSTEXT" }, - { 0, NULL } -}; - -/** Obtain a list of predefined keys. */ -_PUBLIC_ int reg_list_predefs(TALLOC_CTX *mem_ctx, char ***predefs, uint32_t **hkeys) -{ - int i; - *predefs = talloc_array(mem_ctx, char *, ARRAY_SIZE(reg_predefined_keys)); - *hkeys = talloc_array(mem_ctx, uint32_t, ARRAY_SIZE(reg_predefined_keys)); - - for (i = 0; reg_predefined_keys[i].name; i++) { - (*predefs)[i] = talloc_strdup(mem_ctx, reg_predefined_keys[i].name); - (*hkeys)[i] = reg_predefined_keys[i].handle; - } - - return i; -} - -/** Obtain name of specific hkey. */ -_PUBLIC_ const char *reg_get_predef_name(uint32_t hkey) -{ - int i; - for (i = 0; reg_predefined_keys[i].name; i++) { - if (reg_predefined_keys[i].handle == hkey) return reg_predefined_keys[i].name; - } - - return NULL; -} - -/** Get predefined key by name. */ -_PUBLIC_ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, const char *name, struct registry_key **key) -{ - int i; - - for (i = 0; reg_predefined_keys[i].name; i++) { - if (!strcasecmp(reg_predefined_keys[i].name, name)) return reg_get_predefined_key(ctx, reg_predefined_keys[i].handle, key); - } - - DEBUG(1, ("No predefined key with name '%s'\n", name)); - - return WERR_BADFILE; -} - -/** Get predefined key by id. */ -_PUBLIC_ WERROR reg_get_predefined_key(struct registry_context *ctx, uint32_t hkey, struct registry_key **key) -{ - WERROR ret = ctx->get_predefined_key(ctx, hkey, key); - - if (W_ERROR_IS_OK(ret)) { - (*key)->name = talloc_strdup(*key, reg_get_predef_name(hkey)); - (*key)->path = ""; - } - - return ret; -} - -/** Open a registry file/host/etc */ -_PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *backend, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, struct registry_key **root) -{ - struct registry_hive *rethive; - struct registry_key *retkey = NULL; - struct reg_init_function_entry *entry; - WERROR werr; - - entry = reg_find_backend_entry(backend); - - if (!entry) { - DEBUG(0, ("No such registry backend '%s' loaded!\n", backend)); - return WERR_GENERAL_FAILURE; - } - - if(!entry->hive_functions || !entry->hive_functions->open_hive) { - return WERR_NOT_SUPPORTED; - } - - rethive = talloc(parent_ctx, struct registry_hive); - rethive->location = location?talloc_strdup(rethive, location):NULL; - rethive->session_info = talloc_reference(rethive, session_info); - rethive->credentials = talloc_reference(rethive, credentials); - rethive->functions = entry->hive_functions; - rethive->backend_data = NULL; - - werr = entry->hive_functions->open_hive(rethive, &retkey); - - if(!W_ERROR_IS_OK(werr)) { - return werr; - } - - if(!retkey) { - DEBUG(0, ("Backend %s didn't provide root key!\n", backend)); - return WERR_GENERAL_FAILURE; - } - - rethive->root = retkey; - - retkey->hive = rethive; - retkey->name = NULL; - retkey->path = talloc_strdup(retkey, ""); - - *root = retkey; - - return WERR_OK; -} - -/** - * Open a key - * First tries to use the open_key function from the backend - * then falls back to get_subkey_by_name and later get_subkey_by_index - */ -_PUBLIC_ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, struct registry_key **result) -{ - WERROR error; - - if(!parent) { - DEBUG(0, ("Invalid parent key specified for open of '%s'\n", name)); - return WERR_INVALID_PARAM; - } - - if(!parent->hive->functions->open_key && - (parent->hive->functions->get_subkey_by_name || - parent->hive->functions->get_subkey_by_index)) { - char *orig = strdup(name), - *curbegin = orig, - *curend = strchr(orig, '\\'); - struct registry_key *curkey = parent; - - while(curbegin && *curbegin) { - if(curend)*curend = '\0'; - error = reg_key_get_subkey_by_name(mem_ctx, curkey, curbegin, &curkey); - if(!W_ERROR_IS_OK(error)) { - SAFE_FREE(orig); - return error; - } - if(!curend) break; - curbegin = curend + 1; - curend = strchr(curbegin, '\\'); - } - SAFE_FREE(orig); - - *result = curkey; - - return WERR_OK; - } - - if(!parent->hive->functions->open_key) { - DEBUG(0, ("Registry backend doesn't have get_subkey_by_name nor open_key!\n")); - return WERR_NOT_SUPPORTED; - } - - error = parent->hive->functions->open_key(mem_ctx, parent, name, result); - - if(!W_ERROR_IS_OK(error)) return error; - - (*result)->hive = parent->hive; - (*result)->path = ((parent->hive->root == parent)?talloc_strdup(mem_ctx, name):talloc_asprintf(mem_ctx, "%s\\%s", parent->path, name)); - (*result)->hive = parent->hive; - - return WERR_OK; -} - -/** - * Get value by index - */ -_PUBLIC_ WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *key, int idx, struct registry_value **val) -{ - if(!key) return WERR_INVALID_PARAM; - - if(key->hive->functions->get_value_by_index) { - WERROR status = key->hive->functions->get_value_by_index(mem_ctx, key, idx, val); - if(!W_ERROR_IS_OK(status)) - return status; - } else { - return WERR_NOT_SUPPORTED; - } - - return WERR_OK; -} - -/** - * Get the number of subkeys. - */ -_PUBLIC_ WERROR reg_key_num_subkeys(const struct registry_key *key, uint32_t *count) -{ - if(!key) return WERR_INVALID_PARAM; - - if(key->hive->functions->num_subkeys) { - return key->hive->functions->num_subkeys(key, count); - } - - if(key->hive->functions->get_subkey_by_index) { - int i; - WERROR error; - struct registry_key *dest = NULL; - TALLOC_CTX *mem_ctx = talloc_init("num_subkeys"); - - for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(mem_ctx, key, i, &dest)); i++); - talloc_free(mem_ctx); - - *count = i; - if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) error = WERR_OK; - return error; - } - - return WERR_NOT_SUPPORTED; -} - -/** - * Get the number of values of a key. - */ -_PUBLIC_ WERROR reg_key_num_values(const struct registry_key *key, uint32_t *count) -{ - - if(!key) return WERR_INVALID_PARAM; - - 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_free(mem_ctx); - - *count = i; - if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) error = WERR_OK; - return error; - } - - return WERR_NOT_SUPPORTED; -} - -/** - * Get subkey by index. - */ -_PUBLIC_ WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *key, int idx, struct registry_key **subkey) -{ - if(!key) return WERR_INVALID_PARAM; - - if(key->hive->functions->get_subkey_by_index) { - WERROR status = key->hive->functions->get_subkey_by_index(mem_ctx, key, idx, subkey); - if(!NT_STATUS_IS_OK(status)) return status; - } else { - return WERR_NOT_SUPPORTED; - } - - if(key->hive->root == key) - (*subkey)->path = talloc_strdup(mem_ctx, (*subkey)->name); - else - (*subkey)->path = talloc_asprintf(mem_ctx, "%s\\%s", key->path, (*subkey)->name); - - (*subkey)->hive = key->hive; - return WERR_OK;; -} - -/** - * Get subkey by name. - */ -WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char *name, struct registry_key **subkey) -{ - int i; - WERROR error = WERR_OK; - - if(!key) return WERR_INVALID_PARAM; - - if(key->hive->functions->get_subkey_by_name) { - error = key->hive->functions->get_subkey_by_name(mem_ctx, key,name,subkey); - } else if(key->hive->functions->open_key) { - error = key->hive->functions->open_key(mem_ctx, key, name, subkey); - } else if(key->hive->functions->get_subkey_by_index) { - 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) && !strcasecmp((*subkey)->name, name)) { - break; - } - } - - if (W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) - error = WERR_DEST_NOT_FOUND; - } else { - return WERR_NOT_SUPPORTED; - } - - if(!W_ERROR_IS_OK(error)) return error; - - (*subkey)->path = talloc_asprintf(mem_ctx, "%s\\%s", key->path, (*subkey)->name); - (*subkey)->hive = key->hive; - - return WERR_OK; -} - -/** - * Get value by name. - */ -_PUBLIC_ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char *name, struct registry_value **val) -{ - int i; - WERROR error = WERR_OK; - - if(!key) return WERR_INVALID_PARAM; - - if(key->hive->functions->get_value_by_name) { - error = key->hive->functions->get_value_by_name(mem_ctx, key,name, val); - } 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)) { - break; - } - } - } - - if (W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) - return WERR_DEST_NOT_FOUND; - - return error; -} - -/** - * Delete a key. - */ -_PUBLIC_ WERROR reg_key_del(struct registry_key *parent, const char *name) -{ - WERROR error; - if(!parent) return WERR_INVALID_PARAM; - - - if(!parent->hive->functions->del_key) - return WERR_NOT_SUPPORTED; - - error = parent->hive->functions->del_key(parent, name); - if(!W_ERROR_IS_OK(error)) return error; - - return WERR_OK; -} - -/** - * Add a key. - */ -_PUBLIC_ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, const struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *desc, struct registry_key **newkey) -{ - WERROR error; - - if (!parent) return WERR_INVALID_PARAM; - - if (!parent->hive->functions->add_key) { - DEBUG(1, ("Backend '%s' doesn't support method add_key\n", parent->hive->functions->name)); - return WERR_NOT_SUPPORTED; - } - - error = parent->hive->functions->add_key(mem_ctx, parent, name, access_mask, desc, newkey); - - if(!W_ERROR_IS_OK(error)) return error; - - if (!*newkey) { - DEBUG(0, ("Backend returned WERR_OK, but didn't specify key!\n")); - return WERR_GENERAL_FAILURE; - } - - (*newkey)->hive = parent->hive; - - return WERR_OK; -} - -/** - * Set a value. - */ -_PUBLIC_ WERROR reg_val_set(struct registry_key *key, const char *value, uint32_t type, DATA_BLOB data) -{ - /* A 'real' set function has preference */ - if (key->hive->functions->set_value) - return key->hive->functions->set_value(key, value, type, data); - - DEBUG(1, ("Backend '%s' doesn't support method set_value\n", key->hive->functions->name)); - return WERR_NOT_SUPPORTED; -} - -/** - * Get the security descriptor on a key. - */ -_PUBLIC_ WERROR reg_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, struct security_descriptor **secdesc) -{ - /* A 'real' set function has preference */ - if (key->hive->functions->key_get_sec_desc) - return key->hive->functions->key_get_sec_desc(ctx, key, secdesc); - - DEBUG(1, ("Backend '%s' doesn't support method get_sec_desc\n", key->hive->functions->name)); - return WERR_NOT_SUPPORTED; -} - -/** - * Delete a value. - */ -_PUBLIC_ WERROR reg_del_value(const struct registry_key *key, const char *valname) -{ - WERROR ret = WERR_OK; - if(!key->hive->functions->del_value) - return WERR_NOT_SUPPORTED; - - ret = key->hive->functions->del_value(key, valname); - - if(!W_ERROR_IS_OK(ret)) return ret; - - return ret; -} - -/** - * Flush a key to disk. - */ -_PUBLIC_ WERROR reg_key_flush(const struct registry_key *key) -{ - if (!key) { - return WERR_INVALID_PARAM; - } - - if (key->hive->functions->flush_key) { - return key->hive->functions->flush_key(key); - } - - /* No need for flushing, apparently */ - return WERR_OK; -} - -/** - * Get the maximum name and data lengths of the subkeys. - */ -_PUBLIC_ WERROR reg_key_subkeysizes(const struct registry_key *key, uint32_t *max_subkeylen, uint32_t *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_free(mem_ctx); - - return WERR_OK; -} - -/** - * Get the maximum name and data lengths of the values. - */ -_PUBLIC_ WERROR reg_key_valuesizes(const struct registry_key *key, uint32_t *max_valnamelen, uint32_t *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.length); - } - - i++; - } while (W_ERROR_IS_OK(error)); - - talloc_free(mem_ctx); - - return WERR_OK; -} diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c deleted file mode 100644 index 696336161e..0000000000 --- a/source4/lib/registry/common/reg_util.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Transparent registry backend handling - Copyright (C) Jelmer Vernooij 2003-2004. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "lib/registry/registry.h" -#include "librpc/gen_ndr/winreg.h" - -/** - * @file - * @brief Registry utility functions - */ - -static const struct { - uint32_t 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 */ -_PUBLIC_ const char *str_regtype(int type) -{ - 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"; -} - -_PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, DATA_BLOB *data) -{ - char *ret = NULL; - - if(data->length == 0) return talloc_strdup(mem_ctx, ""); - - switch (type) { - case REG_EXPAND_SZ: - case REG_SZ: - convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, data->data, data->length, (void **)&ret); - return ret; - - case REG_BINARY: - ret = data_blob_hex_string(mem_ctx, data); - return ret; - - case REG_DWORD: - if (*(int *)data->data == 0) - return talloc_strdup(mem_ctx, "0"); - - return talloc_asprintf(mem_ctx, "0x%x", *(int *)data->data); - - case REG_MULTI_SZ: - /* FIXME */ - break; - - default: - break; - } - - return ret; -} - -/** Generate a string that describes a registry value */ -_PUBLIC_ 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->data_type, &val->data)); -} - -_PUBLIC_ BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data) -{ - int i; - *type = -1; - - /* Find the correct type */ - for (i = 0; reg_value_types[i].name; i++) { - if (!strcmp(reg_value_types[i].name, type_str)) { - *type = reg_value_types[i].id; - break; - } - } - - if (*type == -1) - return False; - - /* Convert data appropriately */ - - switch (*type) - { - case REG_SZ: - case REG_EXPAND_SZ: - data->length = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, data_str, strlen(data_str), (void **)&data->data); - break; - - case REG_DWORD: { - uint32_t tmp = strtol(data_str, NULL, 0); - *data = data_blob_talloc(mem_ctx, &tmp, 4); - } - break; - - case REG_NONE: - ZERO_STRUCTP(data); - break; - - case REG_BINARY: - *data = strhex_to_data_blob(data_str); - talloc_steal(mem_ctx, data->data); - break; - - default: - /* FIXME */ - return False; - } - return True; -} - -/** - * Replace all \'s with /'s - */ -char *reg_path_win2unix(char *path) -{ - int i; - for(i = 0; path[i]; i++) { - if(path[i] == '\\') path[i] = '/'; - } - return path; -} -/** - * Replace all /'s with \'s - */ -char *reg_path_unix2win(char *path) -{ - int i; - for(i = 0; path[i]; i++) { - if(path[i] == '/') path[i] = '\\'; - } - return path; -} - -/** Open a key by name (including the predefined key name!) */ -WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result) -{ - struct registry_key *predef; - WERROR error; - int predeflength; - char *predefname; - - if(strchr(name, '\\')) predeflength = strchr(name, '\\')-name; - else predeflength = strlen(name); - - predefname = talloc_strndup(mem_ctx, name, predeflength); - error = reg_get_predefined_key_by_name(handle, predefname, &predef); - talloc_free(predefname); - - if(!W_ERROR_IS_OK(error)) { - return error; - } - - if (strchr(name, '\\')) { - return reg_open_key(mem_ctx, predef, strchr(name, '\\')+1, result); - } else { - *result = predef; - return WERR_OK; - } -} - -static WERROR get_abs_parent(TALLOC_CTX *mem_ctx, struct registry_context *ctx, const char *path, struct registry_key **parent, const char **name) -{ - char *parent_name; - WERROR error; - - if (strchr(path, '\\') == NULL) { - return WERR_FOOBAR; - } - - parent_name = talloc_strndup(mem_ctx, path, strrchr(path, '\\')-1-path); - - error = reg_open_key_abs(mem_ctx, ctx, parent_name, parent); - if (!W_ERROR_IS_OK(error)) { - return error; - } - - *name = talloc_strdup(mem_ctx, strchr(path, '\\')+1); - - return WERR_OK; -} - -WERROR reg_key_del_abs(struct registry_context *ctx, const char *path) -{ - struct registry_key *parent; - const char *n; - TALLOC_CTX *mem_ctx = talloc_init("reg_key_del_abs"); - WERROR error; - - if (!strchr(path, '\\')) { - return WERR_FOOBAR; - } - - error = get_abs_parent(mem_ctx, ctx, path, &parent, &n); - if (W_ERROR_IS_OK(error)) { - error = reg_key_del(parent, n); - } - - talloc_free(mem_ctx); - - return error; -} - -WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx, const char *path, uint32_t access_mask, struct security_descriptor *sec_desc, struct registry_key **result) -{ - struct registry_key *parent; - const char *n; - WERROR error; - - if (!strchr(path, '\\')) { - return WERR_FOOBAR; - } - - error = get_abs_parent(mem_ctx, ctx, path, &parent, &n); - if (W_ERROR_IS_OK(error)) { - error = reg_key_add_name(mem_ctx, parent, n, access_mask, sec_desc, result); - } - - return error; -} diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index cea37e7e2f..de276d2b5e 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -1,23 +1,10 @@ -# Registry backends - -################################################ -# Start MODULE registry_nt4 -[MODULE::registry_nt4] -INIT_FUNCTION = registry_nt4_init -SUBSYSTEM = registry -OBJ_FILES = \ - reg_backend_nt4.o -PRIVATE_DEPENDENCIES = TDR_REGF -# End MODULE registry_nt4 -################################################ - [SUBSYSTEM::TDR_REGF] PUBLIC_DEPENDENCIES = TDR OBJ_FILES = tdr_regf.o # Special support for external builddirs -lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c -$(srcdir)/lib/registry/reg_backend_nt4.c: lib/registry/tdr_regf.c +lib/registry/regf.c: lib/registry/tdr_regf.c +$(srcdir)/lib/registry/regf.c: lib/registry/tdr_regf.c lib/registry/tdr_regf.h: lib/registry/tdr_regf.c lib/registry/tdr_regf.c: $(srcdir)/lib/registry/regf.idl @CPP="$(CPP)" srcdir="$(srcdir)" $(PERL) $(srcdir)/pidl/pidl $(PIDL_ARGS) \ @@ -27,51 +14,6 @@ lib/registry/tdr_regf.c: $(srcdir)/lib/registry/regf.idl clean:: @-rm -f lib/registry/regf.h lib/registry/tdr_regf* -################################################ -# Start MODULE registry_w95 -[MODULE::registry_w95] -INIT_FUNCTION = registry_w95_init -SUBSYSTEM = registry -OBJ_FILES = \ - reg_backend_w95.o -# End MODULE registry_w95 -################################################ - -################################################ -# Start MODULE registry_dir -[MODULE::registry_dir] -INIT_FUNCTION = registry_dir_init -SUBSYSTEM = registry -OBJ_FILES = \ - reg_backend_dir.o -PRIVATE_DEPENDENCIES = LIBTALLOC -# End MODULE registry_dir -################################################ - -################################################ -# Start MODULE registry_rpc -[MODULE::registry_rpc] -INIT_FUNCTION = registry_rpc_init -OUTPUT_TYPE = INTEGRATED -SUBSYSTEM = registry -OBJ_FILES = \ - reg_backend_rpc.o -PRIVATE_DEPENDENCIES = RPC_NDR_WINREG -# End MODULE registry_rpc -################################################ - -################################################ -# Start MODULE registry_ldb -[MODULE::registry_ldb] -INIT_FUNCTION = registry_ldb_init -SUBSYSTEM = registry -OBJ_FILES = \ - reg_backend_ldb.o -PRIVATE_DEPENDENCIES = \ - LIBLDB -# End MODULE registry_ldb -################################################ - ################################################ # Start SUBSYSTEM registry [LIBRARY::registry] @@ -79,16 +21,30 @@ VERSION = 0.0.1 SO_VERSION = 0 DESCRIPTION = Windows-style registry library OBJ_FILES = \ - common/reg_interface.o \ - common/reg_util.o \ - reg_samba.o \ - patchfile.o -PRIVATE_DEPENDENCIES = \ - LIBSAMBA-UTIL CHARSET + interface.o \ + util.o \ + samba.o \ + patchfile_dotreg.o \ + patchfile_preg.o \ + patchfile.o \ + regf.o \ + hive.o \ + local.o \ + ldb.o \ + dir.o \ + rpc.o +PUBLIC_DEPENDENCIES = \ + LIBSAMBA-UTIL CHARSET TDR_REGF LIBLDB \ + RPC_NDR_WINREG PUBLIC_HEADERS = registry.h # End MODULE registry_ldb ################################################ +[SUBSYSTEM::registry_common] +PUBLIC_DEPENDENCIES = registry +OBJ_FILES = tools/common.o +PUBLIC_PROTO_HEADER = tools/common.h + ################################################ # Start BINARY regdiff [BINARY::regdiff] @@ -106,7 +62,8 @@ MANPAGE = man/regdiff.1 INSTALLDIR = BINDIR OBJ_FILES = tools/regpatch.o PRIVATE_DEPENDENCIES = \ - LIBSAMBA-CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS + LIBSAMBA-CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS \ + registry_common MANPAGE = man/regpatch.1 # End BINARY regpatch ################################################ @@ -118,7 +75,7 @@ INSTALLDIR = BINDIR OBJ_FILES = tools/regshell.o PRIVATE_DEPENDENCIES = \ LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \ - SMBREADLINE + SMBREADLINE registry_common MANPAGE = man/regshell.1 # End BINARY regshell ################################################ @@ -129,7 +86,8 @@ MANPAGE = man/regshell.1 INSTALLDIR = BINDIR OBJ_FILES = tools/regtree.o PRIVATE_DEPENDENCIES = \ - LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS + LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \ + registry_common MANPAGE = man/regtree.1 # End BINARY regtree ################################################ diff --git a/source4/lib/registry/dir.c b/source4/lib/registry/dir.c new file mode 100644 index 0000000000..146c5197fd --- /dev/null +++ b/source4/lib/registry/dir.c @@ -0,0 +1,333 @@ +/* + Unix SMB/CIFS implementation. + Registry interface + Copyright (C) Jelmer Vernooij 2004-2007. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "hive.h" +#include "system/dir.h" +#include "system/filesys.h" + +struct dir_key { + struct hive_key key; + const char *path; +}; + +static struct hive_operations reg_backend_dir; + +static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx, + const struct hive_key *parent, + const char *name, const char *classname, + struct security_descriptor *desc, + struct hive_key **result) +{ + struct dir_key *dk = talloc_get_type(parent, struct dir_key); + char *path; + int ret; + + path = talloc_asprintf(mem_ctx, "%s/%s", dk->path, name); + ret = mkdir(path, 0700); + if (ret == 0) { + struct dir_key *key = talloc(mem_ctx, struct dir_key); + key->key.ops = ®_backend_dir; + key->path = talloc_steal(key, path); + *result = (struct hive_key *)key; + return WERR_OK; + } + + if (errno == EEXIST) + return WERR_ALREADY_EXISTS; + printf("FAILED %s BECAUSE: %s\n", path, strerror(errno)); + return WERR_GENERAL_FAILURE; +} + +static WERROR reg_dir_del_key(const struct hive_key *k, const char *name) +{ + struct dir_key *dk = talloc_get_type(k, struct dir_key); + char *child = talloc_asprintf(NULL, "%s/%s", dk->path, name); + WERROR ret; + + if (rmdir(child) == 0) + ret = WERR_OK; + else if (errno == ENOENT) + ret = WERR_NOT_FOUND; + else + ret = WERR_GENERAL_FAILURE; + + talloc_free(child); + + return ret; +} + +static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, + const struct hive_key *parent, + const char *name, struct hive_key **subkey) +{ + DIR *d; + char *fullpath; + const struct dir_key *p = talloc_get_type(parent, struct dir_key); + struct dir_key *ret; + + if (name == NULL) { + DEBUG(0, ("NULL pointer passed as directory name!")); + return WERR_INVALID_PARAM; + } + + fullpath = talloc_asprintf(mem_ctx, "%s/%s", p->path, name); + + d = opendir(fullpath); + if (d == NULL) { + DEBUG(3,("Unable to open '%s': %s\n", fullpath, strerror(errno))); + return WERR_BADFILE; + } + closedir(d); + ret = talloc(mem_ctx, struct dir_key); + ret->key.ops = ®_backend_dir; + ret->path = talloc_steal(ret, fullpath); + *subkey = (struct hive_key *)ret; + return WERR_OK; +} + +static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, + const struct hive_key *k, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time) +{ + struct dirent *e; + const struct dir_key *dk = talloc_get_type(k, struct dir_key); + int i = 0; + DIR *d; + + d = opendir(dk->path); + + if (d == NULL) + return WERR_INVALID_PARAM; + + while((e = readdir(d))) { + if(!ISDOT(e->d_name) && !ISDOTDOT(e->d_name)) { + struct stat stbuf; + char *thispath; + + /* Check if file is a directory */ + asprintf(&thispath, "%s/%s", dk->path, e->d_name); + stat(thispath, &stbuf); + + if (!S_ISDIR(stbuf.st_mode)) { + SAFE_FREE(thispath); + continue; + } + + if (i == idx) { + struct stat st; + *name = talloc_strdup(mem_ctx, e->d_name); + *classname = NULL; + stat(thispath, &st); + unix_to_nt_time(last_mod_time, st.st_mtime); + SAFE_FREE(thispath); + closedir(d); + return WERR_OK; + } + i++; + + SAFE_FREE(thispath); + } + } + + closedir(d); + + return WERR_NO_MORE_ITEMS; +} + +WERROR reg_open_directory(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key) +{ + struct dir_key *dk; + + if (location == NULL) + return WERR_INVALID_PARAM; + + dk = talloc(parent_ctx, struct dir_key); + dk->key.ops = ®_backend_dir; + dk->path = talloc_strdup(dk, location); + *key = (struct hive_key *)dk; + return WERR_OK; +} + +WERROR reg_create_directory(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key) +{ + if (mkdir(location, 0700) != 0) { + *key = NULL; + return WERR_GENERAL_FAILURE; + } + + return reg_open_directory(parent_ctx, location, key); +} + +static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *lastmod) +{ + DIR *d; + const struct dir_key *dk = talloc_get_type(key, struct dir_key); + struct dirent *e; + struct stat st; + + SMB_ASSERT(key != NULL); + + if (classname != NULL) + *classname = NULL; + + d = opendir(dk->path); + if (d == NULL) + return WERR_INVALID_PARAM; + + if (num_subkeys != NULL) + *num_subkeys = 0; + + if (num_values != NULL) + *num_values = 0; + + while((e = readdir(d))) { + if(!ISDOT(e->d_name) && !ISDOTDOT(e->d_name)) { + char *path = talloc_asprintf(ctx, "%s/%s", dk->path, e->d_name); + + if (stat(path, &st) < 0) { + DEBUG(0, ("Error statting %s: %s\n", path, strerror(errno))); + continue; + } + + if (S_ISDIR(st.st_mode) && num_subkeys != NULL) + (*num_subkeys)++; + + if (!S_ISDIR(st.st_mode) && num_values != NULL) + (*num_values)++; + + talloc_free(path); + } + } + + closedir(d); + + if (lastmod != NULL) + *lastmod = 0; + return WERR_OK; +} + +static WERROR reg_dir_set_value (struct hive_key *key, const char *name, + uint32_t type, const DATA_BLOB data) +{ + const struct dir_key *dk = talloc_get_type(key, struct dir_key); + char *path = talloc_asprintf(dk, "%s/%s", dk->path, name); + + if (!file_save(path, data.data, data.length)) + return WERR_GENERAL_FAILURE; + + /* FIXME: Type */ + + return WERR_OK; +} + +static WERROR reg_dir_get_value (TALLOC_CTX *mem_ctx, + struct hive_key *key, const char *name, + uint32_t *type, DATA_BLOB *data) +{ + const struct dir_key *dk = talloc_get_type(key, struct dir_key); + char *path = talloc_asprintf(mem_ctx, "%s/%s", dk->path, name); + size_t size; + char *contents; + + contents = file_load(path, &size, mem_ctx); + talloc_free(path); + if (contents == NULL) + return WERR_NOT_FOUND; + + if (type != NULL) + *type = 4; /* FIXME */ + + data->data = (uint8_t *)contents; + data->length = size; + + return WERR_OK; +} + +static WERROR reg_dir_enum_value (TALLOC_CTX *mem_ctx, + const struct hive_key *key, int idx, + const char **name, + uint32_t *type, DATA_BLOB *data) +{ + const struct dir_key *dk = talloc_get_type(key, struct dir_key); + DIR *d; + struct dirent *e; + int i; + + d = opendir(dk->path); + if (d == NULL) { + DEBUG(3,("Unable to open '%s': %s\n", dk->path, strerror(errno))); + return WERR_BADFILE; + } + + i = 0; + while((e = readdir(d))) { + if (ISDOT(e->d_name) || ISDOTDOT(e->d_name)) + continue; + + if (i == idx) { + if (name != NULL) + *name = talloc_strdup(mem_ctx, e->d_name); + W_ERROR_NOT_OK_RETURN(reg_dir_get_value(mem_ctx, key, *name, type, data)); + return WERR_OK; + } + + i++; + } + closedir(d); + + return WERR_NO_MORE_ITEMS; +} + + +static WERROR reg_dir_del_value (struct hive_key *key, const char *name) +{ + const struct dir_key *dk = talloc_get_type(key, struct dir_key); + char *path = talloc_asprintf(key, "%s/%s", dk->path, name); + if (unlink(path) < 0) { + talloc_free(path); + if (errno == ENOENT) + return WERR_NOT_FOUND; + return WERR_GENERAL_FAILURE; + } + talloc_free(path); + + return WERR_OK; +} + +static struct hive_operations reg_backend_dir = { + .name = "dir", + .get_key_by_name = reg_dir_open_key, + .get_key_info = reg_dir_get_info, + .add_key = reg_dir_add_key, + .del_key = reg_dir_del_key, + .enum_key = reg_dir_key_by_index, + .set_value = reg_dir_set_value, + .get_value_by_name = reg_dir_get_value, + .enum_value = reg_dir_enum_value, + .delete_value = reg_dir_del_value, +}; diff --git a/source4/lib/registry/hive.c b/source4/lib/registry/hive.c new file mode 100644 index 0000000000..b2c826b93d --- /dev/null +++ b/source4/lib/registry/hive.c @@ -0,0 +1,145 @@ + +/* + Unix SMB/CIFS implementation. + Registry hive interface + Copyright (C) Jelmer Vernooij 2003-2007. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "hive.h" +#include "system/filesys.h" + +/** Open a registry file/host/etc */ +_PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + struct hive_key **root) +{ + int fd, num; + char peek[20]; + + /* Check for directory */ + if (directory_exist(location)) { + return reg_open_directory(parent_ctx, location, root); + } + + fd = open(location, O_RDWR); + if (fd == -1) { + return WERR_BADFILE; + } + + num = read(fd, peek, 20); + if (num == -1) { + return WERR_BADFILE; + } + + if (!strncmp(peek, "regf", 4)) { + close(fd); + return reg_open_regf_file(parent_ctx, location, root); + } else if (!strncmp(peek, "TDB file", 8)) { + close(fd); + return reg_open_ldb_file(parent_ctx, location, session_info, credentials, root); + } + + return WERR_BADFILE; +} + +_PUBLIC_ WERROR hive_key_get_info(TALLOC_CTX *mem_ctx, const struct hive_key *key, + const char **classname, uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time) +{ + return key->ops->get_key_info(mem_ctx, key, classname, num_subkeys, + num_values, last_change_time); +} + +_PUBLIC_ WERROR hive_key_add_name(TALLOC_CTX *ctx, const struct hive_key *parent_key, + const char *name, const char *classname, struct security_descriptor *desc, + struct hive_key **key) +{ + SMB_ASSERT(strchr(name, '\\') == NULL); + + return parent_key->ops->add_key(ctx, parent_key, name, classname, desc, key); +} + +_PUBLIC_ WERROR hive_key_del(const struct hive_key *key, const char *name) +{ + return key->ops->del_key(key, name); +} + +_PUBLIC_ WERROR hive_get_key_by_name(TALLOC_CTX *mem_ctx, + const struct hive_key *key, const char *name, + struct hive_key **subkey) +{ + return key->ops->get_key_by_name(mem_ctx, key, name, subkey); +} + +WERROR hive_enum_key(TALLOC_CTX *mem_ctx, + const struct hive_key *key, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time) +{ + return key->ops->enum_key(mem_ctx, key, idx, name, classname, + last_mod_time); +} + +WERROR hive_set_value(struct hive_key *key, const char *name, uint32_t type, + const DATA_BLOB data) +{ + if (key->ops->set_value == NULL) + return WERR_NOT_SUPPORTED; + + return key->ops->set_value(key, name, type, data); +} + +WERROR hive_get_value (TALLOC_CTX *mem_ctx, + struct hive_key *key, const char *name, + uint32_t *type, DATA_BLOB *data) +{ + if (key->ops->get_value_by_name == NULL) + return WERR_NOT_SUPPORTED; + + return key->ops->get_value_by_name(mem_ctx, key, name, type, data); +} + +WERROR hive_get_value_by_index (TALLOC_CTX *mem_ctx, + struct hive_key *key, uint32_t idx, const char **name, + uint32_t *type, DATA_BLOB *data) +{ + if (key->ops->enum_value == NULL) + return WERR_NOT_SUPPORTED; + + return key->ops->enum_value(mem_ctx, key, idx, name, type, data); +} + + +WERROR hive_del_value (struct hive_key *key, const char *name) +{ + if (key->ops->delete_value == NULL) + return WERR_NOT_SUPPORTED; + + return key->ops->delete_value(key, name); +} + +WERROR hive_key_flush(struct hive_key *key) +{ + if (key->ops->flush_key == NULL) + return WERR_OK; + + return key->ops->flush_key(key); +} diff --git a/source4/lib/registry/hive.h b/source4/lib/registry/hive.h new file mode 100644 index 0000000000..33759fdecc --- /dev/null +++ b/source4/lib/registry/hive.h @@ -0,0 +1,197 @@ +/* + Unix SMB/CIFS implementation. + Registry hive interface + Copyright (C) Jelmer Vernooij 2003-2007. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __REGISTRY_HIVE_H__ +#define __REGISTRY_HIVE_H__ + +#include "core.h" +#include "talloc.h" +#include "librpc/gen_ndr/security.h" + +/** + * This file contains the hive API. This API is generally used for + * reading a specific file that contains just one hive. + * + * Good examples are .DAT (NTUSER.DAT) files. + * + * This API does not have any notification support (that + * should be provided by the registry implementation), nor + * does it understand what predefined keys are. + */ + +struct hive_key { + const struct hive_operations *ops; +}; + +struct hive_operations { + const char *name; + + /** + * Open a specific subkey + */ + WERROR (*enum_key) (TALLOC_CTX *mem_ctx, + const struct hive_key *key, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time); + + /** + * Open a subkey by name + */ + WERROR (*get_key_by_name) (TALLOC_CTX *mem_ctx, + const struct hive_key *key, const char *name, + struct hive_key **subkey); + + /** + * Add a new key. + */ + WERROR (*add_key) (TALLOC_CTX *ctx, + const struct hive_key *parent_key, const char *name, + const char *classname, struct security_descriptor *desc, + struct hive_key **key); + /** + * Remove an existing key. + */ + WERROR (*del_key) (const struct hive_key *key, const char *name); + + /** + * Force write of a key to disk. + */ + WERROR (*flush_key) (struct hive_key *key); + + /** + * Retrieve a registry value with a specific index. + */ + WERROR (*enum_value) (TALLOC_CTX *mem_ctx, + const struct hive_key *key, int idx, + const char **name, uint32_t *type, + DATA_BLOB *data); + + /** + * Retrieve a registry value with the specified name + */ + WERROR (*get_value_by_name) (TALLOC_CTX *mem_ctx, + struct hive_key *key, const char *name, + uint32_t *type, DATA_BLOB *data); + + /** + * Set a value on the specified registry key. + */ + WERROR (*set_value) (struct hive_key *key, const char *name, + uint32_t type, const DATA_BLOB data); + + /** + * Remove a value. + */ + WERROR (*delete_value) (struct hive_key *key, const char *name); + + /* Security Descriptors */ + + /** + * Change the security descriptor on a registry key. + * + * This should return WERR_NOT_SUPPORTED if the underlying + * format does not have a mechanism for storing + * security descriptors. + */ + WERROR (*set_sec_desc) (struct hive_key *key, + const struct security_descriptor *desc); + + /** + * Retrieve the security descriptor on a registry key. + * + * This should return WERR_NOT_SUPPORTED if the underlying + * format does not have a mechanism for storing + * security descriptors. + */ + WERROR (*get_sec_desc) (TALLOC_CTX *ctx, + const struct hive_key *key, + struct security_descriptor **desc); + + /** + * Retrieve general information about a key. + */ + WERROR (*get_key_info) (TALLOC_CTX *mem_ctx, + const struct hive_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time); +}; + +struct cli_credentials; +struct auth_session_info; + +WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + struct hive_key **root); +WERROR hive_key_get_info(TALLOC_CTX *mem_ctx, const struct hive_key *key, + const char **classname, uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time); +WERROR hive_key_add_name(TALLOC_CTX *ctx, const struct hive_key *parent_key, + const char *name, const char *classname, struct security_descriptor *desc, + struct hive_key **key); +_PUBLIC_ WERROR hive_key_del(const struct hive_key *key, const char *name); +_PUBLIC_ WERROR hive_get_key_by_name(TALLOC_CTX *mem_ctx, + const struct hive_key *key, const char *name, + struct hive_key **subkey); +WERROR hive_enum_key(TALLOC_CTX *mem_ctx, + const struct hive_key *key, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time); + +WERROR hive_set_value (struct hive_key *key, const char *name, + uint32_t type, const DATA_BLOB data); + +WERROR hive_get_value (TALLOC_CTX *mem_ctx, + struct hive_key *key, const char *name, + uint32_t *type, DATA_BLOB *data); +WERROR hive_get_value_by_index (TALLOC_CTX *mem_ctx, + struct hive_key *key, uint32_t idx, const char **name, + uint32_t *type, DATA_BLOB *data); + +WERROR hive_del_value (struct hive_key *key, const char *name); + +WERROR hive_key_flush(struct hive_key *key); + + +/* Individual backends */ +WERROR reg_open_directory(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key); +WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key); +WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + struct hive_key **k); + + +WERROR reg_create_directory(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key); +WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, + const char *location, + int major_version, + struct hive_key **key); + + +#endif /* __REGISTRY_HIVE_H__ */ diff --git a/source4/lib/registry/interface.c b/source4/lib/registry/interface.c new file mode 100644 index 0000000000..4d75e99f00 --- /dev/null +++ b/source4/lib/registry/interface.c @@ -0,0 +1,277 @@ +/* + Unix SMB/CIFS implementation. + Transparent registry backend handling + Copyright (C) Jelmer Vernooij 2003-2007. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "lib/util/dlinklist.h" +#include "lib/registry/registry.h" +#include "system/filesys.h" +#include "build.h" + + +/** + * @file + * @brief Main registry functions + */ + +const struct reg_predefined_key reg_predefined_keys[] = { + {HKEY_CLASSES_ROOT,"HKEY_CLASSES_ROOT" }, + {HKEY_CURRENT_USER,"HKEY_CURRENT_USER" }, + {HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" }, + {HKEY_PERFORMANCE_DATA, "HKEY_PERFORMANCE_DATA" }, + {HKEY_USERS, "HKEY_USERS" }, + {HKEY_CURRENT_CONFIG, "HKEY_CURRENT_CONFIG" }, + {HKEY_DYN_DATA, "HKEY_DYN_DATA" }, + {HKEY_PERFORMANCE_TEXT, "HKEY_PERFORMANCE_TEXT" }, + {HKEY_PERFORMANCE_NLSTEXT, "HKEY_PERFORMANCE_NLSTEXT" }, + { 0, NULL } +}; + +/** Obtain name of specific hkey. */ +_PUBLIC_ const char *reg_get_predef_name(uint32_t hkey) +{ + int i; + for (i = 0; reg_predefined_keys[i].name; i++) { + if (reg_predefined_keys[i].handle == hkey) + return reg_predefined_keys[i].name; + } + + return NULL; +} + +/** Get predefined key by name. */ +_PUBLIC_ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, + const char *name, + struct registry_key **key) +{ + int i; + + for (i = 0; reg_predefined_keys[i].name; i++) { + if (!strcasecmp(reg_predefined_keys[i].name, name)) + return reg_get_predefined_key(ctx, reg_predefined_keys[i].handle, + key); + } + + DEBUG(1, ("No predefined key with name '%s'\n", name)); + + return WERR_BADFILE; +} + +/** Get predefined key by id. */ +_PUBLIC_ WERROR reg_get_predefined_key(const struct registry_context *ctx, + uint32_t hkey, struct registry_key **key) +{ + return ctx->ops->get_predefined_key(ctx, hkey, key); +} + +/** + * Open a key + * First tries to use the open_key function from the backend + * then falls back to get_subkey_by_name and later get_subkey_by_index + */ +_PUBLIC_ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, + const char *name, struct registry_key **result) +{ + if (parent == NULL) { + DEBUG(0, ("Invalid parent key specified for open of '%s'\n", name)); + return WERR_INVALID_PARAM; + } + + if (parent->context->ops->open_key == NULL) { + DEBUG(0, ("Registry backend doesn't have open_key!\n")); + return WERR_NOT_SUPPORTED; + } + + return parent->context->ops->open_key(mem_ctx, parent, name, result); +} + +/** + * Get value by index + */ +_PUBLIC_ WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + uint32_t idx, + const char **name, + uint32_t *type, + DATA_BLOB *data) +{ + if (key == NULL) + return WERR_INVALID_PARAM; + + if (key->context->ops->enum_value == NULL) + return WERR_NOT_SUPPORTED; + + return key->context->ops->enum_value(mem_ctx, key, idx, name, type, + data); +} + +/** + * Get the number of subkeys. + */ +_PUBLIC_ WERROR reg_key_get_info(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time) +{ + if (key == NULL) + return WERR_INVALID_PARAM; + + if (key->context->ops->get_key_info == NULL) + return WERR_NOT_SUPPORTED; + + return key->context->ops->get_key_info(mem_ctx, + key, classname, num_subkeys, + num_values, last_change_time); +} + +/** + * Get subkey by index. + */ +_PUBLIC_ WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, + const struct registry_key *key, int idx, const char **name, + const char **keyclass, NTTIME *last_changed_time) +{ + if (key == NULL) + return WERR_INVALID_PARAM; + + if (key->context->ops->enum_key == NULL) + return WERR_NOT_SUPPORTED; + + return key->context->ops->enum_key(mem_ctx, key, idx, name, + keyclass, last_changed_time); +} + +/** + * Get value by name. + */ +_PUBLIC_ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char *name, + uint32_t *type, + DATA_BLOB *data) +{ + if (key == NULL) + return WERR_INVALID_PARAM; + + if (key->context->ops->get_value == NULL) + return WERR_NOT_SUPPORTED; + + return key->context->ops->get_value(mem_ctx, key, name, type, data); +} + +/** + * Delete a key. + */ +_PUBLIC_ WERROR reg_key_del(struct registry_key *parent, const char *name) +{ + if (parent == NULL) + return WERR_INVALID_PARAM; + + if (parent->context->ops->delete_key == NULL) + return WERR_NOT_SUPPORTED; + + return parent->context->ops->delete_key(parent, name); +} + +/** + * Add a key. + */ +_PUBLIC_ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, + struct registry_key *parent, + const char *name, const char *key_class, + struct security_descriptor *desc, + struct registry_key **newkey) +{ + if (parent == NULL) + return WERR_INVALID_PARAM; + + if (parent->context->ops->create_key == NULL) { + DEBUG(1, ("Backend '%s' doesn't support method add_key\n", + parent->context->ops->name)); + return WERR_NOT_SUPPORTED; + } + + return parent->context->ops->create_key(mem_ctx, parent, name, + key_class, desc, newkey); +} + +/** + * Set a value. + */ +_PUBLIC_ WERROR reg_val_set(struct registry_key *key, const char *value, + uint32_t type, const DATA_BLOB data) +{ + if (key == NULL) + return WERR_INVALID_PARAM; + + /* A 'real' set function has preference */ + if (key->context->ops->set_value == NULL) { + DEBUG(1, ("Backend '%s' doesn't support method set_value\n", + key->context->ops->name)); + return WERR_NOT_SUPPORTED; + } + + return key->context->ops->set_value(key, value, type, data); +} + +/** + * Get the security descriptor on a key. + */ +_PUBLIC_ WERROR reg_get_sec_desc(TALLOC_CTX *ctx, + const struct registry_key *key, + struct security_descriptor **secdesc) +{ + if (key == NULL) + return WERR_INVALID_PARAM; + + /* A 'real' set function has preference */ + if (key->context->ops->get_security == NULL) + return WERR_NOT_SUPPORTED; + + return key->context->ops->get_security(ctx, key, secdesc); +} + +/** + * Delete a value. + */ +_PUBLIC_ WERROR reg_del_value(struct registry_key *key, const char *valname) +{ + if (key == NULL) + return WERR_INVALID_PARAM; + + if (key->context->ops->delete_value == NULL) + return WERR_NOT_SUPPORTED; + + return key->context->ops->delete_value(key, valname); +} + +/** + * Flush a key to disk. + */ +_PUBLIC_ WERROR reg_key_flush(struct registry_key *key) +{ + if (key == NULL) + return WERR_INVALID_PARAM; + + if (key->context->ops->flush_key == NULL) + return WERR_NOT_SUPPORTED; + + return key->context->ops->flush_key(key); +} diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c new file mode 100644 index 0000000000..8ee4d9f932 --- /dev/null +++ b/source4/lib/registry/ldb.c @@ -0,0 +1,501 @@ +/* + Unix SMB/CIFS implementation. + Registry interface + Copyright (C) Jelmer Vernooij 2004-2007. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "registry.h" +#include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" +#include "db_wrap.h" +#include "librpc/gen_ndr/winreg.h" + +static struct hive_operations reg_backend_ldb; + +struct ldb_key_data +{ + struct hive_key key; + struct ldb_context *ldb; + struct ldb_dn *dn; + struct ldb_message **subkeys, **values; + int subkey_count, value_count; +}; + +static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char **name, + uint32_t *type, DATA_BLOB *data) +{ + const struct ldb_val *val; + if (name != NULL) + *name = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(msg, "value", NULL)); + + if (type != NULL) + *type = ldb_msg_find_attr_as_uint(msg, "type", 0); + val = ldb_msg_find_ldb_val(msg, "data"); + + switch (*type) + { + case REG_SZ: + case REG_EXPAND_SZ: + data->length = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, + val->data, val->length, (void **)&data->data); + break; + + case REG_DWORD: { + uint32_t tmp = strtoul((char *)val->data, NULL, 0); + *data = data_blob_talloc(mem_ctx, &tmp, 4); + } + break; + + default: + *data = data_blob_talloc(mem_ctx, val->data, val->length); + break; + } +} + +static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, + TALLOC_CTX *mem_ctx, const char *name, + uint32_t type, DATA_BLOB data) +{ + struct ldb_val val; + struct ldb_message *msg = talloc_zero(mem_ctx, struct ldb_message); + char *type_s; + + ldb_msg_add_string(msg, "value", talloc_strdup(mem_ctx, name)); + + switch (type) { + case REG_SZ: + case REG_EXPAND_SZ: + val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8, + (void *)data.data, data.length, (void **)&val.data); + ldb_msg_add_value(msg, "data", &val, NULL); + break; + + case REG_DWORD: + ldb_msg_add_string(msg, "data", talloc_asprintf(mem_ctx, "0x%x", IVAL(data.data, 0))); + break; + default: + ldb_msg_add_value(msg, "data", &data, NULL); + } + + + type_s = talloc_asprintf(mem_ctx, "%u", type); + ldb_msg_add_string(msg, "type", type_s); + + return msg; +} + + +static int reg_close_ldb_key(struct ldb_key_data *key) +{ + if (key->subkeys != NULL) { + talloc_free(key->subkeys); + key->subkeys = NULL; + } + + if (key->values != NULL) { + talloc_free(key->values); + key->values = NULL; + } + return 0; +} + +static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, + const struct hive_key *from, + const char *path, const char *add) +{ + TALLOC_CTX *local_ctx; + struct ldb_dn *ret; + char *mypath = talloc_strdup(mem_ctx, path); + char *begin; + struct ldb_key_data *kd = talloc_get_type(from, struct ldb_key_data); + struct ldb_context *ldb = kd->ldb; + + local_ctx = talloc_new(mem_ctx); + + if (add) { + ret = ldb_dn_new(mem_ctx, ldb, add); + } else { + ret = ldb_dn_new(mem_ctx, ldb, NULL); + } + if (!ldb_dn_validate(ret)) { + talloc_free(ret); + talloc_free(local_ctx); + return NULL; + } + + while (mypath) { + char *keyname; + + begin = strrchr(mypath, '\\'); + + if (begin) keyname = begin + 1; + else keyname = mypath; + + if(strlen(keyname)) { + ldb_dn_add_base_fmt(ret, "key=%s", keyname); + } + + if(begin) { + *begin = '\0'; + } else { + break; + } + } + + ldb_dn_add_base(ret, kd->dn); + + talloc_free(local_ctx); + + return ret; +} + +static WERROR cache_subkeys(struct ldb_key_data *kd) +{ + struct ldb_context *c = kd->ldb; + struct ldb_result *res; + int ret; + + ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &res); + + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Error getting subkeys for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); + return WERR_FOOBAR; + } + + kd->subkey_count = res->count; + kd->subkeys = talloc_steal(kd, res->msgs); + talloc_free(res); + + return WERR_OK; +} + +static WERROR cache_values(struct ldb_key_data *kd) +{ + struct ldb_context *c = kd->ldb; + struct ldb_result *res; + int ret; + + ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(value=*)", NULL, &res); + + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Error getting values for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); + return WERR_FOOBAR; + } + kd->value_count = res->count; + kd->values = talloc_steal(kd, res->msgs); + talloc_free(res); + return WERR_OK; +} + + +static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, + const struct hive_key *k, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time) +{ + struct ldb_message_element *el; + struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data); + + /* Do a search if necessary */ + if (kd->subkeys == NULL) { + W_ERROR_NOT_OK_RETURN(cache_subkeys(kd)); + } + + if (idx >= kd->subkey_count) + return WERR_NO_MORE_ITEMS; + + el = ldb_msg_find_element(kd->subkeys[idx], "key"); + SMB_ASSERT(el != NULL); + SMB_ASSERT(el->num_values != 0); + + if (name != NULL) + *name = talloc_strdup(mem_ctx, (char *)el->values[0].data); + + if (classname != NULL) + *classname = NULL; /* TODO: Store properly */ + + if (last_mod_time != NULL) + *last_mod_time = 0; /* TODO: we need to add this to the + ldb backend properly */ + + return WERR_OK; +} + +static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct hive_key *k, int idx, + const char **name, uint32_t *data_type, DATA_BLOB *data) +{ + struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data); + + /* Do the search if necessary */ + if (kd->values == NULL) { + W_ERROR_NOT_OK_RETURN(cache_values(kd)); + } + + if(idx >= kd->value_count) return WERR_NO_MORE_ITEMS; + + reg_ldb_unpack_value(mem_ctx, kd->values[idx], + name, data_type, data); + + return WERR_OK; +} + +static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, + const char *name, uint32_t *data_type, DATA_BLOB *data) +{ + struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data); + struct ldb_context *c = kd->ldb; + struct ldb_result *res; + int ret; + char *query = talloc_asprintf(mem_ctx, "(value=%s)", name); + + ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, query, NULL, &res); + + talloc_free(query); + + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Error getting values for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); + return WERR_FOOBAR; + } + + if (res->count == 0) + return WERR_NOT_FOUND; + + reg_ldb_unpack_value(mem_ctx, res->msgs[0], NULL, data_type, data); + + return WERR_OK; +} + +static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, + const char *name, struct hive_key **key) +{ + struct ldb_result *res; + struct ldb_dn *ldap_path; + int ret; + struct ldb_key_data *newkd; + struct ldb_key_data *kd = talloc_get_type(h, struct ldb_key_data); + struct ldb_context *c = kd->ldb; + + ldap_path = reg_path_to_ldb(mem_ctx, h, name, NULL); + + ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL, &res); + + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Error opening key '%s': %s\n", + ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); + return WERR_FOOBAR; + } else if (res->count == 0) { + DEBUG(0, ("Key '%s' not found\n", ldb_dn_get_linearized(ldap_path))); + talloc_free(res); + return WERR_NOT_FOUND; + } + + newkd = talloc_zero(mem_ctx, struct ldb_key_data); + newkd->key.ops = ®_backend_ldb; + newkd->ldb = talloc_reference(newkd, kd->ldb); + newkd->dn = ldb_dn_copy(mem_ctx, res->msgs[0]->dn); + + *key = (struct hive_key *)newkd; + + talloc_free(res); + + return WERR_OK; +} + +WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + struct hive_key **k) +{ + struct ldb_key_data *kd; + struct ldb_context *wrap; + + if (location == NULL) + return WERR_INVALID_PARAM; + + wrap = ldb_wrap_connect(parent_ctx, location, session_info, + credentials, 0, NULL); + + if (wrap == NULL) { + DEBUG(1, (__FILE__": unable to connect\n")); + return WERR_FOOBAR; + } + + ldb_set_debug_stderr(wrap); + + kd = talloc_zero(parent_ctx, struct ldb_key_data); + kd->key.ops = ®_backend_ldb; + kd->ldb = talloc_reference(kd, wrap); + talloc_set_destructor (kd, reg_close_ldb_key); + kd->dn = ldb_dn_new(kd, wrap, "hive=NONE"); + + *k = (struct hive_key *)kd; + + return WERR_OK; +} + +static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, const struct hive_key *parent, + const char *name, const char *classname, + struct security_descriptor *sd, + struct hive_key **newkey) +{ + const struct ldb_key_data *parentkd = (const struct ldb_key_data *)parent; + struct ldb_message *msg; + struct ldb_key_data *newkd; + int ret; + + msg = ldb_msg_new(mem_ctx); + + msg->dn = reg_path_to_ldb(msg, parent, name, NULL); + + ldb_msg_add_string(msg, "key", talloc_strdup(mem_ctx, name)); + if (classname != NULL) + ldb_msg_add_string(msg, "classname", talloc_strdup(mem_ctx, classname)); + + ret = ldb_add(parentkd->ldb, msg); + if (ret < 0) { + DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parentkd->ldb))); + return WERR_FOOBAR; + } + + DEBUG(2, ("key added: %s\n", ldb_dn_get_linearized(msg->dn))); + + newkd = talloc_zero(mem_ctx, struct ldb_key_data); + newkd->ldb = talloc_reference(newkd, parentkd->ldb); + newkd->key.ops = ®_backend_ldb; + newkd->dn = talloc_steal(newkd, msg->dn); + + *newkey = (struct hive_key *)newkd; + + return WERR_OK; +} + +static WERROR ldb_del_key (const struct hive_key *key, const char *child) +{ + int ret; + struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data); + struct ldb_dn *childdn; + + childdn = ldb_dn_copy(parentkd->ldb, parentkd->dn); + ldb_dn_add_child_fmt(childdn, "key=%s", child); + + ret = ldb_delete(parentkd->ldb, childdn); + + talloc_free(childdn); + + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + return WERR_NOT_FOUND; + } else if (ret < 0) { + DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(parentkd->ldb))); + return WERR_FOOBAR; + } + + return WERR_OK; +} + +static WERROR ldb_del_value (struct hive_key *key, const char *child) +{ + int ret; + struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data); + struct ldb_dn *childdn; + + childdn = ldb_dn_copy(kd->ldb, kd->dn); + ldb_dn_add_child_fmt(childdn, "value=%s", child); + + ret = ldb_delete(kd->ldb, childdn); + + talloc_free(childdn); + + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + return WERR_NOT_FOUND; + } else if (ret < 0) { + DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(kd->ldb))); + return WERR_FOOBAR; + } + + return WERR_OK; +} + +static WERROR ldb_set_value(struct hive_key *parent, + const char *name, uint32_t type, + const DATA_BLOB data) +{ + struct ldb_message *msg; + struct ldb_key_data *kd = talloc_get_type(parent, struct ldb_key_data); + int ret; + TALLOC_CTX *mem_ctx = talloc_init("ldb_set_value"); + + msg = reg_ldb_pack_value(kd->ldb, mem_ctx, name, type, data); + + msg->dn = ldb_dn_copy(msg, kd->dn); + ldb_dn_add_child_fmt(msg->dn, "value=%s", name); + + ret = ldb_add(kd->ldb, msg); + if (ret < 0) { + ret = ldb_modify(kd->ldb, msg); + if (ret < 0) { + DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(kd->ldb))); + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + } + + talloc_free(mem_ctx); + return WERR_OK; +} + +static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, + const struct hive_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time) +{ + struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data); + + /* FIXME */ + if (classname != NULL) + *classname = NULL; + + if (num_subkeys != NULL) { + W_ERROR_NOT_OK_RETURN(cache_subkeys(kd)); + *num_subkeys = kd->subkey_count; + } + + if (num_values != NULL) { + W_ERROR_NOT_OK_RETURN(cache_values(kd)); + *num_values = kd->value_count; + } + + if (last_change_time != NULL) + *last_change_time = 0; + + return WERR_OK; +} + +static struct hive_operations reg_backend_ldb = { + .name = "ldb", + .add_key = ldb_add_key, + .del_key = ldb_del_key, + .get_key_by_name = ldb_open_key, + .enum_value = ldb_get_value_by_id, + .enum_key = ldb_get_subkey_by_id, + .set_value = ldb_set_value, + .get_value_by_name = ldb_get_value, + .delete_value = ldb_del_value, + .get_key_info = ldb_get_key_info, +}; diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c new file mode 100644 index 0000000000..aefb11bde2 --- /dev/null +++ b/source4/lib/registry/local.c @@ -0,0 +1,333 @@ +/* + Unix SMB/CIFS implementation. + Transparent registry backend handling + Copyright (C) Jelmer Vernooij 2003-2007. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "lib/util/dlinklist.h" +#include "lib/registry/registry.h" +#include "system/filesys.h" +#include "build.h" + +struct reg_key_path { + uint32_t predefined_key; + const char **elements; +}; + +struct registry_local { + struct registry_context registry; + + struct mountpoint { + struct reg_key_path path; + struct hive_key *key; + struct mountpoint *prev, *next; + } *mountpoints; + + struct auth_session_info *session_info; + struct cli_credentials *credentials; +}; + +struct local_key { + struct registry_key global; + struct reg_key_path path; + struct hive_key *hive_key; +}; + + +struct registry_key *reg_import_hive_key(struct registry_context *ctx, + struct hive_key *hive, + uint32_t predefined_key, + const char **elements) +{ + struct local_key *local_key; + struct reg_key_path parent_path; + + parent_path.predefined_key = predefined_key; + parent_path.elements = elements; + + local_key = talloc(ctx, struct local_key); + local_key->hive_key = talloc_steal(local_key, hive); + local_key->global.context = talloc_reference(local_key, ctx); + local_key->path = parent_path; + + return (struct registry_key *)local_key; +} + + +static WERROR local_open_key(TALLOC_CTX *mem_ctx, + struct registry_key *parent, + const char *path, + struct registry_key **result) +{ + char *orig = talloc_strdup(mem_ctx, path), + *curbegin = orig, + *curend = strchr(orig, '\\'); + struct local_key *local_parent = talloc_get_type(parent, struct local_key); + struct hive_key *curkey = local_parent->hive_key; + WERROR error; + const char **elements = NULL; + int el; + + if (local_parent->path.elements != NULL) { + elements = talloc_array(mem_ctx, const char *, + str_list_length(local_parent->path.elements) + 1); + for (el = 0; local_parent->path.elements[el] != NULL; el++) { + elements[el] = talloc_reference(elements, + local_parent->path.elements[el]); + } + elements[el] = NULL; + } else { + elements = NULL; + el = 0; + } + + while (curbegin != NULL && *curbegin) { + if (curend != NULL) + *curend = '\0'; + elements = talloc_realloc(mem_ctx, elements, const char *, el+2); + elements[el] = talloc_strdup(elements, curbegin); + el++; + elements[el] = NULL; + error = hive_get_key_by_name(mem_ctx, curkey, curbegin, &curkey); + if (!W_ERROR_IS_OK(error)) { + DEBUG(2, ("Opening key %s failed: %s\n", curbegin, win_errstr(error))); + talloc_free(orig); + return error; + } + if (curend == NULL) + break; + curbegin = curend + 1; + curend = strchr(curbegin, '\\'); + } + talloc_free(orig); + + *result = reg_import_hive_key(local_parent->global.context, curkey, + local_parent->path.predefined_key, + talloc_steal(curkey, elements)); + + return WERR_OK; +} + +WERROR local_get_predefined_key (const struct registry_context *ctx, + uint32_t key_id, struct registry_key **key) +{ + struct registry_local *rctx = talloc_get_type(ctx, struct registry_local); + struct mountpoint *mp; + + for (mp = rctx->mountpoints; mp != NULL; mp = mp->next) { + if (mp->path.predefined_key == key_id && + mp->path.elements == NULL) + break; + } + + if (mp == NULL) + return WERR_NOT_FOUND; + + *key = reg_import_hive_key(ctx, mp->key, + mp->path.predefined_key, + mp->path.elements + ); + + return WERR_OK; +} + +WERROR local_enum_key(TALLOC_CTX *mem_ctx, + const struct registry_key *key, uint32_t idx, + const char **name, + const char **keyclass, + NTTIME *last_changed_time) +{ + const struct local_key *local = (const struct local_key *)key; + + return hive_enum_key(mem_ctx, local->hive_key, idx, name, keyclass, + last_changed_time); +} + +static WERROR local_create_key (TALLOC_CTX *mem_ctx, + struct registry_key *parent_key, + const char *name, + const char *key_class, + struct security_descriptor *security, + struct registry_key **key) +{ + const struct local_key *local_parent; + struct hive_key *hivekey; + const char **elements; + int i; + char *last_part; + + last_part = strrchr(name, '\\'); + if (last_part == NULL) { + last_part = name; + local_parent = (const struct local_key *)parent_key; + } else { + W_ERROR_NOT_OK_RETURN(reg_open_key(mem_ctx, parent_key, + talloc_strndup(mem_ctx, name, last_part-name), + &local_parent)); + last_part++; + } + + W_ERROR_NOT_OK_RETURN(hive_key_add_name(mem_ctx, local_parent->hive_key, + last_part, key_class, security, &hivekey)); + + if (local_parent->path.elements != NULL) { + elements = talloc_array(hivekey, const char *, + str_list_length(local_parent->path.elements)+2); + for (i = 0; local_parent->path.elements[i] != NULL; i++) { + elements[i] = talloc_reference(elements, + local_parent->path.elements[i]); + } + } else { + elements = talloc_array(hivekey, const char *, 2); + i = 0; + } + + elements[i] = talloc_strdup(elements, name); + elements[i+1] = NULL; + + *key = reg_import_hive_key(local_parent->global.context, hivekey, + local_parent->path.predefined_key, + elements); + + return WERR_OK; +} + +static WERROR local_set_value (struct registry_key *key, const char *name, + uint32_t type, const DATA_BLOB data) +{ + struct local_key *local = (struct local_key *)key; + + return hive_set_value(local->hive_key, name, type, data); +} + +static WERROR local_get_value (TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char *name, uint32_t *type, DATA_BLOB *data) +{ + const struct local_key *local = (const struct local_key *)key; + + return hive_get_value(mem_ctx, local->hive_key, name, type, data); +} + +static WERROR local_enum_value (TALLOC_CTX *mem_ctx, + const struct registry_key *key, uint32_t idx, + const char **name, + uint32_t *type, + DATA_BLOB *data) +{ + const struct local_key *local = (const struct local_key *)key; + + return hive_get_value_by_index(mem_ctx, local->hive_key, idx, + name, type, data); +} + +static WERROR local_delete_key (struct registry_key *key, const char *name) +{ + const struct local_key *local = (const struct local_key *)key; + + return hive_key_del(local->hive_key, name); +} + +static WERROR local_delete_value (struct registry_key *key, const char *name) +{ + const struct local_key *local = (const struct local_key *)key; + + return hive_del_value(local->hive_key, name); +} + +static WERROR local_flush_key (struct registry_key *key) +{ + const struct local_key *local = (const struct local_key *)key; + + return hive_key_flush(local->hive_key); +} + +static WERROR local_get_key_info (TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time) +{ + const struct local_key *local = (const struct local_key *)key; + + return hive_key_get_info(mem_ctx, local->hive_key, + classname, num_subkeys, num_values, + last_change_time); +} + +const static struct registry_operations local_ops = { + .name = "local", + .open_key = local_open_key, + .get_predefined_key = local_get_predefined_key, + .enum_key = local_enum_key, + .create_key = local_create_key, + .set_value = local_set_value, + .get_value = local_get_value, + .enum_value = local_enum_value, + .delete_key = local_delete_key, + .delete_value = local_delete_value, + .flush_key = local_flush_key, + .get_key_info = local_get_key_info, +}; + +WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials) +{ + struct registry_local *ret = talloc_zero(mem_ctx, struct registry_local); + + W_ERROR_HAVE_NO_MEMORY(ret); + + ret->registry.ops = &local_ops; + ret->session_info = session_info; + ret->credentials = credentials; + + *ctx = (struct registry_context *)ret; + + return WERR_OK; +} + +WERROR reg_mount_hive(struct registry_context *rctx, + struct hive_key *hive_key, + uint32_t key_id, + const char **elements) +{ + struct registry_local *reg_local = talloc_get_type(rctx, struct registry_local); + struct mountpoint *mp = talloc(rctx, struct mountpoint); + int i = 0; + + mp->path.predefined_key = key_id; + mp->prev = mp->next = NULL; + mp->key = hive_key; + if (elements != NULL) { + mp->path.elements = talloc_array(mp, const char *, + str_list_length(elements)); + for (i = 0; elements[i] != NULL; i++) { + mp->path.elements[i] = talloc_reference(mp->path.elements, + elements[i]); + } + mp->path.elements[i] = NULL; + } else { + mp->path.elements = NULL; + } + + DLIST_ADD(reg_local->mountpoints, mp); + + return WERR_OK; +} diff --git a/source4/lib/registry/man/regdiff.1.xml b/source4/lib/registry/man/regdiff.1.xml index 0e237bfece..7bcaa1502c 100644 --- a/source4/lib/registry/man/regdiff.1.xml +++ b/source4/lib/registry/man/regdiff.1.xml @@ -54,7 +54,7 @@ --backend BACKEND Name of backend to load. Possible values are: - w95, nt4, gconf, dir and rpc. The default is dir. + creg, regf, dir and rpc. The default is dir. This argument can be specified twice: once for the first diff --git a/source4/lib/registry/man/regpatch.1.xml b/source4/lib/registry/man/regpatch.1.xml index c04bad9e66..d9dcdcbf80 100644 --- a/source4/lib/registry/man/regpatch.1.xml +++ b/source4/lib/registry/man/regpatch.1.xml @@ -49,7 +49,7 @@ --backend BACKEND Name of backend to load. Possible values are: - w95, nt4, gconf, dir and rpc. The default is dir. + creg, regf, dir and rpc. The default is dir. diff --git a/source4/lib/registry/man/regshell.1.xml b/source4/lib/registry/man/regshell.1.xml index edec729120..9f16d8cc24 100644 --- a/source4/lib/registry/man/regshell.1.xml +++ b/source4/lib/registry/man/regshell.1.xml @@ -48,7 +48,7 @@ --backend BACKEND Name of backend to load. Possible values are: - w95, nt4, gconf, dir and rpc. The default is dir. + creg, regf, dir and rpc. The default is dir. diff --git a/source4/lib/registry/man/regtree.1.xml b/source4/lib/registry/man/regtree.1.xml index aa31855a2b..93f15e1fb2 100644 --- a/source4/lib/registry/man/regtree.1.xml +++ b/source4/lib/registry/man/regtree.1.xml @@ -48,7 +48,7 @@ --backend BACKEND Name of backend to load. Possible values are: - w95, nt4, gconf, dir and rpc. The default is dir. + creg, regf, dir and rpc. The default is dir. diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index 12847eedd8..50c8f54397 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -1,8 +1,9 @@ /* Unix SMB/CIFS implementation. - Reading .REG files + Reading registry patch files - Copyright (C) Jelmer Vernooij 2004 + Copyright (C) Jelmer Vernooij 2004-2007 + Copyright (C) Wilco Baan Hofman 2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,153 +20,191 @@ */ #include "includes.h" +#include "lib/registry/patchfile.h" #include "lib/registry/registry.h" #include "system/filesys.h" -/** - * @file - * @brief Registry patch files - */ - -#define DEFAULT_IDENT_STRING "SAMBA4 REGISTRY" - -static struct reg_diff_key *diff_find_add_key(struct reg_diff *diff, const char *path) -{ - int i; - - for (i = 0; diff->numkeys; i++) { - if (!strcasecmp(diff->keys[i].name, path)) - return &diff->keys[i]; - } - diff->keys = talloc_realloc(diff, diff->keys, struct reg_diff_key, diff->numkeys+2); - diff->keys[diff->numkeys].name = talloc_strdup(diff->keys, path); - diff->keys[diff->numkeys].changetype = REG_DIFF_CHANGE_KEY; - diff->keys[diff->numkeys].numvalues = 0; - diff->keys[diff->numkeys].values = NULL; +_PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *callbacks, void *callback_data); - diff->numkeys++; - return NULL; -} +_PUBLIC_ WERROR reg_dotreg_diff_load(int fd, const struct reg_diff_callbacks *callbacks, void *callback_data); /* * Generate difference between two keys */ -static WERROR reg_generate_diff_key(struct reg_diff *diff, struct registry_key *oldkey, struct registry_key *newkey) +WERROR reg_generate_diff_key(struct registry_key *oldkey, + struct registry_key *newkey, + const char *path, + const struct reg_diff_callbacks *callbacks, + void *callback_data) { int i; struct registry_key *t1, *t2; - struct registry_value *v1, *v2; - WERROR error1, error2; + char *tmppath; + const char *keyname1; + WERROR error, error1, error2; TALLOC_CTX *mem_ctx = talloc_init("writediff"); + uint32_t old_num_subkeys, old_num_values, + new_num_subkeys, new_num_values; - /* Subkeys that were deleted */ - for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_subkey_by_index(mem_ctx, oldkey, i, &t1)); i++) { - error2 = reg_key_get_subkey_by_name(mem_ctx, newkey, t1->name, &t2); + if (oldkey != NULL) { + error = reg_key_get_info(mem_ctx, oldkey, NULL, &old_num_subkeys, &old_num_values, + NULL); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error occured while getting key info: %s\n", + win_errstr(error))); + return error; + } + } else { + old_num_subkeys = 0; + old_num_values = 0; + } - if (W_ERROR_IS_OK(error2)) + /* Subkeys that were deleted */ + for (i = 0; i < old_num_subkeys; i++) { + error1 = reg_key_get_subkey_by_index(mem_ctx, oldkey, i, &keyname1, + NULL, NULL); + if (!W_ERROR_IS_OK(error1)) { + DEBUG(0, ("Error occured while getting subkey by index: %s\n", + win_errstr(error2))); continue; + } + + if (newkey != NULL) { + error2 = reg_open_key(mem_ctx, newkey, keyname1, &t2); + + if (W_ERROR_IS_OK(error2)) + continue; + } else { + error2 = WERR_DEST_NOT_FOUND; + t2 = NULL; + } if (!W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - DEBUG(0, ("Error occured while getting subkey by name: %d\n", W_ERROR_V(error2))); + DEBUG(0, ("Error occured while getting subkey by name: %s\n", + win_errstr(error2))); + talloc_free(mem_ctx); return error2; } /* newkey didn't have such a subkey, add del diff */ - diff->keys = talloc_realloc(diff, diff->keys, struct reg_diff_key, diff->numkeys+2); - diff->keys[diff->numkeys].name = talloc_strdup(diff->keys, t1->path); - diff->keys[diff->numkeys].changetype = REG_DIFF_DEL_KEY; - diff->numkeys++; + tmppath = talloc_asprintf(mem_ctx, "%s\\%s", path, keyname1); + callbacks->del_key(callback_data, tmppath); + talloc_free(tmppath); } - if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while getting subkey by index: %d\n", W_ERROR_V(error1))); - talloc_free(mem_ctx); - return error1; + if (newkey != NULL) { + error = reg_key_get_info(mem_ctx, newkey, NULL, &new_num_subkeys, &new_num_values, + NULL); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error occured while getting key info: %s\n", + win_errstr(error))); + return error; + } + } else { + new_num_subkeys = 0; + new_num_values = 0; } /* Subkeys that were added */ - for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_subkey_by_index(mem_ctx, newkey, i, &t1)); i++) { - error2 = reg_key_get_subkey_by_name(mem_ctx, oldkey, t1->name, &t2); + for(i = 0; i < new_num_subkeys; i++) { + error1 = reg_key_get_subkey_by_index(mem_ctx, newkey, i, &keyname1, + NULL, NULL); + if (!W_ERROR_IS_OK(error1)) { + DEBUG(0, ("Error occured while getting subkey by index: %s\n", + win_errstr(error1))); + talloc_free(mem_ctx); + return error1; + } + + if (oldkey != NULL) { + error2 = reg_open_key(mem_ctx, oldkey, keyname1, &t1); + + if (W_ERROR_IS_OK(error2)) + continue; + } else { + t1 = NULL; + error2 = WERR_DEST_NOT_FOUND; + } - if (W_ERROR_IS_OK(error2)) - continue; - if (!W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - DEBUG(0, ("Error occured while getting subkey by name: %d\n", W_ERROR_V(error2))); + DEBUG(0, ("Error occured while getting subkey by name: %s\n", + win_errstr(error2))); + talloc_free(mem_ctx); return error2; } /* oldkey didn't have such a subkey, add add diff */ - diff->keys = talloc_realloc(diff, diff->keys, struct reg_diff_key, diff->numkeys+2); - diff->keys[diff->numkeys].name = talloc_strdup(diff->keys, t1->path); - diff->keys[diff->numkeys].changetype = REG_DIFF_CHANGE_KEY; - diff->keys[diff->numkeys].numvalues = 0; - diff->keys[diff->numkeys].values = NULL; - diff->numkeys++; - - reg_generate_diff_key(diff, t1, t2); - } + tmppath = talloc_asprintf(mem_ctx, "%s\\%s", path, keyname1); + callbacks->add_key(callback_data, tmppath); - if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while getting subkey by index: %d\n", W_ERROR_V(error1))); - talloc_free(mem_ctx); - return error1; + W_ERROR_NOT_OK_RETURN( + reg_open_key(mem_ctx, newkey, keyname1, &t2)); + + reg_generate_diff_key(t1, t2, tmppath, callbacks, callback_data); + talloc_free(tmppath); } /* Values that were changed */ - for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(mem_ctx, newkey, i, &v1)); i++) { - struct reg_diff_key *thiskey = NULL; - error2 = reg_key_get_value_by_name(mem_ctx, oldkey, v1->name, &v2); + for(i = 0; i < new_num_values; i++) { + const char *name; + uint32_t type1, type2; + DATA_BLOB contents1, contents2; + + error1 = reg_key_get_value_by_index(mem_ctx, newkey, i, + &name, &type1, &contents1); + if (!W_ERROR_IS_OK(error1)) { + DEBUG(0, ("Unable to get key by index: %s\n", + win_errstr(error1))); + talloc_free(mem_ctx); + return error1; + } + + if (oldkey != NULL) { + error2 = reg_key_get_value_by_name(mem_ctx, oldkey, name, + &type2, &contents2); + } else + error2 = WERR_DEST_NOT_FOUND; if(!W_ERROR_IS_OK(error2) && !W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - DEBUG(0, ("Error occured while getting value by name: %d\n", W_ERROR_V(error2))); + DEBUG(0, ("Error occured while getting value by name: %s\n", + win_errstr(error2))); + talloc_free(mem_ctx); return error2; } - if (W_ERROR_IS_OK(error2) && data_blob_cmp(&v1->data, &v2->data) == 0) + if (W_ERROR_IS_OK(error2) && data_blob_cmp(&contents1, &contents2) == 0) continue; - thiskey = diff_find_add_key(diff, oldkey->path); - thiskey->values = talloc_realloc(diff, thiskey->values, struct reg_diff_value, thiskey->numvalues+2); - thiskey->values[thiskey->numvalues].name = talloc_strdup(thiskey->values, v1->name); - thiskey->values[thiskey->numvalues].type = v2->data_type; - thiskey->values[thiskey->numvalues].changetype = REG_DIFF_SET_VAL; - thiskey->values[thiskey->numvalues].data = data_blob_dup_talloc(thiskey->values, &v2->data); - thiskey->numvalues++; - } - - if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while getting value by index: %d\n", W_ERROR_V(error1))); - talloc_free(mem_ctx); - return error1; + callbacks->set_value(callback_data, path, name, type1, contents1); } /* Values that were deleted */ - for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(mem_ctx, oldkey, i, &v1)); i++) { - struct reg_diff_key *thiskey = NULL; - error2 = reg_key_get_value_by_name(mem_ctx, newkey, v1->name, &v2); + for (i = 0; i < old_num_values; i++) { + const char *name; + error1 = reg_key_get_value_by_index(mem_ctx, oldkey, i, &name, + NULL, NULL); + if (!W_ERROR_IS_OK(error1)) { + DEBUG(0, ("Error ocurred getting value by index: %s\n", + win_errstr(error1))); + talloc_free(mem_ctx); + return error1; + } + + error2 = reg_key_get_value_by_name(mem_ctx, newkey, name, NULL, + NULL); if (W_ERROR_IS_OK(error2)) continue; if (!W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - DEBUG(0, ("Error occured while getting value by name: %d\n", W_ERROR_V(error2))); + DEBUG(0, ("Error occured while getting value by name: %s\n", + win_errstr(error2))); return error2; } - thiskey = diff_find_add_key(diff, oldkey->path); - thiskey->values = talloc_realloc(diff, thiskey->values, struct reg_diff_value, thiskey->numvalues+2); - thiskey->values[thiskey->numvalues].name = talloc_strdup(thiskey->values, v1->name); - thiskey->values[thiskey->numvalues].changetype = REG_DIFF_DEL_VAL; - thiskey->numvalues++; - } - - if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while getting value by index: %d\n", W_ERROR_V(error1))); - talloc_free(mem_ctx); - return error1; + callbacks->del_value(callback_data, path, name); } talloc_free(mem_ctx); @@ -175,244 +214,206 @@ static WERROR reg_generate_diff_key(struct reg_diff *diff, struct registry_key * /** * Generate diff between two registry contexts */ -_PUBLIC_ struct reg_diff *reg_generate_diff(TALLOC_CTX *mem_ctx, struct registry_context *ctx1, struct registry_context *ctx2) +_PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1, + struct registry_context *ctx2, + const struct reg_diff_callbacks *callbacks, + void *callback_data) { - struct reg_diff *diff = talloc_zero(mem_ctx, struct reg_diff); int i; WERROR error; - for(i = HKEY_CLASSES_ROOT; i <= HKEY_PERFORMANCE_NLSTEXT; i++) { - struct registry_key *r1, *r2; + for(i = HKEY_FIRST; i <= HKEY_LAST; i++) { + struct registry_key *r1 = NULL, *r2 = NULL; error = reg_get_predefined_key(ctx1, i, &r1); - if (!W_ERROR_IS_OK(error)) { + if (!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_NOT_FOUND)) { DEBUG(0, ("Unable to open hive %s for backend 1\n", reg_get_predef_name(i))); - continue; } error = reg_get_predefined_key(ctx2, i, &r2); - if (!W_ERROR_IS_OK(error)) { + if (!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_NOT_FOUND)) { DEBUG(0, ("Unable to open hive %s for backend 2\n", reg_get_predef_name(i))); - continue; } - reg_generate_diff_key(diff, r1, r2); - } - - return diff; -} - -/** - * Save registry diff - */ -_PUBLIC_ WERROR reg_diff_save(const struct reg_diff *diff, const char *filename) -{ - int xf, i, j; - - if (filename) { - xf = open(filename, O_CREAT, 0755); - if (xf == -1) { - DEBUG(0, ("Unable to open %s\n", filename)); - return WERR_BADFILE; - } - } else - xf = STDIN_FILENO; - - fdprintf(xf, "%s\n\n", diff->format?diff->format:DEFAULT_IDENT_STRING); - - for (i = 0; i < diff->numkeys; i++) { - if (diff->keys[i].changetype == REG_DIFF_DEL_KEY) { - fdprintf(xf, "-%s\n\n", diff->keys[i].name); + if (r1 == NULL && r2 == NULL) continue; - } - fdprintf(xf, "[%s]\n", diff->keys[i].name); - - for (j = 0; j < diff->keys[i].numvalues; j++) { - fdprintf(xf, "\"%s\"=", diff->keys[i].values[j].name); - switch (diff->keys[i].values[j].changetype) { - case REG_DIFF_DEL_VAL: - fdprintf(xf, "-\n"); - break; - case REG_DIFF_SET_VAL: - fdprintf(xf, "%s:%s\n", - str_regtype(diff->keys[i].values[j].type), - reg_val_data_string(NULL, - diff->keys[i].values[j].type, - &diff->keys[i].values[j].data)); - break; - } + error = reg_generate_diff_key(r1, r2, reg_get_predef_name(i), callbacks, callback_data); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Unable to determine diff: %s\n", win_errstr(error))); + return error; } - - fdprintf(xf, "\n"); } - - close(xf); - + if (callbacks->done != NULL) { + callbacks->done(callback_data); + } return WERR_OK; } /** * Load diff file */ -_PUBLIC_ struct reg_diff *reg_diff_load(TALLOC_CTX *ctx, const char *fn) +_PUBLIC_ WERROR reg_diff_load(const char *filename, const struct reg_diff_callbacks *callbacks, void *callback_data) { - struct reg_diff *diff; int fd; - char *line, *p, *q; - struct reg_diff_key *curkey = NULL; - struct reg_diff_value *curval; - - fd = open(fn, O_RDONLY, 0); + char hdr[4]; + + fd = open(filename, O_RDONLY, 0); if (fd == -1) { - DEBUG(0, ("Error opening registry patch file `%s'\n", fn)); - return NULL; + DEBUG(0, ("Error opening registry patch file `%s'\n", filename)); + return WERR_GENERAL_FAILURE; } - diff = talloc_zero(ctx, struct reg_diff); - if (diff == NULL) { - close(fd); - return NULL; + if (read(fd, &hdr, 4) != 4) { + DEBUG(0, ("Error reading registry patch file `%s'\n", filename)); + return WERR_GENERAL_FAILURE; } - - diff->format = afdgets(fd, diff, 0); - if (!diff->format) { - talloc_free(diff); - close(fd); - return NULL; + + /* Reset position in file */ + lseek(fd, 0, SEEK_SET); +#if 0 + if (strncmp(hdr, "CREG", 4) == 0) { + /* Must be a W9x CREG Config.pol file */ + return reg_creg_diff_load(diff, fd); + } else if (strncmp(hdr, "regf", 4) == 0) { + /* Must be a REGF NTConfig.pol file */ + return reg_regf_diff_load(diff, fd); + } else +#endif + if (strncmp(hdr, "PReg", 4) == 0) { + /* Must be a GPO Registry.pol file */ + return reg_preg_diff_load(fd, callbacks, callback_data); + } else { + /* Must be a normal .REG file */ + return reg_dotreg_diff_load(fd, callbacks, callback_data); } +} - while ((line = afdgets(fd, diff, 0))) { - /* Ignore comments and empty lines */ - if (strlen(line) == 0 || line[0] == ';') { - curkey = NULL; - talloc_free(line); - continue; - } +/** + * The reg_diff_apply functions + */ +static WERROR reg_diff_apply_add_key(void *_ctx, const char *key_name) +{ + struct registry_context *ctx = _ctx; + struct registry_key *tmp; + WERROR error; - /* Start of key */ - if (line[0] == '[') { - p = strchr_m(line, ']'); - if (p[strlen(p)-2] != ']') { - DEBUG(0, ("Malformed line\n")); - return NULL; - } - diff->keys = talloc_realloc(diff, diff->keys, struct reg_diff_key, diff->numkeys+2); - diff->keys[diff->numkeys].name = talloc_strndup(diff->keys, line+1, strlen(line)-2); - diff->keys[diff->numkeys].changetype = REG_DIFF_CHANGE_KEY; - diff->keys[diff->numkeys].numvalues = 0; - diff->keys[diff->numkeys].values = NULL; - curkey = &diff->keys[diff->numkeys]; - diff->numkeys++; - talloc_free(line); - continue; - } + error = reg_key_add_abs(ctx, ctx, key_name, 0, NULL, &tmp); - /* Deleting key */ - if (line[0] == '-') { - diff->keys = talloc_realloc(diff, diff->keys, struct reg_diff_key, diff->numkeys+2); - diff->keys[diff->numkeys].name = talloc_strdup(diff->keys, line+1); - diff->keys[diff->numkeys].changetype = REG_DIFF_DEL_KEY; - diff->numkeys++; - talloc_free(line); - continue; - } + if (!W_ERROR_EQUAL(error, WERR_ALREADY_EXISTS) && !W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error adding new key '%s': %s\n", key_name, win_errstr(error))); + return error; + } + return WERR_OK; +} - /* Deleting/Changing value */ - p = strchr_m(line, '='); - if (p == NULL) { - DEBUG(0, ("Malformed line\n")); - talloc_free(line); - continue; - } +static WERROR reg_diff_apply_del_key(void *_ctx, const char *key_name) +{ + struct registry_context *ctx = _ctx; + WERROR error; - *p = '\0'; p++; + error = reg_key_del_abs(ctx, key_name); - if (curkey == NULL) { - DEBUG(0, ("Value change without key\n")); - talloc_free(line); - continue; - } + if(!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Unable to delete key '%s'\n", key_name)); + return error; + } + + return WERR_OK; +} - curkey->values = talloc_realloc(diff->keys, curkey->values, struct reg_diff_value, curkey->numvalues+2); - curval = &curkey->values[curkey->numvalues]; - curkey->numvalues++; - curval->name = talloc_strdup(curkey->values, line); +static WERROR reg_diff_apply_set_value(void *_ctx, const char *path, const char *value_name, uint32_t value_type, DATA_BLOB value) +{ + struct registry_context *ctx = _ctx; + struct registry_key *tmp; + WERROR error; + + /* Open key */ + error = reg_open_key_abs(ctx, ctx, path, &tmp); - /* Delete value */ - if (strcmp(p, "-")) { - curval->changetype = REG_DIFF_DEL_VAL; - talloc_free(line); - continue; - } - - q = strchr_m(p, ':'); - if (q) { - *q = '\0'; - q++; - } + if (W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) { + DEBUG(0, ("Error opening key '%s'\n", path)); + return error; + } - curval->changetype = REG_DIFF_SET_VAL; - reg_string_to_val(curkey->values, q?p:"REG_SZ", q?q:p, &curval->type, &curval->data); + /* Set value */ + error = reg_val_set(tmp, value_name, + value_type, value); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error setting value '%s'\n", value_name)); + return error; + } + + return WERR_OK; +} - talloc_free(line); +static WERROR reg_diff_apply_del_value (void *_ctx, const char *key_name, const char *value_name) +{ + struct registry_context *ctx = _ctx; + struct registry_key *tmp; + WERROR error; + + /* Open key */ + error = reg_open_key_abs(ctx, ctx, key_name, &tmp); + + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error opening key '%s'\n", key_name)); + return error; } - close(fd); + error = reg_del_value(tmp, value_name); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error deleting value '%s'\n", value_name)); + return error; + } + - return diff; + return WERR_OK; } -/** - * Apply diff to a registry context - */ -_PUBLIC_ BOOL reg_diff_apply (const struct reg_diff *diff, struct registry_context *ctx) +static WERROR reg_diff_apply_del_all_values(void *_ctx, const char *key_name) { - TALLOC_CTX *mem_ctx = talloc_init("apply_cmd_file"); - struct registry_key *tmp = NULL; + struct registry_context *ctx = _ctx; + struct registry_key *key; WERROR error; - int i, j; + int i; + uint32_t num_values; - for (i = 0; i < diff->numkeys; i++) { - if (diff->keys[i].changetype == REG_DIFF_DEL_KEY) { - error = reg_key_del_abs(ctx, diff->keys[i].name); + error = reg_open_key_abs(ctx, ctx, key_name, &key); - if(!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Unable to delete key '%s'\n", diff->keys[i].name)); - return False; - } + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error opening key '%s'\n", key_name)); + return error; + } - continue; - } + W_ERROR_NOT_OK_RETURN(reg_key_get_info(ctx, key, + NULL, + NULL, + &num_values, + NULL)); + + for (i = 0; i < num_values; i++) { + const char *name; + W_ERROR_NOT_OK_RETURN(reg_key_get_value_by_index(ctx, key, i, &name, + NULL, NULL)); + W_ERROR_NOT_OK_RETURN(reg_del_value(key, name)); + } - /* Add / change key */ - error = reg_open_key_abs(mem_ctx, ctx, diff->keys[i].name, &tmp); + return WERR_OK; +} - /* If we found it, apply the other bits, else create such a key */ - if (W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) { - if(!W_ERROR_IS_OK(reg_key_add_abs(mem_ctx, ctx, diff->keys[i].name, 0, NULL, &tmp))) { - DEBUG(0, ("Error adding new key '%s'\n", diff->keys[i].name)); - return False; - } - } +/** + * Apply diff to a registry context + */ +_PUBLIC_ WERROR reg_diff_apply (const char *filename, struct registry_context *ctx) +{ + struct reg_diff_callbacks callbacks; - for (j = 0; j < diff->keys[i].numvalues; j++) { - if (diff->keys[i].values[j].changetype == REG_DIFF_DEL_VAL) { - error = reg_del_value(tmp, diff->keys[i].values[j].name); - if (!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error deleting value '%s'\n", diff->keys[i].values[j].name)); - return False; - } - - error = reg_val_set(tmp, diff->keys[i].values[j].name, - diff->keys[i].values[j].type, - diff->keys[i].values[j].data); - if (!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error setting value '%s'\n", diff->keys[i].values[j].name)); - return False; - } - } - } - } + callbacks.add_key = reg_diff_apply_add_key; + callbacks.del_key = reg_diff_apply_del_key; + callbacks.set_value = reg_diff_apply_set_value; + callbacks.del_value = reg_diff_apply_del_value; + callbacks.del_all_values = reg_diff_apply_del_all_values; + callbacks.done = NULL; - return True; + return reg_diff_load(filename, &callbacks, ctx); } diff --git a/source4/lib/registry/patchfile.h b/source4/lib/registry/patchfile.h new file mode 100644 index 0000000000..194e2a132a --- /dev/null +++ b/source4/lib/registry/patchfile.h @@ -0,0 +1,52 @@ +/* + Unix SMB/CIFS implementation. + Patchfile interface + Copyright (C) Jelmer Vernooij 2006 + Copyright (C) Wilco Baan Hofman 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _PATCHFILE_H +#define _PATCHFILE_H + +#include "lib/registry/registry.h" + +struct reg_diff_callbacks { + WERROR (*add_key) (void *callback_data, const char *key_name); + WERROR (*set_value) (void *callback_data, const char *key_name, + const char *value_name, uint32_t value_type, DATA_BLOB value); + WERROR (*del_value) (void *callback_data, const char *key_name, const char *value_name); + WERROR (*del_key) (void *callback_data, const char *key_name); + WERROR (*del_all_values) (void *callback_data, const char *key_name); + WERROR (*done) (void *callback_data); +}; + +_PUBLIC_ WERROR reg_diff_apply (const char *filename, + struct registry_context *ctx); + +_PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1, + struct registry_context *ctx2, + const struct reg_diff_callbacks *callbacks, + void *callback_data); +_PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, + struct reg_diff_callbacks **callbacks, void **callback_data); +_PUBLIC_ WERROR reg_generate_diff_key(struct registry_key *oldkey, + struct registry_key *newkey, + const char *path, + const struct reg_diff_callbacks *callbacks, + void *callback_data); + +#endif /* _PATCHFILE_H */ diff --git a/source4/lib/registry/patchfile_dotreg.c b/source4/lib/registry/patchfile_dotreg.c new file mode 100644 index 0000000000..f11ceb1be0 --- /dev/null +++ b/source4/lib/registry/patchfile_dotreg.c @@ -0,0 +1,247 @@ +/* + Unix SMB/CIFS implementation. + Reading .REG files + + Copyright (C) Jelmer Vernooij 2004-2007 + Copyright (C) Wilco Baan Hofman 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* FIXME Newer .REG files, created by Windows XP and above use unicode UTF-16 */ + +#include "includes.h" +#include "lib/registry/patchfile.h" +#include "lib/registry/registry.h" +#include "system/filesys.h" + +/** + * @file + * @brief Registry patch files + */ + +#define HEADER_STRING "REGEDIT4" + +struct dotreg_data { + int fd; +}; + +static WERROR reg_dotreg_diff_add_key(void *_data, const char *key_name) +{ + struct dotreg_data *data = _data; + + fdprintf(data->fd, "\n[%s]\n", key_name); + + return WERR_OK; +} + +static WERROR reg_dotreg_diff_del_key(void *_data, const char *key_name) +{ + struct dotreg_data *data = _data; + + fdprintf(data->fd, "\n[-%s]\n", key_name); + + return WERR_OK; +} + +static WERROR reg_dotreg_diff_set_value(void *_data, const char *path, + const char *value_name, uint32_t value_type, DATA_BLOB value) +{ + struct dotreg_data *data = _data; + + fdprintf(data->fd, "\"%s\"=%s:%s\n", + value_name, str_regtype(value_type), + reg_val_data_string(NULL, value_type, value)); + + return WERR_OK; +} + +static WERROR reg_dotreg_diff_del_value(void *_data, const char *path, const char *value_name) +{ + struct dotreg_data *data = _data; + + fdprintf(data->fd, "\"%s\"=-\n", value_name); + + return WERR_OK; +} + +static WERROR reg_dotreg_diff_done(void *_data) +{ + struct dotreg_data *data = _data; + + close(data->fd); + talloc_free(data); + + return WERR_OK; +} + +static WERROR reg_dotreg_diff_del_all_values (void *callback_data, const char *key_name) +{ + return WERR_NOT_SUPPORTED; +} + +/** + * Save registry diff + */ +_PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, + struct reg_diff_callbacks **callbacks, void **callback_data) +{ + struct dotreg_data *data; + + data = talloc_zero(ctx, struct dotreg_data); + *callback_data = data; + + if (filename) { + data->fd = open(filename, O_CREAT, 0755); + if (data->fd == -1) { + DEBUG(0, ("Unable to open %s\n", filename)); + return WERR_BADFILE; + } + } else { + data->fd = STDOUT_FILENO; + } + + fdprintf(data->fd, "%s\n", HEADER_STRING); + + *callbacks = talloc(ctx, struct reg_diff_callbacks); + + (*callbacks)->add_key = reg_dotreg_diff_add_key; + (*callbacks)->del_key = reg_dotreg_diff_del_key; + (*callbacks)->set_value = reg_dotreg_diff_set_value; + (*callbacks)->del_value = reg_dotreg_diff_del_value; + (*callbacks)->del_all_values = reg_dotreg_diff_del_all_values; + (*callbacks)->done = reg_dotreg_diff_done; + + return WERR_OK; +} + +/** + * Load diff file + */ +_PUBLIC_ WERROR reg_dotreg_diff_load(int fd, const struct reg_diff_callbacks *callbacks, void *callback_data) +{ + char *line, *p, *q; + char *curkey = NULL; + TALLOC_CTX *mem_ctx = talloc_init("reg_dotreg_diff_load"); + WERROR error; + uint32_t value_type; + DATA_BLOB value; + + line = afdgets(fd, mem_ctx, 0); + if (!line) { + DEBUG(0, ("Can't read from file.\n")); + talloc_free(mem_ctx); + close(fd); + return WERR_GENERAL_FAILURE; + } + + while ((line = afdgets(fd, mem_ctx, 0))) { + /* Ignore comments and empty lines */ + if (strlen(line) == 0 || line[0] == ';') { + talloc_free(line); + + if (curkey) { + talloc_free(curkey); + } + curkey = NULL; + continue; + } + + /* Start of key */ + if (line[0] == '[') { + p = strchr_m(line, ']'); + if (p[strlen(p)-1] != ']') { + DEBUG(0, ("Missing ']'\n")); + return WERR_GENERAL_FAILURE; + } + /* Deleting key */ + if (line[1] == '-') { + curkey = talloc_strndup(line, line+2, strlen(line)-3); + + error = callbacks->del_key(callback_data, curkey); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0,("Error deleting key %s\n", curkey)); + talloc_free(mem_ctx); + return error; + } + + talloc_free(line); + curkey = NULL; + continue; + } + curkey = talloc_strndup(mem_ctx, line+1, strlen(line)-2); + + error = callbacks->add_key(callback_data, curkey); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0,("Error adding key %s\n", curkey)); + talloc_free(mem_ctx); + return error; + } + + talloc_free(line); + continue; + } + + /* Deleting/Changing value */ + p = strchr_m(line, '='); + if (p == NULL) { + DEBUG(0, ("Malformed line\n")); + talloc_free(line); + continue; + } + + *p = '\0'; p++; + + if (curkey == NULL) { + DEBUG(0, ("Value change without key\n")); + talloc_free(line); + continue; + } + + /* Delete value */ + if (strcmp(p, "-")) { + error = callbacks->del_value(callback_data, curkey, line); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error deleting value %s in key %s\n", line, curkey)); + talloc_free(mem_ctx); + return error; + } + + talloc_free(line); + continue; + } + + q = strchr_m(p, ':'); + if (q) { + *q = '\0'; + q++; + } + + reg_string_to_val(line, q?p:"REG_SZ", q?q:p, &value_type, &value); + + error = callbacks->set_value(callback_data, curkey, line, value_type, value); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error setting value for %s in %s\n", line, curkey)); + talloc_free(mem_ctx); + return error; + } + + talloc_free(line); + } + + close(fd); + + return WERR_OK; +} diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c new file mode 100644 index 0000000000..1c8d76538a --- /dev/null +++ b/source4/lib/registry/patchfile_preg.c @@ -0,0 +1,270 @@ +/* + Unix SMB/CIFS implementation. + Reading Registry.pol PReg registry files + + Copyright (C) Wilco Baan Hofman 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "lib/registry/registry.h" +#include "system/filesys.h" +#include "pstring.h" + +struct preg_data { + int fd; +}; + +static WERROR preg_read_utf16(int fd, char *c) +{ + uint16_t v; + + if (read(fd, &v, 2) < 2) { + return WERR_GENERAL_FAILURE; + } + push_codepoint(c, v); + return WERR_OK; +} + +/* FIXME These functions need to be implemented */ +static WERROR reg_preg_diff_add_key(void *_data, const char *key_name) +{ + struct preg_data *data = _data; + return WERR_OK; +} + +static WERROR reg_preg_diff_del_key(void *_data, const char *key_name) +{ + struct preg_data *data = _data; + return WERR_OK; +} + +static WERROR reg_preg_diff_set_value(void *_data, const char *key_name, const char *value_name, uint32_t value_type, DATA_BLOB value_data) +{ + struct preg_data *data = _data; + return WERR_OK; +} + +static WERROR reg_preg_diff_del_value(void *_data, const char *key_name, const char *value_name) +{ + struct preg_data *data = _data; + return WERR_OK; +} + +static WERROR reg_preg_diff_del_all_values(void *_data, const char *key_name) +{ + struct preg_data *data = _data; + return WERR_OK; +} + +static WERROR reg_preg_diff_done(void *_data) +{ + struct preg_data *data = _data; + + close(data->fd); + talloc_free(data); + return WERR_OK; +} + +/** + * Save registry diff + */ +_PUBLIC_ WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename, struct reg_diff_callbacks **callbacks, void **callback_data) +{ + struct preg_data *data; + struct { + char hdr[4]; + uint32_t version; + } preg_header; + + + data = talloc_zero(ctx, struct preg_data); + *callback_data = data; + + if (filename) { + data->fd = open(filename, O_CREAT, 0755); + if (data->fd == -1) { + DEBUG(0, ("Unable to open %s\n", filename)); + return WERR_BADFILE; + } + } else { + data->fd = STDOUT_FILENO; + } + snprintf(preg_header.hdr, 4, "PReg"); + SIVAL(&preg_header, 4, 1); + write(data->fd, (uint8_t *)&preg_header,8); + + *callbacks = talloc(ctx, struct reg_diff_callbacks); + + (*callbacks)->add_key = reg_preg_diff_add_key; + (*callbacks)->del_key = reg_preg_diff_del_key; + (*callbacks)->set_value = reg_preg_diff_set_value; + (*callbacks)->del_value = reg_preg_diff_del_value; + (*callbacks)->del_all_values = reg_preg_diff_del_all_values; + (*callbacks)->done = reg_preg_diff_done; + + return WERR_OK; +} +/** + * Load diff file + */ +_PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *callbacks, void *callback_data) +{ + struct { + char hdr[4]; + uint32_t version; + } preg_header; + pstring buf; + char *buf_ptr = buf; + TALLOC_CTX *mem_ctx = talloc_init("reg_preg_diff_load"); + + + /* Read first 8 bytes (the header) */ + if (read(fd, &preg_header, 8) != 8) { + DEBUG(0, ("Could not read PReg file: %s\n", + strerror(errno))); + close(fd); + return WERR_GENERAL_FAILURE; + } + if (strncmp(preg_header.hdr, "PReg", 4) != 0) { + DEBUG(0, ("This file is not a valid preg registry file\n")); + close(fd); + return WERR_GENERAL_FAILURE; + } + if (preg_header.version > 1) { + DEBUG(0, ("Warning: file format version is higher than expected.\n")); + } + + /* Read the entries */ + while(1) { + char *key, *value_name; + uint32_t value_type, length; + DATA_BLOB data; + + if (!W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr))) { + break; + } + if (*buf_ptr != '[') { + DEBUG(0, ("Error in PReg file.\n")); + close(fd); + return WERR_GENERAL_FAILURE; + } + + /* Get the path */ + buf_ptr = buf; + while (W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr != ';' && buf_ptr-buf < sizeof(buf)) { + buf_ptr++; + } + key = talloc_asprintf(mem_ctx, "\\%s", buf); + + /* Get the name */ + buf_ptr = buf; + while (W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr != ';' && buf_ptr-buf < sizeof(buf)) { + buf_ptr++; + } + value_name = talloc_strdup(mem_ctx, buf); + + /* Get the type */ + if (read(fd, &value_type, 4) < 4) { + DEBUG(0, ("Error while reading PReg\n")); + close(fd); + return WERR_GENERAL_FAILURE; + } + /* Read past delimiter */ + buf_ptr = buf; + if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr == ';') && buf_ptr-buf < sizeof(buf)) { + DEBUG(0, ("Error in PReg file.\n")); + close(fd); + return WERR_GENERAL_FAILURE; + } + /* Get data length */ + if (read(fd, &length, 4) < 4) { + DEBUG(0, ("Error while reading PReg\n")); + close(fd); + return WERR_GENERAL_FAILURE; + } + /* Read past delimiter */ + buf_ptr = buf; + if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr == ';') && buf_ptr-buf < sizeof(buf)) { + DEBUG(0, ("Error in PReg file.\n")); + close(fd); + return WERR_GENERAL_FAILURE; + } + /* Get the data */ + buf_ptr = buf; + if (length < sizeof(buf) && read(fd, buf_ptr, length) != length) { + DEBUG(0, ("Error while reading PReg\n")); + close(fd); + return WERR_GENERAL_FAILURE; + } + data.length = length; + data.data = talloc_memdup(mem_ctx, buf, length); + + /* Check if delimiter is in place (whine if it isn't) */ + buf_ptr = buf; + if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr == ']') && buf_ptr-buf < sizeof(buf)) { + DEBUG(0, ("Warning: Missing ']' in PReg file, expected ']', got '%c' 0x%x.\n",*buf_ptr, *buf_ptr)); + } + + if (strcasecmp(value_name, "**DelVals") == 0) { + callbacks->del_all_values(callback_data, key); + } else if (strncasecmp(value_name, "**Del.",6) == 0) { + char *p = value_name+6; + + callbacks->del_value(callback_data, key, p); + } else if (strcasecmp(value_name, "**DeleteValues") == 0) { + char *p, *q; + + p = (char *) data.data; + + while ((q = strchr_m(p, ';'))) { + *q = '\0'; + q++; + + callbacks->del_value(callback_data, key, p); + + p = q; + } + callbacks->del_value(callback_data, key, p); + } else if (strcasecmp(value_name, "**DeleteKeys") == 0) { + char *p, *q, *full_key; + + p = (char *) data.data; + + while ((q = strchr_m(p, ';'))) { + *q = '\0'; + q++; + + full_key = talloc_asprintf(mem_ctx, "%s\\%s", key, p); + callbacks->del_key(callback_data, full_key); + talloc_free(full_key); + + p = q; + } + full_key = talloc_asprintf(mem_ctx, "%s\\%s", key, p); + callbacks->del_key(callback_data, full_key); + talloc_free(full_key); + } else { + callbacks->add_key(callback_data, key); + callbacks->set_value(callback_data, key, value_name, value_type, data); + } + talloc_free(key); + talloc_free(value_name); + talloc_free(data.data); + } + close(fd); + return WERR_OK; +} diff --git a/source4/lib/registry/reg_backend_dir.c b/source4/lib/registry/reg_backend_dir.c deleted file mode 100644 index c2dd3dad00..0000000000 --- a/source4/lib/registry/reg_backend_dir.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Registry interface - Copyright (C) Jelmer Vernooij 2004. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "registry.h" -#include "system/dir.h" -#include "system/filesys.h" - -static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx, const struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *desc, struct registry_key **result) -{ - char *path; - int ret; - asprintf(&path, "%s%s\\%s", parent->hive->location, parent->path, name); - path = reg_path_win2unix(path); - ret = mkdir(path, 0700); - SAFE_FREE(path); - if(ret == 0)return WERR_OK; /* FIXME */ - return WERR_INVALID_PARAM; -} - -static WERROR reg_dir_del_key(const struct registry_key *k, const char *name) -{ - char *child = talloc_asprintf(NULL, "%s/%s", (char *)k->backend_data, name); - WERROR ret; - - if (rmdir(child) == 0) ret = WERR_OK; else ret = WERR_GENERAL_FAILURE; - - talloc_free(child); - - return ret; -} - -static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, const struct registry_key *p, const char *name, struct registry_key **subkey) -{ - DIR *d; - char *fullpath, *unixpath; - struct registry_key *ret; - - if(!name) { - DEBUG(0, ("NULL pointer passed as directory name!")); - return WERR_INVALID_PARAM; - } - - - fullpath = talloc_asprintf(mem_ctx, "%s/%s", (char *)p->backend_data, name); - unixpath = reg_path_win2unix(fullpath); - - d = opendir(unixpath); - if(!d) { - DEBUG(3,("Unable to open '%s': %s\n", unixpath, strerror(errno))); - return WERR_BADFILE; - } - closedir(d); - ret = talloc(mem_ctx, struct registry_key); - ret->hive = p->hive; - ret->path = fullpath; - ret->backend_data = unixpath; - *subkey = ret; - return WERR_OK; -} - -static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *k, int idx, struct registry_key **key) -{ - struct dirent *e; - char *fullpath = k->backend_data; - int i = 0; - DIR *d; - - d = opendir(fullpath); - - if(!d) return WERR_INVALID_PARAM; - - while((e = readdir(d))) { - if(!ISDOT(e->d_name) && !ISDOTDOT(e->d_name)) { - struct stat stbuf; - char *thispath; - - /* Check if file is a directory */ - asprintf(&thispath, "%s/%s", fullpath, e->d_name); - stat(thispath, &stbuf); - - if(S_ISDIR(stbuf.st_mode)) { - if(i == idx) { - (*key) = talloc(mem_ctx, struct registry_key); - (*key)->name = talloc_strdup(*key, e->d_name); - (*key)->path = NULL; - (*key)->backend_data = talloc_strdup(*key, thispath); - SAFE_FREE(thispath); - closedir(d); - return WERR_OK; - } - i++; - } - - SAFE_FREE(thispath); - } - } - - closedir(d); - - return WERR_NO_MORE_ITEMS; -} - -static WERROR reg_dir_open(struct registry_hive *h, struct registry_key **key) -{ - if(!h->location) return WERR_INVALID_PARAM; - - *key = talloc(h, struct registry_key); - (*key)->backend_data = talloc_strdup(*key, h->location); - return WERR_OK; -} - -static struct hive_operations reg_backend_dir = { - .name = "dir", - .open_hive = reg_dir_open, - .open_key = reg_dir_open_key, - .add_key = reg_dir_add_key, - .del_key = reg_dir_del_key, - .get_subkey_by_index = reg_dir_key_by_index -}; - -NTSTATUS registry_dir_init(void) -{ - return registry_register(®_backend_dir); -} diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c deleted file mode 100644 index ca9327c174..0000000000 --- a/source4/lib/registry/reg_backend_ldb.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Registry interface - Copyright (C) Jelmer Vernooij 2004. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "registry.h" -#include "lib/ldb/include/ldb.h" -#include "lib/ldb/include/ldb_errors.h" -#include "db_wrap.h" -#include "librpc/gen_ndr/winreg.h" - -struct ldb_key_data -{ - struct ldb_dn *dn; - struct ldb_message **subkeys, **values; - int subkey_count, value_count; -}; - -static int ldb_free_hive (struct registry_hive *hive) -{ - talloc_free(hive->backend_data); - hive->backend_data = NULL; - return 0; -} - -static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char **name, uint32_t *type, DATA_BLOB *data) -{ - const struct ldb_val *val; - *name = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(msg, "value", NULL)); - *type = ldb_msg_find_attr_as_uint(msg, "type", 0); - val = ldb_msg_find_ldb_val(msg, "data"); - - switch (*type) - { - case REG_SZ: - case REG_EXPAND_SZ: - data->length = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, val->data, val->length, (void **)&data->data); - break; - - case REG_DWORD: { - uint32_t tmp = strtoul((char *)val->data, NULL, 0); - *data = data_blob_talloc(mem_ctx, &tmp, 4); - } - break; - - default: - *data = data_blob_talloc(mem_ctx, val->data, val->length); - break; - } -} - -static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, const char *name, uint32_t type, DATA_BLOB data) -{ - struct ldb_val val; - struct ldb_message *msg = talloc_zero(mem_ctx, struct ldb_message); - char *type_s; - - ldb_msg_add_string(msg, "value", talloc_strdup(mem_ctx, name)); - - switch (type) { - case REG_SZ: - case REG_EXPAND_SZ: - val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8, (void *)data.data, data.length, (void **)&val.data); - ldb_msg_add_value(msg, "data", &val, NULL); - break; - - case REG_DWORD: - ldb_msg_add_string(msg, "data", talloc_asprintf(mem_ctx, "0x%x", IVAL(data.data, 0))); - break; - default: - ldb_msg_add_value(msg, "data", &data, NULL); - } - - - type_s = talloc_asprintf(mem_ctx, "%u", type); - ldb_msg_add_string(msg, "type", type_s); - - return msg; -} - - -static int reg_close_ldb_key(struct registry_key *key) -{ - struct ldb_key_data *kd = talloc_get_type(key->backend_data, struct ldb_key_data); -/* struct ldb_context *c = key->hive->backend_data; */ - - if (kd->subkeys) { - talloc_free(kd->subkeys); - kd->subkeys = NULL; - } - - if (kd->values) { - talloc_free(kd->values); - kd->values = NULL; - } - return 0; -} - -static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const struct registry_key *from, const char *path, const char *add) -{ - TALLOC_CTX *local_ctx; - struct ldb_dn *ret; - char *mypath = talloc_strdup(mem_ctx, path); - char *begin; - struct ldb_key_data *kd = talloc_get_type(from->backend_data, struct ldb_key_data); - struct ldb_context *ldb = talloc_get_type(from->hive->backend_data, struct ldb_context); - - local_ctx = talloc_new(mem_ctx); - - if (add) { - ret = ldb_dn_new(mem_ctx, ldb, add); - } else { - ret = ldb_dn_new(mem_ctx, ldb, NULL); - } - if ( ! ldb_dn_validate(ret)) { - talloc_free(ret); - talloc_free(local_ctx); - return NULL; - } - - while(mypath) { - char *keyname; - - begin = strrchr(mypath, '\\'); - - if (begin) keyname = begin + 1; - else keyname = mypath; - - if(strlen(keyname)) { - ldb_dn_add_base_fmt(ret, "key=%s", keyname); - } - - if(begin) { - *begin = '\0'; - } else { - break; - } - } - - ldb_dn_add_base(ret, kd->dn); - - talloc_free(local_ctx); - - return ret; -} - - -static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, const struct registry_key *k, int idx, struct registry_key **subkey) -{ - struct ldb_context *c = talloc_get_type(k->hive->backend_data, struct ldb_context); - struct ldb_message_element *el; - struct ldb_key_data *kd = talloc_get_type(k->backend_data, struct ldb_key_data); - struct ldb_key_data *newkd; - - /* Do a search if necessary */ - if (kd->subkeys == NULL) { - struct ldb_result *res; - int ret; - - ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &res); - - if (ret != LDB_SUCCESS) { - DEBUG(0, ("Error getting subkeys for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); - return WERR_FOOBAR; - } - - kd->subkey_count = res->count; - kd->subkeys = talloc_steal(kd, res->msgs); - talloc_free(res); - } - - if (idx >= kd->subkey_count) return WERR_NO_MORE_ITEMS; - - el = ldb_msg_find_element(kd->subkeys[idx], "key"); - - *subkey = talloc(mem_ctx, struct registry_key); - talloc_set_destructor(*subkey, reg_close_ldb_key); - (*subkey)->name = talloc_strdup(mem_ctx, (char *)el->values[0].data); - (*subkey)->backend_data = newkd = talloc_zero(*subkey, struct ldb_key_data); - (*subkey)->last_mod = 0; /* TODO: we need to add this to the - ldb backend properly */ - newkd->dn = ldb_dn_copy(mem_ctx, kd->subkeys[idx]->dn); - - return WERR_OK; -} - -static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct registry_key *k, int idx, struct registry_value **value) -{ - struct ldb_context *c = talloc_get_type(k->hive->backend_data, struct ldb_context); - struct ldb_key_data *kd = talloc_get_type(k->backend_data, struct ldb_key_data); - - /* Do the search if necessary */ - if (kd->values == NULL) { - struct ldb_result *res; - int ret; - - ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(value=*)", NULL, &res); - - if (ret != LDB_SUCCESS) { - DEBUG(0, ("Error getting values for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); - return WERR_FOOBAR; - } - kd->value_count = res->count; - kd->values = talloc_steal(kd, res->msgs); - talloc_free(res); - } - - if(idx >= kd->value_count) return WERR_NO_MORE_ITEMS; - - *value = talloc(mem_ctx, struct registry_value); - - reg_ldb_unpack_value(mem_ctx, kd->values[idx], &(*value)->name, &(*value)->data_type, &(*value)->data); - - return WERR_OK; -} - -static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct registry_key *h, const char *name, struct registry_key **key) -{ - struct ldb_context *c = talloc_get_type(h->hive->backend_data, struct ldb_context); - struct ldb_result *res; - struct ldb_dn *ldap_path; - int ret; - 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, &res); - - if (ret != LDB_SUCCESS) { - DEBUG(0, ("Error opening key '%s': %s\n", ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); - return WERR_FOOBAR; - } else if (res->count == 0) { - talloc_free(res); - return WERR_BADFILE; - } - - *key = talloc(mem_ctx, struct registry_key); - talloc_set_destructor(*key, reg_close_ldb_key); - (*key)->name = talloc_strdup(mem_ctx, strrchr(name, '\\')?strchr(name, '\\'):name); - (*key)->backend_data = newkd = talloc_zero(*key, struct ldb_key_data); - newkd->dn = ldb_dn_copy(mem_ctx, res->msgs[0]->dn); - - talloc_free(res); - - return WERR_OK; -} - -static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) -{ - struct ldb_key_data *kd; - struct ldb_context *wrap; - - if (!hive->location) return WERR_INVALID_PARAM; - - wrap = ldb_wrap_connect(hive, hive->location, hive->session_info, hive->credentials, 0, NULL); - - if(!wrap) { - DEBUG(1, ("ldb_open_hive: unable to connect\n")); - return WERR_FOOBAR; - } - - ldb_set_debug_stderr(wrap); - hive->backend_data = wrap; - - *k = talloc_zero(hive, struct registry_key); - talloc_set_destructor (*k, reg_close_ldb_key); - talloc_set_destructor (hive, ldb_free_hive); - (*k)->name = talloc_strdup(*k, ""); - (*k)->backend_data = kd = talloc_zero(*k, struct ldb_key_data); - kd->dn = ldb_dn_new(*k, wrap, "hive=NONE"); - - - return WERR_OK; -} - -static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, const struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *sd, struct registry_key **newkey) -{ - struct ldb_context *ctx = talloc_get_type(parent->hive->backend_data, struct ldb_context); - struct ldb_message *msg; - struct ldb_key_data *newkd; - int ret; - - msg = ldb_msg_new(mem_ctx); - - msg->dn = reg_path_to_ldb(msg, parent, name, NULL); - - ldb_msg_add_string(msg, "key", talloc_strdup(mem_ctx, name)); - - ret = ldb_add(ctx, msg); - if (ret < 0) { - DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(ctx))); - return WERR_FOOBAR; - } - - *newkey = talloc_zero(mem_ctx, struct registry_key); - (*newkey)->name = talloc_strdup(mem_ctx, name); - - (*newkey)->backend_data = newkd = talloc_zero(*newkey, struct ldb_key_data); - newkd->dn = talloc_steal(newkd, msg->dn); - - return WERR_OK; -} - -static WERROR ldb_del_key (const struct registry_key *key, const char *child) -{ - struct ldb_context *ctx = talloc_get_type(key->hive->backend_data, struct ldb_context); - int ret; - struct ldb_key_data *kd = talloc_get_type(key->backend_data, struct ldb_key_data); - struct ldb_dn *childdn; - - childdn = ldb_dn_copy(ctx, kd->dn); - ldb_dn_add_child_fmt(childdn, "key=%s", child); - - ret = ldb_delete(ctx, childdn); - - talloc_free(childdn); - - if (ret < 0) { - DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(ctx))); - return WERR_FOOBAR; - } - - return WERR_OK; -} - -static WERROR ldb_del_value (const struct registry_key *key, const char *child) -{ - int ret; - struct ldb_context *ctx = talloc_get_type(key->hive->backend_data, struct ldb_context); - struct ldb_key_data *kd = talloc_get_type(key->backend_data, struct ldb_key_data); - struct ldb_dn *childdn; - - childdn = ldb_dn_copy(ctx, kd->dn); - ldb_dn_add_child_fmt(childdn, "value=%s", child); - - ret = ldb_delete(ctx, childdn); - - talloc_free(childdn); - - if (ret < 0) { - DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(ctx))); - return WERR_FOOBAR; - } - - return WERR_OK; -} - -static WERROR ldb_set_value (const struct registry_key *parent, const char *name, uint32_t type, DATA_BLOB data) -{ - struct ldb_context *ctx = talloc_get_type(parent->hive->backend_data, struct ldb_context); - struct ldb_message *msg; - struct ldb_key_data *kd = talloc_get_type(parent->backend_data, struct ldb_key_data); - int ret; - TALLOC_CTX *mem_ctx = talloc_init("ldb_set_value"); - - msg = reg_ldb_pack_value(ctx, mem_ctx, name, type, data); - - msg->dn = ldb_dn_copy(msg, kd->dn); - ldb_dn_add_child_fmt(msg->dn, "value=%s", name); - - ret = ldb_add(ctx, msg); - if (ret < 0) { - ret = ldb_modify(ctx, msg); - if (ret < 0) { - DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(ctx))); - talloc_free(mem_ctx); - return WERR_FOOBAR; - } - } - - talloc_free(mem_ctx); - return WERR_OK; -} - -static struct hive_operations reg_backend_ldb = { - .name = "ldb", - .add_key = ldb_add_key, - .del_key = ldb_del_key, - .open_hive = ldb_open_hive, - .open_key = ldb_open_key, - .get_value_by_index = ldb_get_value_by_id, - .get_subkey_by_index = ldb_get_subkey_by_id, - .set_value = ldb_set_value, - .del_value = ldb_del_value, -}; - -NTSTATUS registry_ldb_init(void) -{ - return registry_register(®_backend_ldb); -} diff --git a/source4/lib/registry/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4.c deleted file mode 100644 index 74261c57a9..0000000000 --- a/source4/lib/registry/reg_backend_nt4.c +++ /dev/null @@ -1,1124 +0,0 @@ -/* - Samba CIFS implementation - Registry backend for REGF files - Copyright (C) 2005 Jelmer Vernooij, jelmer@samba.org - Copyright (C) 2006 Wilco Baan Hofman, wilco@baanhofman.nl - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include "includes.h" -#include "lib/registry/registry.h" -#include "system/filesys.h" -#include "system/time.h" -#include "lib/registry/tdr_regf.h" -#include "librpc/gen_ndr/ndr_security.h" - -/* TODO: - * - Return error codes that make more sense - * - Locking - */ - -/* - * Read HBIN blocks into memory - */ - -struct regf_data { - int fd; - struct hbin_block **hbins; - struct regf_hdr *header; -}; - -static struct hbin_block *hbin_by_offset (const struct regf_data *data, uint32_t offset, uint32_t *rel_offset) -{ - int i; - - for (i = 0; data->hbins[i]; i++) { - if (offset >= data->hbins[i]->offset_from_first && - offset < data->hbins[i]->offset_from_first+ - data->hbins[i]->offset_to_next) { - if (rel_offset) - *rel_offset = offset - data->hbins[i]->offset_from_first - 0x20; - return data->hbins[i]; - } - } - - return NULL; -} - -/* - * Validate a regf header - * For now, do nothing, but we should check the checksum - */ -static uint32_t regf_hdr_checksum(const uint8_t *buffer) -{ - uint32_t checksum = 0, x; - int i; - - for (i = 0; i < 0x01FB; i+= 4) { - x = IVAL(buffer, i); - checksum ^= x; - } - - return checksum; -} - -static DATA_BLOB hbin_get(const struct regf_data *data, uint32_t offset) -{ - DATA_BLOB ret; - struct hbin_block *hbin; - uint32_t rel_offset; - ret.data = NULL; - ret.length = 0; - - hbin = hbin_by_offset(data, offset, &rel_offset); - - if (hbin == NULL) { - DEBUG(1, ("Can't find HBIN containing 0x%04x\n", offset)); - return ret; - } - - ret.length = IVAL(hbin->data, rel_offset); - if (!(ret.length & 0x80000000)) { - DEBUG(0, ("Trying to use dirty block at 0x%04x\n", offset)); - return ret; - } - - /* remove high bit */ - ret.length = (ret.length ^ 0xffffffff) + 1; - - ret.length -= 4; /* 4 bytes for the length... */ - ret.data = hbin->data + - (offset - hbin->offset_from_first - 0x20) + 4; - - return ret; -} - -static BOOL hbin_get_tdr (struct regf_data *regf, uint32_t offset, TALLOC_CTX *ctx, tdr_pull_fn_t pull_fn, void *p) -{ - struct tdr_pull pull; - - ZERO_STRUCT(pull); - - pull.data = hbin_get(regf, offset); - if (!pull.data.data) { - DEBUG(1, ("Unable to get data at 0x%04x\n", offset)); - return False; - } - - if (NT_STATUS_IS_ERR(pull_fn(&pull, ctx, p))) { - DEBUG(1, ("Error parsing record at 0x%04x using tdr\n", offset)); - return False; - } - - return True; -} - -/* Allocate some new data */ -static DATA_BLOB hbin_alloc (struct regf_data *data, uint32_t size, uint32_t *offset) -{ - DATA_BLOB ret; - uint32_t rel_offset = -1; /* Relative offset ! */ - struct hbin_block *hbin = NULL; - int i; - - *offset = 0; - - if (size == 0) - return data_blob(NULL, 0); - - size += 4; /* Need to include uint32 for the length */ - - /* Allocate as a multiple of 8 */ - size = (size + 7) & ~7; - - ret.data = NULL; - ret.length = 0; - - for (i = 0; (hbin = data->hbins[i]); i++) { - int j; - uint32_t my_size; - for (j = 0; j < hbin->offset_to_next-0x20; j+= my_size) { - uint32_t header = IVAL(hbin->data, j + 4); - my_size = IVAL(hbin->data, j); - - if (my_size == 0x0) { - DEBUG(0, ("Invalid zero-length block! File is corrupt.\n")); - return ret; - } - - if (my_size % 8 != 0) { - DEBUG(0, ("Encountered non-aligned block!\n")); - } - - if (my_size & 0x80000000) { /* Used... */ - my_size = (my_size ^ 0xffffffff) + 1; - } else if (my_size == size) { /* exact match */ - rel_offset = j; - DEBUG(4, ("Found free block of exact size %d in middle of HBIN\n", size)); - break; - } else if (my_size > size) { /* data will remain */ - rel_offset = j; - SIVAL(hbin->data, rel_offset+size, my_size-size); - DEBUG(4, ("Found free block of size %d (needing %d) in middle of HBIN\n", my_size, size)); - break; - } - - if (header == 0xffffffff && - hbin->offset_to_next-rel_offset >= size) { - rel_offset = j; - - DEBUG(4, ("Found free block of size %d at end of HBIN\n", size)); - /* Mark new free block size */ - SIVAL(hbin->data, rel_offset+size,hbin->offset_to_next - rel_offset - size - 0x20); - SIVAL(hbin->data, rel_offset+size+0x4, 0xffffffff); - break; - } - - if (header == 0xffffffff) { - break; - } - } - - if (rel_offset != -1) - break; - } - - /* No space available in previous hbins, - * allocate new one */ - if (data->hbins[i] == NULL) { - DEBUG(4, ("No space available in other HBINs for block of size %d, allocating new HBIN\n", size)); - data->hbins = talloc_realloc(data, data->hbins, struct hbin_block *, i+2); - hbin = talloc(data->hbins, struct hbin_block); - data->hbins[i] = hbin; - data->hbins[i+1] = NULL; - - hbin->HBIN_ID = talloc_strdup(hbin, "hbin"); - hbin->offset_from_first = (i == 0?0:data->hbins[i-1]->offset_from_first+data->hbins[i-1]->offset_to_next); - hbin->offset_to_next = 0x1000; - hbin->unknown[0] = 0; - hbin->unknown[0] = 0; - unix_to_nt_time(&hbin->last_change, time(NULL)); - hbin->block_size = hbin->offset_to_next; - hbin->data = talloc_zero_array(hbin, uint8_t, hbin->block_size - 0x20); - - rel_offset = 0x0; - SIVAL(hbin->data, size, hbin->block_size - size - 0x20); - SIVAL(hbin->data, size + 0x4, 0xffffffff); - } - - /* Set size and mark as used */ - SIVAL(hbin->data, rel_offset, size | 0x80000000); - - ret.data = hbin->data + rel_offset + 0x4; /* Skip past length */ - ret.length = size - 0x4; - if (offset) { - uint32_t new_rel_offset; - *offset = hbin->offset_from_first + rel_offset + 0x20; - SMB_ASSERT(hbin_by_offset(data, *offset, &new_rel_offset) == hbin); - SMB_ASSERT(new_rel_offset == rel_offset); - } - - return ret; -} - -/* Store a data blob. Return the offset at which it was stored */ -static uint32_t hbin_store (struct regf_data *data, DATA_BLOB blob) -{ - uint32_t ret; - DATA_BLOB dest = hbin_alloc(data, blob.length, &ret); - - memcpy(dest.data, blob.data, blob.length); - - return ret; -} - -static uint32_t hbin_store_tdr (struct regf_data *data, tdr_push_fn_t push_fn, void *p) -{ - struct tdr_push *push = talloc_zero(data, struct tdr_push); - uint32_t ret; - - if (NT_STATUS_IS_ERR(push_fn(push, p))) { - DEBUG(0, ("Error during push\n")); - return -1; - } - - ret = hbin_store(data, push->data); - - talloc_free(push); - - return ret; -} - - -/* Free existing data */ -static void hbin_free (struct regf_data *data, uint32_t offset) -{ - uint32_t size; - uint32_t rel_offset; - struct hbin_block *hbin; - - SMB_ASSERT (offset > 0); - - hbin = hbin_by_offset(data, offset, &rel_offset); - - if (hbin == NULL) - return; - - /* Get original size */ - size = IVAL(hbin->data, rel_offset); - - if (!(size & 0x80000000)) { - DEBUG(1, ("Trying to free already freed block at 0x%04x\n", offset)); - return; - } - - /* Mark block as free */ - SIVAL(hbin->data, rel_offset, size &~ 0x80000000); -} - -/* Store a data blob data was already stored, but hsa changed in size - * Will try to save it at the current location if possible, otherwise - * does a free + store */ -static uint32_t hbin_store_resize (struct regf_data *data, uint32_t orig_offset, DATA_BLOB blob) -{ - uint32_t rel_offset; - struct hbin_block *hbin = hbin_by_offset(data, orig_offset, &rel_offset); - uint32_t my_size; - uint32_t orig_size; - uint32_t needed_size; - uint32_t possible_size; - int i; - - SMB_ASSERT(orig_offset > 0); - - if (!hbin) - return hbin_store(data, blob); - - /* Get original size */ - orig_size = IVAL(hbin->data, rel_offset); - - needed_size = blob.length + 4; /* Add uint32 containing length */ - needed_size = (needed_size + 7) & ~7; /* Align */ - - /* Fits into current allocated block */ - if (orig_size >= needed_size) { - memcpy(hbin->data + rel_offset + 0x4, blob.data, blob.length); - return orig_offset; - } - - possible_size = orig_size; - - /* Check if it can be combined with the next few free records */ - for (i = rel_offset; - i < hbin->offset_to_next - 0x20; - i += my_size) { - uint32_t header; - if (IVAL(hbin->data, i) & 0x80000000) /* Used */ - break; - - my_size = IVAL(hbin->data, i); - header = IVAL(hbin->data, i + 4); - if (header == 0xffffffff) { - possible_size = hbin->offset_to_next - 0x20 - rel_offset; - } else if (my_size == 0x0) { - DEBUG(0, ("Invalid zero-length block! File is corrupt.\n")); - break; - } else { - possible_size += my_size; - } - - if (possible_size >= blob.length) { - SIVAL(hbin->data, rel_offset, possible_size); - memcpy(hbin->data + rel_offset + 0x4, blob.data, blob.length); - return orig_offset; - } - - if (header == 0xffffffff) - break; - } - - hbin_free(data, orig_offset); - return hbin_store(data, blob); -} - -static uint32_t hbin_store_tdr_resize (struct regf_data *regf, tdr_push_fn_t push_fn, uint32_t orig_offset, void *p) -{ - struct tdr_push *push = talloc_zero(regf, struct tdr_push); - uint32_t ret; - - if (NT_STATUS_IS_ERR(push_fn(push, p))) { - DEBUG(0, ("Error during push\n")); - return -1; - } - - ret = hbin_store_resize(regf, orig_offset, push->data); - - talloc_free(push); - - return ret; -} - -static WERROR regf_num_subkeys (const struct registry_key *key, uint32_t *count) -{ - struct nk_block *nk = key->backend_data; - - *count = nk->num_subkeys; - - return WERR_OK; -} - -static WERROR regf_num_values (const struct registry_key *key, uint32_t *count) -{ - struct nk_block *nk = key->backend_data; - - *count = nk->num_values; - - return WERR_OK; -} - -static struct registry_key *regf_get_key (TALLOC_CTX *ctx, struct regf_data *regf, uint32_t offset) -{ - struct registry_key *ret; - struct nk_block *nk; - - ret = talloc_zero(ctx, struct registry_key); - nk = talloc(ret, struct nk_block); - if (!hbin_get_tdr(regf, offset, nk, (tdr_pull_fn_t)tdr_pull_nk_block, nk)) { - DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset)); - return NULL; - } - - if (strcmp(nk->header, "nk") != 0) { - DEBUG(0, ("Expected nk record, got %s\n", nk->header)); - talloc_free(ret); - return NULL; - } - - ret->name = talloc_steal(ret, nk->key_name); - ret->last_mod = nk->last_change; - - if (nk->clsname_offset != -1) { - DATA_BLOB data = hbin_get(regf, nk->clsname_offset); - ret->class_name = talloc_strndup(ret, (char*)data.data, nk->clsname_length); - } - ret->backend_data = nk; - - return ret; -} - -static WERROR regf_get_value (TALLOC_CTX *ctx, const struct registry_key *key, int idx, struct registry_value **ret) -{ - struct nk_block *nk = key->backend_data; - struct vk_block *vk; - struct regf_data *regf = key->hive->backend_data; - uint32_t vk_offset; - DATA_BLOB data; - - if (idx >= nk->num_values) - return WERR_NO_MORE_ITEMS; - - data = hbin_get(regf, nk->values_offset); - if (!data.data) { - DEBUG(0, ("Unable to find value list\n")); - return WERR_GENERAL_FAILURE; - } - - if (data.length < nk->num_values * 4) { - DEBUG(1, ("Value counts mismatch\n")); - } - - vk_offset = IVAL(data.data, idx * 4); - - *ret = talloc_zero(ctx, struct registry_value); - if (!(*ret)) - return WERR_NOMEM; - - vk = talloc(*ret, struct vk_block); - if (!vk) - return WERR_NOMEM; - - if (!hbin_get_tdr(regf, vk_offset, vk, (tdr_pull_fn_t)tdr_pull_vk_block, vk)) { - DEBUG(0, ("Unable to get VK block at %d\n", vk_offset)); - return WERR_GENERAL_FAILURE; - } - - (*ret)->name = talloc_steal(*ret, vk->data_name); - (*ret)->data_type = vk->data_type; - if (vk->data_length & 0x80000000) { - vk->data_length &=~0x80000000; - (*ret)->data.data = (uint8_t *)&vk->data_offset; - (*ret)->data.length = vk->data_length; - } else { - (*ret)->data = hbin_get(regf, vk->data_offset); - } - - if ((*ret)->data.length < vk->data_length) { - DEBUG(1, ("Read data less than indicated data length!\n")); - } - - return WERR_OK; -} - -static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, const struct registry_key *key, int idx, struct registry_key **ret) -{ - DATA_BLOB data; - struct nk_block *nk = key->backend_data; - uint32_t key_off=0; - - if (idx >= nk->num_subkeys) - return WERR_NO_MORE_ITEMS; - - data = hbin_get(key->hive->backend_data, nk->subkeys_offset); - if (!data.data) { - DEBUG(0, ("Unable to find subkey list\n")); - return WERR_GENERAL_FAILURE; - } - - if (!strncmp((char *)data.data, "li", 2)) { - struct li_block li; - struct tdr_pull pull; - - DEBUG(10, ("Subkeys in LI list\n")); - ZERO_STRUCT(pull); - pull.data = data; - - if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { - DEBUG(0, ("Error parsing LI list\n")); - return WERR_GENERAL_FAILURE; - } - SMB_ASSERT(!strncmp(li.header, "li",2)); - - if (li.key_count != nk->num_subkeys) { - DEBUG(0, ("Subkey counts don't match\n")); - return WERR_GENERAL_FAILURE; - } - key_off = li.nk_offset[idx]; - - } else if (!strncmp((char *)data.data, "lf", 2)) { - struct lf_block lf; - struct tdr_pull pull; - - DEBUG(10, ("Subkeys in LF list\n")); - ZERO_STRUCT(pull); - pull.data = data; - - if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, nk, &lf))) { - DEBUG(0, ("Error parsing LF list\n")); - return WERR_GENERAL_FAILURE; - } - SMB_ASSERT(!strncmp(lf.header, "lf",2)); - - if (lf.key_count != nk->num_subkeys) { - DEBUG(0, ("Subkey counts don't match\n")); - return WERR_GENERAL_FAILURE; - } - - key_off = lf.hr[idx].nk_offset; - } else if (!strncmp((char *)data.data, "lh", 2)) { - struct lh_block lh; - struct tdr_pull pull; - - DEBUG(10, ("Subkeys in LH list")); - ZERO_STRUCT(pull); - pull.data = data; - - if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { - DEBUG(0, ("Error parsing LH list\n")); - return WERR_GENERAL_FAILURE; - } - SMB_ASSERT(!strncmp(lh.header, "lh",2)); - - if (lh.key_count != nk->num_subkeys) { - DEBUG(0, ("Subkey counts don't match\n")); - return WERR_GENERAL_FAILURE; - } - key_off = lh.hr[idx].nk_offset; - } else if (!strncmp((char *)data.data, "ri", 2)) { - struct ri_block ri; - struct tdr_pull pull; - uint16_t i; - uint16_t sublist_count = 0; - - ZERO_STRUCT(pull); - pull.data = data; - - if (NT_STATUS_IS_ERR(tdr_pull_ri_block(&pull, nk, &ri))) { - DEBUG(0, ("Error parsing RI list\n")); - return WERR_GENERAL_FAILURE; - } - SMB_ASSERT(!strncmp(ri.header, "ri",2)); - - for (i = 0; i < ri.key_count; i++) { - DATA_BLOB list_data; - - /* Get sublist data blob */ - list_data = hbin_get(key->hive->backend_data, ri.offset[i]); - if (!list_data.data) { - DEBUG(0, ("Error getting RI list.")); - return WERR_GENERAL_FAILURE; - } - - ZERO_STRUCT(pull); - pull.data = list_data; - - if (!strncmp((char *)list_data.data, "li", 2)) { - struct li_block li; - - if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { - DEBUG(0, ("Error parsing LI list from RI\n")); - return WERR_GENERAL_FAILURE; - } - SMB_ASSERT(!strncmp(li.header, "li",2)); - - /* Advance to next sublist if necessary */ - if (idx >= sublist_count + li.key_count) { - sublist_count += li.key_count; - continue; - } - key_off = li.nk_offset[idx - sublist_count]; - sublist_count += li.key_count; - break; - } else if (!strncmp((char *)list_data.data, "lh", 2)) { - struct lh_block lh; - - if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { - DEBUG(0, ("Error parsing LH list from RI\n")); - return WERR_GENERAL_FAILURE; - } - SMB_ASSERT(!strncmp(lh.header, "lh",2)); - - - /* Advance to next sublist if necessary */ - if (idx >= sublist_count + lh.key_count) { - sublist_count += lh.key_count; - continue; - } - key_off = lh.hr[idx - sublist_count].nk_offset; - sublist_count += lh.key_count; - break; - } else { - DEBUG(0,("Unknown sublist in ri block\n")); - SMB_ASSERT(0); - } - - } - - if (idx > sublist_count) { - return WERR_NO_MORE_ITEMS; - } - - } else { - DEBUG(0, ("Unknown type for subkey list (0x%04x): %c%c\n", nk->subkeys_offset, data.data[0], data.data[1])); - return WERR_GENERAL_FAILURE; - } - - *ret = regf_get_key (ctx, key->hive->backend_data, key_off); - - return WERR_OK; -} - -static WERROR regf_match_subkey_by_name (TALLOC_CTX *ctx, const struct registry_key *key, uint32_t offset, const char *name, uint32_t *ret) -{ - DATA_BLOB subkey_data; - struct nk_block subkey; - struct tdr_pull pull; - - subkey_data = hbin_get(key->hive->backend_data, offset); - if (!subkey_data.data) { - DEBUG(0, ("Unable to retrieve subkey HBIN\n")); - return WERR_GENERAL_FAILURE; - } - - ZERO_STRUCT(pull); - pull.data = subkey_data; - - if (NT_STATUS_IS_ERR(tdr_pull_nk_block(&pull, ctx, &subkey))) { - DEBUG(0, ("Error parsing NK structure.\n")); - return WERR_GENERAL_FAILURE; - } - if (strncmp(subkey.header, "nk", 2)) { - DEBUG(0, ("Not an NK structure.\n")); - return WERR_GENERAL_FAILURE; - } - if (!strcasecmp(subkey.key_name, name)) { - *ret = offset; - } else { - *ret = 0; - } - return WERR_OK; -} - -static WERROR regf_get_subkey_by_name (TALLOC_CTX *ctx, const struct registry_key *key, const char *name, struct registry_key **ret) -{ - DATA_BLOB data; - struct nk_block *nk = key->backend_data; - uint32_t key_off = 0; - - data = hbin_get(key->hive->backend_data, nk->subkeys_offset); - if (!data.data) { - DEBUG(0, ("Unable to find subkey list\n")); - return WERR_GENERAL_FAILURE; - } - - if (!strncmp((char *)data.data, "li",2)) { - struct li_block li; - struct tdr_pull pull; - uint16_t i; - - DEBUG(10, ("Subkeys in LI list\n")); - ZERO_STRUCT(pull); - pull.data = data; - - if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { - DEBUG(0, ("Error parsing LI list\n")); - return WERR_GENERAL_FAILURE; - } - SMB_ASSERT(!strncmp(li.header, "li",2)); - - if (li.key_count != nk->num_subkeys) { - DEBUG(0, ("Subkey counts don't match\n")); - return WERR_GENERAL_FAILURE; - } - - for (i = 0; i < li.key_count; i++) { - W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, li.nk_offset[i], name, &key_off)); - if (key_off) { - break; - } - } - if (!key_off) { - return WERR_DEST_NOT_FOUND; - } - } else if (!strncmp((char *)data.data, "lf",2)) { - struct lf_block lf; - struct tdr_pull pull; - uint16_t i; - - DEBUG(10, ("Subkeys in LF list\n")); - ZERO_STRUCT(pull); - pull.data = data; - - if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, nk, &lf))) { - DEBUG(0, ("Error parsing LF list\n")); - return WERR_GENERAL_FAILURE; - } - SMB_ASSERT(!strncmp(lf.header, "lf",2)); - - if (lf.key_count != nk->num_subkeys) { - DEBUG(0, ("Subkey counts don't match\n")); - return WERR_GENERAL_FAILURE; - } - - for (i = 0; i < lf.key_count; i++) { - if (strncmp(lf.hr[i].hash, name, 4)) { - continue; - } - W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, lf.hr[i].nk_offset, name, &key_off)); - if (key_off) { - break; - } - } - if (!key_off) { - return WERR_DEST_NOT_FOUND; - } - } else if (!strncmp((char *)data.data, "lh",2)) { - struct lh_block lh; - struct tdr_pull pull; - uint16_t i; - uint32_t hash = 0; - char *hash_name; - - DEBUG(10, ("Subkeys in LH list\n")); - ZERO_STRUCT(pull); - pull.data = data; - - if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { - DEBUG(0, ("Error parsing LH list\n")); - return WERR_GENERAL_FAILURE; - } - SMB_ASSERT(!strncmp(lh.header, "lh",2)); - - if (lh.key_count != nk->num_subkeys) { - DEBUG(0, ("Subkey counts don't match\n")); - return WERR_GENERAL_FAILURE; - } - - /* Compute hash for the name */ - hash_name = strupper_talloc(nk, name); - for (i = 0; *(hash_name + i) != 0; i++) { - hash *= 37; - hash += *(hash_name + i); - } - for (i = 0; i < lh.key_count; i++) { - if (lh.hr[i].base37 != hash) { - continue; - } - W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, lh.hr[i].nk_offset, name, &key_off)); - if (key_off) { - break; - } - } - if (!key_off) { - return WERR_DEST_NOT_FOUND; - } - } else if (!strncmp((char *)data.data, "ri", 2)) { - struct ri_block ri; - struct tdr_pull pull; - uint16_t i, j; - - DEBUG(10, ("Subkeys in RI list\n")); - ZERO_STRUCT(pull); - pull.data = data; - - if (NT_STATUS_IS_ERR(tdr_pull_ri_block(&pull, nk, &ri))) { - DEBUG(0, ("Error parsing RI list\n")); - return WERR_GENERAL_FAILURE; - } - SMB_ASSERT(!strncmp(ri.header, "ri",2)); - - - for (i = 0; i < ri.key_count; i++) { - DATA_BLOB list_data; - - /* Get sublist data blob */ - list_data = hbin_get(key->hive->backend_data, ri.offset[i]); - if (!list_data.data) { - DEBUG(0, ("Error getting RI list.")); - return WERR_GENERAL_FAILURE; - } - - ZERO_STRUCT(pull); - pull.data = list_data; - - if (!strncmp((char *)list_data.data, "li", 2)) { - struct li_block li; - - if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { - DEBUG(0, ("Error parsing LI list from RI\n")); - return WERR_GENERAL_FAILURE; - } - SMB_ASSERT(!strncmp(li.header, "li",2)); - - for (j = 0; j < li.key_count; j++) { - W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, - li.nk_offset[j], name, &key_off)); - if (key_off) { - break; - } - } - } else if (!strncmp((char *)list_data.data, "lh", 2)) { - struct lh_block lh; - uint32_t hash = 0; - char *hash_name; - - if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { - DEBUG(0, ("Error parsing LH list from RI\n")); - return WERR_GENERAL_FAILURE; - } - SMB_ASSERT(!strncmp(lh.header, "lh",2)); - - /* Compute hash for the name */ - hash_name = strupper_talloc(nk, name); - for (j = 0; *(hash_name + j) != 0; j++) { - hash *= 37; - hash += *(hash_name + j); - } - for (j = 0; j < lh.key_count; j++) { - if (lh.hr[j].base37 != hash) { - continue; - } - W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, - lh.hr[j].nk_offset, name, &key_off)); - if (key_off) { - break; - } - } - } - if (key_off) { - break; - } - - } - if (!key_off) { - return WERR_DEST_NOT_FOUND; - } - } else { - DEBUG(0, ("Unknown subkey list type.\n")); - return WERR_GENERAL_FAILURE; - } - - *ret = regf_get_key (ctx, key->hive->backend_data, key_off); - return WERR_OK; -} - -static WERROR regf_set_sec_desc (const struct registry_key *key, const struct security_descriptor *sec_desc) -{ - /* FIXME */ - return WERR_NOT_SUPPORTED; -} - -static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, struct security_descriptor **sd) -{ - struct nk_block *nk = key->backend_data; - struct sk_block sk; - struct regf_data *regf = key->hive->backend_data; - DATA_BLOB data; - - if (!hbin_get_tdr(regf, nk->sk_offset, ctx, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { - DEBUG(0, ("Unable to find security descriptor\n")); - return WERR_GENERAL_FAILURE; - } - - if (strcmp(sk.header, "sk") != 0) { - DEBUG(0, ("Expected 'sk', got '%s'\n", sk.header)); - return WERR_GENERAL_FAILURE; - } - - *sd = talloc(ctx, struct security_descriptor); - if (!*sd) - return WERR_NOMEM; - - data.data = sk.sec_desc; - data.length = sk.rec_size; - if (NT_STATUS_IS_ERR(ndr_pull_struct_blob(&data, ctx, *sd, (ndr_pull_flags_fn_t)ndr_pull_security_descriptor))) { - DEBUG(0, ("Error parsing security descriptor\n")); - return WERR_GENERAL_FAILURE; - } - - return WERR_OK; -} - -static uint32_t lf_add_entry (struct regf_data *regf, uint32_t list_offset, const char *name, uint32_t key_offset) -{ - uint32_t ret; - struct lf_block lf; - - ZERO_STRUCT(lf); - - /* Add to subkeys list */ - if (list_offset == -1) { /* Need to create subkeys list */ - lf.header = "lf"; - } else { - if (!hbin_get_tdr(regf, list_offset, regf, (tdr_pull_fn_t)tdr_pull_lf_block, &lf)) { - DEBUG(0, ("Can't get subkeys list\n")); - return -1; - } - } - - lf.hr = talloc_realloc(regf, lf.hr, struct hash_record, lf.key_count+1); - lf.hr[lf.key_count].nk_offset = key_offset; - lf.hr[lf.key_count].hash = talloc_strndup(regf, name, 4); - lf.key_count++; - - ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t)tdr_push_lf_block, list_offset, &lf); - - talloc_free(lf.hr); - - return ret; -} - -static WERROR regf_del_value (const struct registry_key *parent, const char *name) -{ - /* FIXME */ - return WERR_NOT_SUPPORTED; -} - - -static WERROR regf_del_key (const struct registry_key *parent, const char *name) -{ - struct nk_block *nk = parent->backend_data; - - SMB_ASSERT(nk); - - if (nk->subkeys_offset == -1) - return WERR_BADFILE; - - /* FIXME */ - - return WERR_NOT_SUPPORTED; -} - -static WERROR regf_add_key (TALLOC_CTX *ctx, const struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *sec_desc, struct registry_key **ret) -{ - struct nk_block *parent_nk = parent->backend_data, nk; - struct regf_data *regf = parent->hive->backend_data; - uint32_t offset; - - nk.header = "nk"; - nk.type = REG_SUB_KEY; - unix_to_nt_time(&nk.last_change, time(NULL)); - nk.uk1 = 0; - nk.parent_offset = 0; /* FIXME */ - nk.num_subkeys = 0; - nk.uk2 = 0; - nk.subkeys_offset = -1; - nk.unknown_offset = -1; - nk.num_values = 0; - nk.sk_offset = 0; - memset(nk.unk3, 0, 5); - nk.clsname_offset = -1; - nk.clsname_length = 0; - nk.key_name = name; - - offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_nk_block, &nk); - - parent_nk->subkeys_offset = lf_add_entry(regf, parent_nk->subkeys_offset, name, nk.parent_offset); - - parent_nk->num_subkeys++; - - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, nk.parent_offset, parent_nk); - - *ret = regf_get_key(ctx, regf, offset); - - /* FIXME: Set sec desc ! */ - return WERR_OK; -} - -static WERROR regf_set_value (const struct registry_key *key, const char *name, uint32_t type, const DATA_BLOB data) -{ - /* FIXME */ - - return WERR_NOT_SUPPORTED; -} - -#if 0 /* Unused */ - -static WERROR regf_save_hbin(struct registry_hive *hive, struct hbin_block *hbin) -{ - struct regf_data *regf = hive->backend_data; - - /* go to right offset */ - if (lseek(regf->fd, SEEK_SET, regf->header->data_offset + hbin->offset_from_first) == -1) { - DEBUG(0, ("Error lseeking in regf file\n")); - return WERR_GENERAL_FAILURE; - } - - if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, (tdr_push_fn_t)tdr_push_hbin_block, hbin))) { - DEBUG(0, ("Error writing HBIN block\n")); - return WERR_GENERAL_FAILURE; - } - - return WERR_OK; -} - -#endif - -static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) -{ - struct regf_data *regf; - struct regf_hdr *regf_hdr; - struct tdr_pull pull; - int i; - - regf = (struct regf_data *)talloc_zero(h, struct regf_data); - h->backend_data = regf; - - DEBUG(5, ("Attempting to load registry file\n")); - - /* Get the header */ - regf->fd = open(h->location, O_RDWR); - - if (regf->fd == -1) { - DEBUG(0,("Could not load file: %s, %s\n", h->location, - strerror(errno))); - return WERR_GENERAL_FAILURE; - } - - ZERO_STRUCT(pull); - pull.data.data = (uint8_t*)fd_load(regf->fd, &pull.data.length, regf); - - if (pull.data.data == NULL) { - DEBUG(0, ("Error reading data\n")); - return WERR_GENERAL_FAILURE; - } - - regf_hdr = talloc(regf, struct regf_hdr); - if (NT_STATUS_IS_ERR(tdr_pull_regf_hdr(&pull, regf_hdr, regf_hdr))) { - return WERR_GENERAL_FAILURE; - } - - regf->header = regf_hdr; - - if (strcmp(regf_hdr->REGF_ID, "regf") != 0) { - DEBUG(0, ("Unrecognized NT registry header id: %s, %s\n", - regf_hdr->REGF_ID, h->location)); - } - - DEBUG(1, ("Registry '%s' read. Version %d.%d.%d.%d\n", - regf_hdr->description, regf_hdr->version.major, - regf_hdr->version.minor, regf_hdr->version.release, - regf_hdr->version.build)); - - /* - * Validate the header ... - */ - if (regf_hdr_checksum(pull.data.data) != regf_hdr->chksum) { - DEBUG(0, ("Registry file checksum error: %s: %d,%d\n", - h->location, regf_hdr->chksum, regf_hdr_checksum(pull.data.data))); - return WERR_GENERAL_FAILURE; - } - - pull.offset = 0x1000; - - i = 0; - /* Read in all hbin blocks */ - regf->hbins = talloc_array(regf, struct hbin_block *, 1); - regf->hbins[0] = NULL; - - while (pull.offset < pull.data.length && pull.offset < regf->header->last_block) { - struct hbin_block *hbin = talloc(regf->hbins, struct hbin_block); - - if (NT_STATUS_IS_ERR(tdr_pull_hbin_block(&pull, hbin, hbin))) { - DEBUG(0, ("[%d] Error parsing HBIN block\n", i)); - return WERR_FOOBAR; - } - - if (strcmp(hbin->HBIN_ID, "hbin") != 0) { - DEBUG(0, ("[%d] Expected 'hbin', got '%s'\n", i, hbin->HBIN_ID)); - return WERR_FOOBAR; - } - - regf->hbins[i] = hbin; - i++; - regf->hbins = talloc_realloc(regf, regf->hbins, struct hbin_block *, i+2); - regf->hbins[i] = NULL; - } - - DEBUG(1, ("%d HBIN blocks read\n", i)); - - *key = regf_get_key(h, regf, 0x20); - - return WERR_OK; -} - -static struct hive_operations reg_backend_nt4 = { - .name = "nt4", - .open_hive = nt_open_hive, - .num_subkeys = regf_num_subkeys, - .num_values = regf_num_values, - .get_subkey_by_index = regf_get_subkey_by_index, - .get_subkey_by_name = regf_get_subkey_by_name, - .get_value_by_index = regf_get_value, - .key_get_sec_desc = regf_get_sec_desc, - .key_set_sec_desc = regf_set_sec_desc, - .add_key = regf_add_key, - .set_value = regf_set_value, - .del_key = regf_del_key, - .del_value = regf_del_value, -}; - -NTSTATUS registry_nt4_init(void) -{ - return registry_register(®_backend_nt4); -} diff --git a/source4/lib/registry/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc.c deleted file mode 100644 index 50489aced2..0000000000 --- a/source4/lib/registry/reg_backend_rpc.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - Samba Unix/Linux SMB implementation - RPC backend for the registry library - Copyright (C) 2003-2004 Jelmer Vernooij, jelmer@samba.org - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include "includes.h" -#include "registry.h" -#include "librpc/gen_ndr/ndr_winreg_c.h" - -static struct hive_operations reg_backend_rpc; - -/** - * This is the RPC backend for the registry library. - */ - -static void init_winreg_String(struct winreg_String *name, const char *s) -{ - name->name = s; -} - - -#define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *hnd) \ -{ \ - struct winreg_Open ## u r; \ - NTSTATUS status; \ - \ - r.in.system_name = NULL; \ - r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; \ - r.out.handle = hnd;\ - \ - status = dcerpc_winreg_Open ## u(p, mem_ctx, &r); \ - if (NT_STATUS_IS_ERR(status)) {\ - DEBUG(0,("Error executing open\n"));\ - return ntstatus_to_werror(status);\ - }\ -\ - return r.out.result;\ -} - -openhive(HKLM) -openhive(HKCU) -openhive(HKPD) -openhive(HKU) -openhive(HKCR) -openhive(HKDD) -openhive(HKCC) - -struct rpc_key_data { - struct policy_handle pol; - int num_subkeys; - int num_values; - int max_valnamelen; - int max_valdatalen; -}; - -static struct { - uint32_t hkey; - WERROR (*open) (struct dcerpc_pipe *p, TALLOC_CTX *, struct policy_handle *h); -} known_hives[] = { -{ HKEY_LOCAL_MACHINE, open_HKLM }, -{ HKEY_CURRENT_USER, open_HKCU }, -{ HKEY_CLASSES_ROOT, open_HKCR }, -{ HKEY_PERFORMANCE_DATA, open_HKPD }, -{ HKEY_USERS, open_HKU }, -{ HKEY_DYN_DATA, open_HKDD }, -{ HKEY_CURRENT_CONFIG, open_HKCC }, -{ 0, NULL } -}; - -static WERROR rpc_query_key(const struct registry_key *k); - -static WERROR rpc_get_predefined_key (struct registry_context *ctx, uint32_t hkey_type, struct registry_key **k) -{ - int n; - struct registry_hive *h; - struct rpc_key_data *mykeydata; - - for(n = 0; known_hives[n].hkey; n++) - { - if(known_hives[n].hkey == hkey_type) break; - } - - if(!known_hives[n].open) { - DEBUG(1, ("No such hive %d\n", hkey_type)); - return WERR_NO_MORE_ITEMS; - } - - h = talloc(ctx, struct registry_hive); - h->functions = ®_backend_rpc; - h->location = NULL; - h->backend_data = ctx->backend_data; - - (*k) = h->root = talloc(h, struct registry_key); - (*k)->hive = h; - (*k)->backend_data = mykeydata = talloc(*k, struct rpc_key_data); - mykeydata->num_values = -1; - mykeydata->num_subkeys = -1; - return known_hives[n].open((struct dcerpc_pipe *)ctx->backend_data, *k, &(mykeydata->pol)); -} - -#if 0 -static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) -{ - struct winreg_OpenKey r; - struct rpc_key_data *mykeydata; - - k->backend_data = mykeydata = talloc(mem_ctx, struct rpc_key_data); - mykeydata->num_values = -1; - mykeydata->num_subkeys = -1; - - /* Then, open the handle using the hive */ - - memset(&r, 0, sizeof(struct winreg_OpenKey)); - r.in.handle = &(((struct rpc_key_data *)k->hive->root->backend_data)->pol); - init_winreg_String(&r.in.keyname, k->path); - r.in.unknown = 0x00000000; - r.in.access_mask = 0x02000000; - r.out.handle = &mykeydata->pol; - - dcerpc_winreg_OpenKey((struct dcerpc_pipe *)k->hive->backend_data, mem_ctx, &r); - - return r.out.result; -} -#endif - -static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, const struct registry_key *h, const char *name, struct registry_key **key) -{ - struct rpc_key_data *mykeydata; - struct winreg_OpenKey r; - - *key = talloc(mem_ctx, struct registry_key); - (*key)->name = talloc_strdup(mem_ctx, name); - - (*key)->backend_data = mykeydata = talloc(mem_ctx, struct rpc_key_data); - mykeydata->num_values = -1; - mykeydata->num_subkeys = -1; - - /* Then, open the handle using the hive */ - - memset(&r, 0, sizeof(struct winreg_OpenKey)); - r.in.parent_handle = &(((struct rpc_key_data *)h->backend_data)->pol); - init_winreg_String(&r.in.keyname, name); - r.in.unknown = 0x00000000; - r.in.access_mask = 0x02000000; - r.out.handle = &mykeydata->pol; - - dcerpc_winreg_OpenKey((struct dcerpc_pipe *)(h->hive->backend_data), mem_ctx, &r); - - return r.out.result; -} - -static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *parent, int n, struct registry_value **value) -{ - struct rpc_key_data *mykeydata = parent->backend_data; - WERROR error; - struct winreg_EnumValue r; - uint32_t len1, zero = 0; - enum winreg_Type type; - NTSTATUS status; - struct winreg_StringBuf name; - uint8_t u8; - - if(mykeydata->num_values == -1) { - error = rpc_query_key(parent); - if(!W_ERROR_IS_OK(error)) return error; - } - - len1 = mykeydata->max_valdatalen; - - name.length = 0; - name.size = mykeydata->max_valnamelen * 2; - name.name = ""; - - r.in.handle = &mykeydata->pol; - r.in.enum_index = n; - r.in.name = &name; - r.in.type = &type; - r.in.value = &u8; - r.in.length = &zero; - r.in.size = &len1; - r.out.name = &name; - - status = dcerpc_winreg_EnumValue((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r); - if(NT_STATUS_IS_ERR(status)) { - DEBUG(0, ("Error in EnumValue: %s\n", nt_errstr(status))); - return WERR_GENERAL_FAILURE; - } - - if(NT_STATUS_IS_OK(status) && - W_ERROR_IS_OK(r.out.result) && r.out.length) { - *value = talloc(mem_ctx, struct registry_value); - (*value)->name = talloc_strdup(mem_ctx, r.out.name->name); - (*value)->data_type = type; - (*value)->data = data_blob_talloc(mem_ctx, r.out.value, *r.out.length); - return WERR_OK; - } - - return r.out.result; -} - -static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *parent, int n, struct registry_key **subkey) -{ - struct winreg_EnumKey r; - struct rpc_key_data *mykeydata = parent->backend_data; - NTSTATUS status; - struct winreg_StringBuf namebuf, classbuf; - NTTIME change_time = 0; - - namebuf.length = 0; - namebuf.size = 1024; - namebuf.name = NULL; - classbuf.length = 0; - classbuf.size = 0; - classbuf.name = NULL; - - r.in.handle = &mykeydata->pol; - r.in.enum_index = n; - r.in.name = &namebuf; - r.in.keyclass = &classbuf; - r.in.last_changed_time = &change_time; - r.out.name = &namebuf; - - status = dcerpc_winreg_EnumKey((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r); - if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { - char *name = talloc_strdup(mem_ctx, r.out.name->name); - return rpc_open_key(mem_ctx, parent, name, subkey); - } - - return r.out.result; -} - -static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, const 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; - - init_winreg_String(&r.in.name, name); - init_winreg_String(&r.in.keyclass, NULL); - - r.in.handle = parent->backend_data; - r.out.new_handle = talloc(mem_ctx, struct policy_handle); - r.in.options = 0; - r.in.access_mask = access_mask; - r.in.secdesc = NULL; - - status = dcerpc_winreg_CreateKey((struct dcerpc_pipe *)(parent->hive->backend_data), mem_ctx, &r); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("CreateKey failed - %s\n", nt_errstr(status))); - return ntstatus_to_werror(status); - } - - if (W_ERROR_IS_OK(r.out.result)) { - *key = talloc(mem_ctx, struct registry_key); - (*key)->name = talloc_strdup(*key, name); - (*key)->backend_data = r.out.new_handle; - } - - return r.out.result; -} - -static WERROR rpc_query_key(const struct registry_key *k) -{ - NTSTATUS status; - struct winreg_QueryInfoKey r; - struct rpc_key_data *mykeydata = k->backend_data; - TALLOC_CTX *mem_ctx = talloc_init("query_key"); - - r.in.classname = talloc(mem_ctx, struct winreg_String); - init_winreg_String(r.in.classname, NULL); - r.in.handle = &mykeydata->pol; - - status = dcerpc_winreg_QueryInfoKey((struct dcerpc_pipe *)(k->hive->backend_data), mem_ctx, &r); - talloc_free(mem_ctx); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("QueryInfoKey failed - %s\n", nt_errstr(status))); - return ntstatus_to_werror(status); - } - - if (W_ERROR_IS_OK(r.out.result)) { - mykeydata->num_subkeys = *r.out.num_subkeys; - mykeydata->num_values = *r.out.num_values; - mykeydata->max_valnamelen = *r.out.max_valnamelen; - mykeydata->max_valdatalen = *r.out.max_valbufsize; - } - - return r.out.result; -} - -static WERROR rpc_del_key(const struct registry_key *parent, const char *name) -{ - NTSTATUS status; - struct rpc_key_data *mykeydata = parent->backend_data; - struct winreg_DeleteKey r; - TALLOC_CTX *mem_ctx = talloc_init("del_key"); - - r.in.handle = &mykeydata->pol; - init_winreg_String(&r.in.key, name); - - status = dcerpc_winreg_DeleteKey((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r); - - talloc_free(mem_ctx); - - return r.out.result; -} - -static WERROR rpc_num_values(const struct registry_key *key, uint32_t *count) -{ - struct rpc_key_data *mykeydata = key->backend_data; - WERROR error; - - if(mykeydata->num_values == -1) { - error = rpc_query_key(key); - if(!W_ERROR_IS_OK(error)) return error; - } - - *count = mykeydata->num_values; - return WERR_OK; -} - -static WERROR rpc_num_subkeys(const struct registry_key *key, uint32_t *count) -{ - struct rpc_key_data *mykeydata = key->backend_data; - WERROR error; - - if(mykeydata->num_subkeys == -1) { - error = rpc_query_key(key); - if(!W_ERROR_IS_OK(error)) return error; - } - - *count = mykeydata->num_subkeys; - return WERR_OK; -} - -static struct hive_operations reg_backend_rpc = { - .name = "rpc", - .open_key = rpc_open_key, - .get_subkey_by_index = rpc_get_subkey_by_index, - .get_value_by_index = rpc_get_value_by_index, - .add_key = rpc_add_key, - .del_key = rpc_del_key, - .num_subkeys = rpc_num_subkeys, - .num_values = rpc_num_values, -}; - -_PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, struct auth_session_info *session_info, struct cli_credentials *credentials, - const char *location, struct event_context *ev) -{ - NTSTATUS status; - struct dcerpc_pipe *p; - - *ctx = talloc(NULL, struct registry_context); - - /* Default to local smbd if no connection is specified */ - if (!location) { - location = talloc_strdup(ctx, "ncalrpc:"); - } - - status = dcerpc_pipe_connect(*ctx /* TALLOC_CTX */, - &p, location, - &ndr_table_winreg, - credentials, ev); - (*ctx)->backend_data = p; - - if(NT_STATUS_IS_ERR(status)) { - DEBUG(1, ("Unable to open '%s': %s\n", location, nt_errstr(status))); - talloc_free(*ctx); - *ctx = NULL; - return ntstatus_to_werror(status); - } - - (*ctx)->get_predefined_key = rpc_get_predefined_key; - - return WERR_OK; -} - -NTSTATUS registry_rpc_init(void) -{ - dcerpc_init(); - return registry_register(®_backend_rpc); -} diff --git a/source4/lib/registry/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95.c deleted file mode 100644 index a0b6e0164a..0000000000 --- a/source4/lib/registry/reg_backend_w95.c +++ /dev/null @@ -1,356 +0,0 @@ -/* - Samba Unix/Linux SMB client utility libeditreg.c - Copyright (C) 2004 Jelmer Vernooij, jelmer@samba.org - - Backend for Windows '95 registry files. Explanation of file format - comes from http://www.cs.mun.ca/~michael/regutils/. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include "includes.h" -#include "registry.h" -#include "system/filesys.h" -#include "system/shmem.h" - -/** - * The registry starts with a header that contains pointers to - * the rgdb. - * - * After the main header follows the RGKN header (key index table). - * The RGKN keys are listed after each other. They are put into - * blocks, the first having a length of 0x2000 bytes, the others - * being 0x1000 bytes long. - * - * After the RGKN header follow one or more RGDB blocks. These blocks - * contain keys. A key is followed by its name and its values. - * - * Values are followed by their name and then their data. - * - * Basically the idea is that the RGKN contains the associations between - * the keys and the RGDB contains the actual data. - */ - -typedef uint32_t DWORD; -typedef unsigned short WORD; - -typedef struct creg_block { - DWORD CREG_ID; /* CREG */ - DWORD uk1; - DWORD rgdb_offset; - DWORD chksum; - WORD num_rgdb; - WORD flags; - DWORD uk2; - DWORD uk3; - DWORD uk4; -} CREG_HDR; - -typedef struct rgkn_block { - DWORD RGKN_ID; /* RGKN */ - DWORD size; - DWORD root_offset; - DWORD free_offset; - DWORD flags; - DWORD chksum; - DWORD uk1; - DWORD uk2; -} RGKN_HDR; - -typedef struct reg_id { - WORD id; - WORD rgdb; -} REG_ID; - -typedef struct rgkn_key { - DWORD type; /* 0x00000000 = normal key, 0x80000000 = free block */ - DWORD hash; /* Contains either hash or size of free blocks that follows */ - DWORD next_free; - DWORD parent_offset; - DWORD first_child_offset; - DWORD next_offset; - REG_ID id; -} RGKN_KEY; - - -typedef struct rgdb_block { - DWORD RGDB_ID; /* RGDB */ - DWORD size; - DWORD unused_size; - WORD flags; - WORD section; - DWORD free_offset; /* -1 if there is no free space */ - WORD max_id; - WORD first_free_id; - DWORD uk1; - DWORD chksum; -} RGDB_HDR; - -typedef struct rgdb_key { - DWORD size; - REG_ID id; - DWORD used_size; - WORD name_len; - WORD num_values; - DWORD uk1; -} RGDB_KEY; - -typedef struct rgdb_value { - DWORD type; - DWORD uk1; - WORD name_len; - WORD data_len; -} RGDB_VALUE; - -typedef struct creg_struct_s { - int fd; - BOOL modified; - char *base; - struct stat sbuf; - CREG_HDR *creg_hdr; - RGKN_HDR *rgkn_hdr; - RGDB_KEY ***rgdb_keys; -} CREG; - -#if 0 /* unused */ -#define RGKN_START_SIZE 0x2000 -#define RGKN_INC_SIZE 0x1000 -#endif - -#define LOCN_RGKN(creg, o) ((RGKN_KEY *)((creg)->base + sizeof(CREG_HDR) + o)) -#define LOCN_RGDB_BLOCK(creg, o) (((creg)->base + (creg)->creg_hdr->rgdb_offset + o)) -#define LOCN_RGDB_KEY(creg, rgdb, id) ((RGDB_KEY *)((creg)->rgdb_keys[(rgdb)][(id)])) - -static DWORD str_to_dword(const char *a) { - int i; - unsigned long ret = 0; - for(i = strlen(a)-1; i >= 0; i--) { - ret = ret * 0x100 + a[i]; - } - return ret; -} - -#if 0 /* unused */ - -static DWORD calc_hash(const char *str) { - DWORD ret = 0; - int i; - for(i = 0; str[i] && str[i] != '\\'; i++) { - ret+=toupper(str[i]); - } - return ret; -} - -static void parse_rgkn_block(CREG *creg, off_t start_off, off_t end_off) -{ - off_t i; - for(i = start_off; end_off - i > sizeof(RGKN_KEY); i+= sizeof(RGKN_KEY)) { - RGKN_KEY *key = (RGKN_KEY *)LOCN_RGKN(creg, i); - if(key->type == 0) { - DEBUG(4,("Regular, id: %d, %d, parent: %x, firstchild: %x, next: %x hash: %lX\n", key->id.id, key->id.rgdb, key->parent_offset, key->first_child_offset, key->next_offset, (long)key->hash)); - } else if(key->type == 0x80000000) { - DEBUG(3,("free\n")); - i += key->hash; - } else { - DEBUG(0,("Invalid key type in RGKN: %0X\n", key->type)); - } - } -} - -#endif - -static void parse_rgdb_block(CREG *creg, RGDB_HDR *rgdb_hdr) -{ - DWORD used_size = rgdb_hdr->size - rgdb_hdr->unused_size; - DWORD offset = 0; - - while(offset < used_size) { - RGDB_KEY *key = (RGDB_KEY *)(((char *)rgdb_hdr) + sizeof(RGDB_HDR) + offset); - - if(!(key->id.id == 0xFFFF && key->id.rgdb == 0xFFFF))creg->rgdb_keys[key->id.rgdb][key->id.id] = key; - offset += key->size; - } -} - -static WERROR w95_open_reg (struct registry_hive *h, struct registry_key **root) -{ - CREG *creg; - DWORD creg_id, rgkn_id; - DWORD i; - DWORD offset; - - creg = talloc(h, CREG); - memset(creg, 0, sizeof(CREG)); - h->backend_data = creg; - - if((creg->fd = open(h->location, O_RDONLY, 0000)) < 0) { - return WERR_FOOBAR; - } - - if (fstat(creg->fd, &creg->sbuf) < 0) { - return WERR_FOOBAR; - } - - creg->base = mmap(0, creg->sbuf.st_size, PROT_READ, MAP_SHARED, creg->fd, 0); - - if (creg->base == (void *)-1) { - DEBUG(0,("Could not mmap file: %s, %s\n", h->location, strerror(errno))); - return WERR_FOOBAR; - } - - creg->creg_hdr = (CREG_HDR *)creg->base; - - if ((creg_id = IVAL(&creg->creg_hdr->CREG_ID,0)) != str_to_dword("CREG")) { - DEBUG(0, ("Unrecognized Windows 95 registry header id: 0x%0X, %s\n", - creg_id, h->location)); - return WERR_FOOBAR; - } - - creg->rgkn_hdr = (RGKN_HDR *)LOCN_RGKN(creg, 0); - - if ((rgkn_id = IVAL(&creg->rgkn_hdr->RGKN_ID,0)) != str_to_dword("RGKN")) { - DEBUG(0, ("Unrecognized Windows 95 registry key index id: 0x%0X, %s\n", - rgkn_id, h->location)); - return WERR_FOOBAR; - } - -#if 0 - /* If'ed out because we only need to parse this stuff when allocating new - * entries (which we don't do at the moment */ - /* First parse the 0x2000 long block */ - parse_rgkn_block(creg, sizeof(RGKN_HDR), 0x2000); - - /* Then parse the other 0x1000 length blocks */ - for(offset = 0x2000; offset < creg->rgkn_hdr->size; offset+=0x1000) { - parse_rgkn_block(creg, offset, offset+0x1000); - } -#endif - - creg->rgdb_keys = talloc_array(h, RGDB_KEY **, creg->creg_hdr->num_rgdb); - - offset = 0; - DEBUG(3, ("Reading %d rgdb entries\n", creg->creg_hdr->num_rgdb)); - for(i = 0; i < creg->creg_hdr->num_rgdb; i++) { - RGDB_HDR *rgdb_hdr = (RGDB_HDR *)LOCN_RGDB_BLOCK(creg, offset); - - if(strncmp((char *)&(rgdb_hdr->RGDB_ID), "RGDB", 4)) { - DEBUG(0, ("unrecognized rgdb entry: %4d, %s\n", - rgdb_hdr->RGDB_ID, h->location)); - return WERR_FOOBAR; - } else { - DEBUG(3, ("Valid rgdb entry, first free id: %d, max id: %d\n", rgdb_hdr->first_free_id, rgdb_hdr->max_id)); - } - - - creg->rgdb_keys[i] = talloc_array(h, RGDB_KEY *, rgdb_hdr->max_id+1); - memset(creg->rgdb_keys[i], 0, sizeof(RGDB_KEY *) * (rgdb_hdr->max_id+1)); - - parse_rgdb_block(creg, rgdb_hdr); - - offset+=rgdb_hdr->size; - } - - /* First element in rgkn should be root key */ - *root = talloc(h, struct registry_key); - (*root)->name = NULL; - (*root)->backend_data = LOCN_RGKN(creg, sizeof(RGKN_HDR)); - - return WERR_OK; -} - -static WERROR w95_get_subkey_by_index (TALLOC_CTX *mem_ctx, const struct registry_key *parent, int n, struct registry_key **key) -{ - CREG *creg = parent->hive->backend_data; - RGKN_KEY *rgkn_key = parent->backend_data; - RGKN_KEY *child; - DWORD child_offset; - DWORD cur = 0; - - /* Get id of first child */ - child_offset = rgkn_key->first_child_offset; - - while(child_offset != 0xFFFFFFFF) { - child = LOCN_RGKN(creg, child_offset); - - /* n == cur ? return! */ - if(cur == n) { - RGDB_KEY *rgdb_key; - rgdb_key = LOCN_RGDB_KEY(creg, child->id.rgdb, child->id.id); - if(!rgdb_key) { - DEBUG(0, ("Can't find %d,%d in RGDB table!\n", child->id.rgdb, child->id.id)); - return WERR_FOOBAR; - } - *key = talloc(mem_ctx, struct registry_key); - (*key)->backend_data = child; - (*key)->name = talloc_strndup(mem_ctx, (char *)rgdb_key + sizeof(RGDB_KEY), rgdb_key->name_len); - return WERR_OK; - } - - cur++; - - child_offset = child->next_offset; - } - - return WERR_NO_MORE_ITEMS; -} - -static WERROR w95_num_values(const struct registry_key *k, uint32_t *count) -{ - RGKN_KEY *rgkn_key = k->backend_data; - RGDB_KEY *rgdb_key = LOCN_RGDB_KEY((CREG *)k->hive->backend_data, rgkn_key->id.rgdb, rgkn_key->id.id); - - if(!rgdb_key) return WERR_FOOBAR; - - *count = rgdb_key->num_values; - - return WERR_OK; -} - -static WERROR w95_get_value_by_id(TALLOC_CTX *mem_ctx, const struct registry_key *k, int idx, struct registry_value **value) -{ - RGKN_KEY *rgkn_key = k->backend_data; - DWORD i; - DWORD offset = 0; - RGDB_KEY *rgdb_key = LOCN_RGDB_KEY((CREG *)k->hive->backend_data, rgkn_key->id.rgdb, rgkn_key->id.id); - RGDB_VALUE *curval = NULL; - - if(!rgdb_key) return WERR_FOOBAR; - - if(idx >= rgdb_key->num_values) return WERR_NO_MORE_ITEMS; - - for(i = 0; i < idx; i++) { - curval = (RGDB_VALUE *)(((char *)rgdb_key) + sizeof(RGDB_KEY) + rgdb_key->name_len + offset); - offset+=sizeof(RGDB_VALUE) + curval->name_len + curval->data_len; - } - - *value = talloc(mem_ctx, struct registry_value); - (*value)->name = talloc_strndup(mem_ctx, (char *)curval+sizeof(RGDB_VALUE), curval->name_len); - - (*value)->data = data_blob_talloc(mem_ctx, curval+sizeof(RGDB_VALUE)+curval->name_len, curval->data_len); - (*value)->data_type = curval->type; - - return WERR_OK; -} - -static struct hive_operations reg_backend_w95 = { - .name = "w95", - .open_hive = w95_open_reg, - .get_value_by_index = w95_get_value_by_id, - .num_values = w95_num_values, - .get_subkey_by_index = w95_get_subkey_by_index, -}; - -NTSTATUS registry_w95_init(void) -{ - return registry_register(®_backend_w95); -} diff --git a/source4/lib/registry/reg_backend_wine.c b/source4/lib/registry/reg_backend_wine.c deleted file mode 100644 index 7184a602d1..0000000000 --- a/source4/lib/registry/reg_backend_wine.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Registry interface - Copyright (C) Jelmer Vernooij 2004. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "lib/registry/common/registry.h" -#include "windows/registry.h" - -static WERROR wine_open_reg (struct registry_hive *h, struct registry_key **key) -{ - /* FIXME: Open h->location and mmap it */ -} - - - -static REG_OPS reg_backend_wine = { - .name = "wine", - .open_hive = wine_open_reg, - -}; - -NTSTATUS registry_wine_init(void) -{ - register_backend("registry", ®_backend_wine); - return NT_STATUS_OK; -} - -WERROR reg_open_wine(struct registry_key **ctx) -{ - /* FIXME: Open ~/.wine/system.reg, etc */ - return WERR_NOT_SUPPORTED; -} diff --git a/source4/lib/registry/reg_samba.c b/source4/lib/registry/reg_samba.c deleted file mode 100644 index 560e1ded31..0000000000 --- a/source4/lib/registry/reg_samba.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Copyright (C) Jelmer Vernooij 2004. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "registry.h" - -/** - * @file - * @brief Samba-specific registry functions - */ - -static WERROR reg_samba_get_predef (struct registry_context *ctx, uint32_t hkey, struct registry_key **k) -{ - WERROR error; - const char *conf; - char *backend; - const char *location; - const char *hivename = reg_get_predef_name(hkey); - - *k = NULL; - - conf = lp_parm_string(-1, "registry", hivename); - - if (!conf) { - return WERR_NOT_SUPPORTED; - } - - location = strchr(conf, ':'); - if (location) { - backend = talloc_strndup(ctx, conf, (int)(location - conf)); - location++; - } else { - backend = talloc_strdup(ctx, "ldb"); - location = conf; - } - - /* FIXME: Different hive backend for HKEY_CLASSES_ROOT: merged view of HKEY_LOCAL_MACHINE\Software\Classes - * and HKEY_CURRENT_USER\Software\Classes */ - - /* FIXME: HKEY_CURRENT_CONFIG is an alias for HKEY_LOCAL_MACHINE\System\CurrentControlSet\Hardware Profiles\Current */ - - /* FIXME: HKEY_PERFORMANCE_DATA is dynamically generated */ - - /* FIXME: HKEY_LOCAL_MACHINE\Hardware is autogenerated */ - - /* FIXME: HKEY_LOCAL_MACHINE\Security\SAM is an alias for HKEY_LOCAL_MACHINE\SAM */ - - error = reg_open_hive(ctx, backend, location, ctx->session_info, ctx->credentials, k); - - talloc_free(backend); - - return error; -} - -_PUBLIC_ WERROR reg_open_local (TALLOC_CTX *mem_ctx, - struct registry_context **ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials) -{ - *ctx = talloc(mem_ctx, struct registry_context); - (*ctx)->credentials = talloc_reference(*ctx, credentials); - (*ctx)->session_info = talloc_reference(*ctx, session_info); - (*ctx)->get_predefined_key = reg_samba_get_predef; - - return WERR_OK; -} diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c new file mode 100644 index 0000000000..7fa71033d9 --- /dev/null +++ b/source4/lib/registry/regf.c @@ -0,0 +1,1923 @@ +/* + Samba CIFS implementation + Registry backend for REGF files + Copyright (C) 2005-2007 Jelmer Vernooij, jelmer@samba.org + Copyright (C) 2006 Wilco Baan Hofman, wilco@baanhofman.nl + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "includes.h" +#include "lib/registry/hive.h" +#include "system/filesys.h" +#include "system/time.h" +#include "lib/registry/tdr_regf.h" +#include "librpc/gen_ndr/ndr_security.h" +#include "librpc/gen_ndr/winreg.h" + +static struct hive_operations reg_backend_regf; + +/** + * There are several places on the web where the REGF format is explained; + * + * TODO: Links + */ + +/* TODO: + * - Return error codes that make more sense + * - Locking + * - do more things in-memory + */ + +/* + * Read HBIN blocks into memory + */ + +struct regf_data { + int fd; + struct hbin_block **hbins; + struct regf_hdr *header; +}; + +static WERROR regf_save_hbin(struct regf_data *data); + +struct regf_key_data { + struct hive_key key; + struct regf_data *hive; + uint32_t offset; + struct nk_block *nk; +}; + +static struct hbin_block *hbin_by_offset(const struct regf_data *data, + uint32_t offset, uint32_t *rel_offset) +{ + int i; + + for (i = 0; data->hbins[i]; i++) { + if (offset >= data->hbins[i]->offset_from_first && + offset < data->hbins[i]->offset_from_first+ + data->hbins[i]->offset_to_next) { + if (rel_offset != NULL) + *rel_offset = offset - data->hbins[i]->offset_from_first - 0x20; + return data->hbins[i]; + } + } + + return NULL; +} + +/** + * Validate a regf header + * For now, do nothing, but we should check the checksum + */ +static uint32_t regf_hdr_checksum(const uint8_t *buffer) +{ + uint32_t checksum = 0, x; + int i; + + for (i = 0; i < 0x01FB; i+= 4) { + x = IVAL(buffer, i); + checksum ^= x; + } + + return checksum; +} + +/** + * Obtain the contents of a HBIN block + */ +static DATA_BLOB hbin_get(const struct regf_data *data, uint32_t offset) +{ + DATA_BLOB ret; + struct hbin_block *hbin; + uint32_t rel_offset; + + ret.data = NULL; + ret.length = 0; + + hbin = hbin_by_offset(data, offset, &rel_offset); + + if (hbin == NULL) { + DEBUG(1, ("Can't find HBIN containing 0x%04x\n", offset)); + return ret; + } + + ret.length = IVAL(hbin->data, rel_offset); + if (!(ret.length & 0x80000000)) { + DEBUG(0, ("Trying to use dirty block at 0x%04x\n", offset)); + return ret; + } + + /* remove high bit */ + ret.length = (ret.length ^ 0xffffffff) + 1; + + ret.length -= 4; /* 4 bytes for the length... */ + ret.data = hbin->data + + (offset - hbin->offset_from_first - 0x20) + 4; + + return ret; +} + +static bool hbin_get_tdr (struct regf_data *regf, uint32_t offset, + TALLOC_CTX *ctx, tdr_pull_fn_t pull_fn, void *p) +{ + struct tdr_pull pull; + + ZERO_STRUCT(pull); + + pull.data = hbin_get(regf, offset); + if (!pull.data.data) { + DEBUG(1, ("Unable to get data at 0x%04x\n", offset)); + return false; + } + + if (NT_STATUS_IS_ERR(pull_fn(&pull, ctx, p))) { + DEBUG(1, ("Error parsing record at 0x%04x using tdr\n", offset)); + return false; + } + + return true; +} + +/* Allocate some new data */ +static DATA_BLOB hbin_alloc(struct regf_data *data, uint32_t size, + uint32_t *offset) +{ + DATA_BLOB ret; + uint32_t rel_offset = -1; /* Relative offset ! */ + struct hbin_block *hbin = NULL; + int i; + + *offset = 0; + + if (size == 0) + return data_blob(NULL, 0); + + size += 4; /* Need to include int32 for the length */ + + /* Allocate as a multiple of 8 */ + size = (size + 7) & ~7; + + ret.data = NULL; + ret.length = 0; + + for (i = 0; (hbin = data->hbins[i]); i++) { + int j; + int32_t my_size; + for (j = 0; j < hbin->offset_to_next-0x20; j+= my_size) { + my_size = IVALS(hbin->data, j); + + if (my_size == 0x0) { + DEBUG(0, ("Invalid zero-length block! File is corrupt.\n")); + return ret; + } + + if (my_size % 8 != 0) { + DEBUG(0, ("Encountered non-aligned block!\n")); + } + + if (my_size < 0) { /* Used... */ + my_size = -my_size; + } else if (my_size == size) { /* exact match */ + rel_offset = j; + DEBUG(4, ("Found free block of exact size %d in middle of HBIN\n", size)); + break; + } else if (my_size > size) { /* data will remain */ + rel_offset = j; + /* Split this block and mark the next block as free */ + SIVAL(hbin->data, rel_offset+size, my_size-size); + DEBUG(4, ("Found free block of size %d (needing %d) in middle of HBIN\n", my_size, size)); + break; + } + } + + if (rel_offset != -1) + break; + } + + /* No space available in previous hbins, + * allocate new one */ + if (data->hbins[i] == NULL) { + DEBUG(4, ("No space available in other HBINs for block of size %d, allocating new HBIN\n", size)); + data->hbins = talloc_realloc(data, data->hbins, struct hbin_block *, i+2); + hbin = talloc(data->hbins, struct hbin_block); + SMB_ASSERT(hbin != NULL); + + data->hbins[i] = hbin; + data->hbins[i+1] = NULL; + + hbin->HBIN_ID = talloc_strdup(hbin, "hbin"); + hbin->offset_from_first = (i == 0?0:data->hbins[i-1]->offset_from_first+data->hbins[i-1]->offset_to_next); + hbin->offset_to_next = 0x1000; + hbin->unknown[0] = 0; + hbin->unknown[0] = 0; + unix_to_nt_time(&hbin->last_change, time(NULL)); + hbin->block_size = hbin->offset_to_next; + hbin->data = talloc_zero_array(hbin, uint8_t, hbin->block_size - 0x20); + + rel_offset = 0x0; + SIVAL(hbin->data, size, hbin->block_size - size - 0x20); + } + + /* Set size and mark as used */ + SIVAL(hbin->data, rel_offset, -size); + + ret.data = hbin->data + rel_offset + 0x4; /* Skip past length */ + ret.length = size - 0x4; + if (offset) { + uint32_t new_rel_offset; + *offset = hbin->offset_from_first + rel_offset + 0x20; + SMB_ASSERT(hbin_by_offset(data, *offset, &new_rel_offset) == hbin); + SMB_ASSERT(new_rel_offset == rel_offset); + } + + return ret; +} + +/* Store a data blob. Return the offset at which it was stored */ +static uint32_t hbin_store (struct regf_data *data, DATA_BLOB blob) +{ + uint32_t ret; + DATA_BLOB dest = hbin_alloc(data, blob.length, &ret); + + memcpy(dest.data, blob.data, blob.length); + + return ret; +} + +static uint32_t hbin_store_tdr (struct regf_data *data, tdr_push_fn_t push_fn, void *p) +{ + struct tdr_push *push = talloc_zero(data, struct tdr_push); + uint32_t ret; + + if (NT_STATUS_IS_ERR(push_fn(push, p))) { + DEBUG(0, ("Error during push\n")); + return -1; + } + + ret = hbin_store(data, push->data); + + talloc_free(push); + + return ret; +} + + +/* Free existing data */ +static void hbin_free (struct regf_data *data, uint32_t offset) +{ + int32_t size; + uint32_t rel_offset; + int32_t next_size; + struct hbin_block *hbin; + + SMB_ASSERT (offset > 0); + + hbin = hbin_by_offset(data, offset, &rel_offset); + + if (hbin == NULL) + return; + + /* Get original size */ + size = IVALS(hbin->data, rel_offset); + + if (size > 0) { + DEBUG(1, ("Trying to free already freed block at 0x%04x\n", offset)); + return; + } + /* Mark as unused */ + size = -size; + + /* If the next block is free, merge into big free block */ + if (rel_offset + size < hbin->offset_to_next) { + next_size = IVALS(hbin->data, rel_offset+size); + if (next_size > 0) { + size += next_size; + } + } + + /* Write block size */ + SIVALS(hbin->data, rel_offset, size); +} + +/** + * Store a data blob data was already stored, but has changed in size + * Will try to save it at the current location if possible, otherwise + * does a free + store */ +static uint32_t hbin_store_resize(struct regf_data *data, + uint32_t orig_offset, DATA_BLOB blob) +{ + uint32_t rel_offset; + struct hbin_block *hbin = hbin_by_offset(data, orig_offset, &rel_offset); + int32_t my_size; + int32_t orig_size; + int32_t needed_size; + int32_t possible_size; + int i; + + SMB_ASSERT(orig_offset > 0); + + if (!hbin) + return hbin_store(data, blob); + + /* Get original size */ + orig_size = -IVALS(hbin->data, rel_offset); + + needed_size = blob.length + 4; /* Add int32 containing length */ + needed_size = (needed_size + 7) & ~7; /* Align */ + + /* Fits into current allocated block */ + if (orig_size >= needed_size) { + memcpy(hbin->data + rel_offset + 0x4, blob.data, blob.length); + /* If the difference in size is greater than 0x4, split the block + * and free/merge it */ + if (orig_size - needed_size > 0x4) { + SIVALS(hbin->data, rel_offset, -needed_size); + SIVALS(hbin->data, rel_offset + needed_size, needed_size-orig_size); + hbin_free(data, orig_offset + needed_size); + } + return orig_offset; + } + + possible_size = orig_size; + + /* Check if it can be combined with the next few free records */ + for (i = rel_offset; i < hbin->offset_to_next - 0x20; i += my_size) { + if (IVALS(hbin->data, i) < 0) /* Used */ + break; + + my_size = IVALS(hbin->data, i); + + if (my_size == 0x0) { + DEBUG(0, ("Invalid zero-length block! File is corrupt.\n")); + break; + } else { + possible_size += my_size; + } + + if (possible_size >= blob.length) { + SIVAL(hbin->data, rel_offset, -possible_size); + memcpy(hbin->data + rel_offset + 0x4, blob.data, blob.length); + return orig_offset; + } + } + + hbin_free(data, orig_offset); + return hbin_store(data, blob); +} + +static uint32_t hbin_store_tdr_resize (struct regf_data *regf, tdr_push_fn_t push_fn, + uint32_t orig_offset, void *p) +{ + struct tdr_push *push = talloc_zero(regf, struct tdr_push); + uint32_t ret; + + if (NT_STATUS_IS_ERR(push_fn(push, p))) { + DEBUG(0, ("Error during push\n")); + return -1; + } + + ret = hbin_store_resize(regf, orig_offset, push->data); + + talloc_free(push); + + return ret; +} + +static uint32_t regf_create_lh_hash(const char *name) +{ + char *hash_name; + uint32_t ret = 0; + uint16_t i; + + hash_name = strupper_talloc(NULL, name); + for (i = 0; *(hash_name + i) != 0; i++) { + ret *= 37; + ret += *(hash_name + i); + } + talloc_free(hash_name); + return ret; +} + +static WERROR regf_get_info (TALLOC_CTX *mem_ctx, + const struct hive_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_mod_time) +{ + const struct regf_key_data *private_data = + (const struct regf_key_data *)key; + + if (num_subkeys != NULL) + *num_subkeys = private_data->nk->num_subkeys; + + if (num_values != NULL) + *num_values = private_data->nk->num_values; + + if (classname != NULL) { + if (private_data->nk->clsname_offset != -1) { + DATA_BLOB data = hbin_get(private_data->hive, + private_data->nk->clsname_offset); + *classname = talloc_strndup(mem_ctx, + (char*)data.data, private_data->nk->clsname_length); + } else + *classname = NULL; + } + + /* TODO: Last mod time */ + + return WERR_OK; +} + +static struct regf_key_data *regf_get_key(TALLOC_CTX *ctx, + struct regf_data *regf, + uint32_t offset) +{ + struct nk_block *nk; + struct regf_key_data *ret; + + ret = talloc_zero(ctx, struct regf_key_data); + ret->key.ops = ®_backend_regf; + ret->hive = talloc_reference(ret, regf); + ret->offset = offset; + nk = talloc(ret, struct nk_block); + if (nk == NULL) + return NULL; + + ret->nk = nk; + + if (!hbin_get_tdr(regf, offset, nk, (tdr_pull_fn_t)tdr_pull_nk_block, nk)) { + DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset)); + return NULL; + } + + if (strcmp(nk->header, "nk") != 0) { + DEBUG(0, ("Expected nk record, got %s\n", nk->header)); + talloc_free(ret); + return NULL; + } + + return ret; +} + + +static WERROR regf_get_value(TALLOC_CTX *ctx, const struct hive_key *key, + int idx, const char **name, + uint32_t *data_type, DATA_BLOB *data) +{ + const struct regf_key_data *private_data = + (const struct regf_key_data *)key; + struct vk_block *vk; + struct regf_data *regf = private_data->hive; + uint32_t vk_offset; + DATA_BLOB tmp; + + if (idx >= private_data->nk->num_values) + return WERR_NO_MORE_ITEMS; + + tmp = hbin_get(regf, private_data->nk->values_offset); + if (!tmp.data) { + DEBUG(0, ("Unable to find value list\n")); + return WERR_GENERAL_FAILURE; + } + + if (tmp.length < private_data->nk->num_values * 4) { + DEBUG(1, ("Value counts mismatch\n")); + } + + vk_offset = IVAL(tmp.data, idx * 4); + + vk = talloc(NULL, struct vk_block); + W_ERROR_HAVE_NO_MEMORY(vk); + + if (!hbin_get_tdr(regf, vk_offset, vk, (tdr_pull_fn_t)tdr_pull_vk_block, vk)) { + DEBUG(0, ("Unable to get VK block at %d\n", vk_offset)); + talloc_free(vk); + return WERR_GENERAL_FAILURE; + } + + /* FIXME: name character set ?*/ + if (name != NULL) + *name = talloc_strndup(ctx, vk->data_name, vk->name_length); + + if (data_type != NULL) + *data_type = vk->data_type; + + if (vk->data_length & 0x80000000) { + vk->data_length &=~0x80000000; + data->data = (uint8_t *)&vk->data_offset; + data->length = vk->data_length; + } else { + *data = hbin_get(regf, vk->data_offset); + } + + if (data->length < vk->data_length) { + DEBUG(1, ("Read data less than indicated data length!\n")); + } + + talloc_free(vk); + + return WERR_OK; +} + +static WERROR regf_get_value_by_name (TALLOC_CTX *mem_ctx, + struct hive_key *key, const char *name, + uint32_t *type, DATA_BLOB *data) +{ + int i; + const char *vname; + WERROR error; + + /* FIXME: Do binary search? Is this list sorted at all? */ + + for (i = 0; W_ERROR_IS_OK(error = regf_get_value(mem_ctx, key, i, + &vname, type, data)); i++) { + if (!strcmp(vname, name)) + return WERR_OK; + } + + if (W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) + return WERR_NOT_FOUND; + + return error; +} + + +static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, + const struct hive_key *key, + uint32_t idx, const char **name, + const char **classname, + NTTIME *last_mod_time) +{ + DATA_BLOB data; + struct regf_key_data *ret; + const struct regf_key_data *private_data = (const struct regf_key_data *)key; + struct nk_block *nk = private_data->nk; + uint32_t key_off=0; + + if (idx >= nk->num_subkeys) + return WERR_NO_MORE_ITEMS; + + data = hbin_get(private_data->hive, nk->subkeys_offset); + if (!data.data) { + DEBUG(0, ("Unable to find subkey list\n")); + return WERR_GENERAL_FAILURE; + } + + if (!strncmp((char *)data.data, "li", 2)) { + struct li_block li; + struct tdr_pull pull; + + DEBUG(10, ("Subkeys in LI list\n")); + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { + DEBUG(0, ("Error parsing LI list\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(li.header, "li", 2)); + + if (li.key_count != nk->num_subkeys) { + DEBUG(0, ("Subkey counts don't match\n")); + return WERR_GENERAL_FAILURE; + } + key_off = li.nk_offset[idx]; + + } else if (!strncmp((char *)data.data, "lf", 2)) { + struct lf_block lf; + struct tdr_pull pull; + + DEBUG(10, ("Subkeys in LF list\n")); + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, nk, &lf))) { + DEBUG(0, ("Error parsing LF list\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(lf.header, "lf", 2)); + + if (lf.key_count != nk->num_subkeys) { + DEBUG(0, ("Subkey counts don't match\n")); + return WERR_GENERAL_FAILURE; + } + + key_off = lf.hr[idx].nk_offset; + } else if (!strncmp((char *)data.data, "lh", 2)) { + struct lh_block lh; + struct tdr_pull pull; + + DEBUG(10, ("Subkeys in LH list\n")); + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { + DEBUG(0, ("Error parsing LH list\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(lh.header, "lh", 2)); + + if (lh.key_count != nk->num_subkeys) { + DEBUG(0, ("Subkey counts don't match\n")); + return WERR_GENERAL_FAILURE; + } + key_off = lh.hr[idx].nk_offset; + } else if (!strncmp((char *)data.data, "ri", 2)) { + struct ri_block ri; + struct tdr_pull pull; + uint16_t i; + uint16_t sublist_count = 0; + + DEBUG(10, ("Subkeys in RI list\n")); + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_ri_block(&pull, nk, &ri))) { + DEBUG(0, ("Error parsing RI list\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(ri.header, "ri", 2)); + + for (i = 0; i < ri.key_count; i++) { + DATA_BLOB list_data; + + /* Get sublist data blob */ + list_data = hbin_get(private_data->hive, ri.offset[i]); + if (!list_data.data) { + DEBUG(0, ("Error getting RI list.")); + return WERR_GENERAL_FAILURE; + } + + ZERO_STRUCT(pull); + pull.data = list_data; + + if (!strncmp((char *)list_data.data, "li", 2)) { + struct li_block li; + + DEBUG(10, ("Subkeys in RI->LI list\n")); + + if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { + DEBUG(0, ("Error parsing LI list from RI\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(li.header, "li", 2)); + + /* Advance to next sublist if necessary */ + if (idx >= sublist_count + li.key_count) { + sublist_count += li.key_count; + continue; + } + key_off = li.nk_offset[idx - sublist_count]; + sublist_count += li.key_count; + break; + } else if (!strncmp((char *)list_data.data, "lh", 2)) { + struct lh_block lh; + + DEBUG(10, ("Subkeys in RI->LH list\n")); + + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { + DEBUG(0, ("Error parsing LH list from RI\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(lh.header, "lh", 2)); + + /* Advance to next sublist if necessary */ + if (idx >= sublist_count + lh.key_count) { + sublist_count += lh.key_count; + continue; + } + key_off = lh.hr[idx - sublist_count].nk_offset; + sublist_count += lh.key_count; + break; + } else { + DEBUG(0,("Unknown sublist in ri block\n")); + + return WERR_GENERAL_FAILURE; + } + + } + + if (idx > sublist_count) { + return WERR_NO_MORE_ITEMS; + } + + } else { + DEBUG(0, ("Unknown type for subkey list (0x%04x): %c%c\n", + nk->subkeys_offset, data.data[0], data.data[1])); + return WERR_GENERAL_FAILURE; + } + + ret = regf_get_key (ctx, private_data->hive, key_off); + + if (classname != NULL) { + if (ret->nk->clsname_offset != -1) { + DATA_BLOB db = hbin_get(ret->hive, + ret->nk->clsname_offset); + *classname = talloc_strndup(ctx, + (char*)db.data, ret->nk->clsname_length); + } else + *classname = NULL; + } + + if (last_mod_time != NULL) + *last_mod_time = ret->nk->last_change; + + if (name != NULL) + *name = talloc_steal(ctx, ret->nk->key_name); + + talloc_free(ret); + + return WERR_OK; +} + +static WERROR regf_match_subkey_by_name(TALLOC_CTX *ctx, + const struct hive_key *key, uint32_t offset, + const char *name, uint32_t *ret) +{ + DATA_BLOB subkey_data; + struct nk_block subkey; + struct tdr_pull pull; + const struct regf_key_data *private_data = + (const struct regf_key_data *)key; + + subkey_data = hbin_get(private_data->hive, offset); + if (!subkey_data.data) { + DEBUG(0, ("Unable to retrieve subkey HBIN\n")); + return WERR_GENERAL_FAILURE; + } + + ZERO_STRUCT(pull); + pull.data = subkey_data; + + if (NT_STATUS_IS_ERR(tdr_pull_nk_block(&pull, ctx, &subkey))) { + DEBUG(0, ("Error parsing NK structure.\n")); + return WERR_GENERAL_FAILURE; + } + + if (strncmp(subkey.header, "nk", 2)) { + DEBUG(0, ("Not an NK structure.\n")); + return WERR_GENERAL_FAILURE; + } + + if (!strcasecmp(subkey.key_name, name)) { + *ret = offset; + } else { + *ret = 0; + } + return WERR_OK; +} + +static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, + const struct hive_key *key, + const char *name, + struct hive_key **ret) +{ + DATA_BLOB data; + const struct regf_key_data *private_data = + (const struct regf_key_data *)key; + struct nk_block *nk = private_data->nk; + uint32_t key_off = 0; + + data = hbin_get(private_data->hive, nk->subkeys_offset); + if (!data.data) { + DEBUG(0, ("Unable to find subkey list\n")); + return WERR_GENERAL_FAILURE; + } + + if (!strncmp((char *)data.data, "li", 2)) { + struct li_block li; + struct tdr_pull pull; + uint16_t i; + + DEBUG(10, ("Subkeys in LI list\n")); + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { + DEBUG(0, ("Error parsing LI list\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(li.header, "li", 2)); + + if (li.key_count != nk->num_subkeys) { + DEBUG(0, ("Subkey counts don't match\n")); + return WERR_GENERAL_FAILURE; + } + + for (i = 0; i < li.key_count; i++) { + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, li.nk_offset[i], name, &key_off)); + if (key_off != 0) + break; + } + if (key_off == 0) + return WERR_NOT_FOUND; + } else if (!strncmp((char *)data.data, "lf", 2)) { + struct lf_block lf; + struct tdr_pull pull; + uint16_t i; + + DEBUG(10, ("Subkeys in LF list\n")); + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, nk, &lf))) { + DEBUG(0, ("Error parsing LF list\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(lf.header, "lf", 2)); + + if (lf.key_count != nk->num_subkeys) { + DEBUG(0, ("Subkey counts don't match\n")); + return WERR_GENERAL_FAILURE; + } + + for (i = 0; i < lf.key_count; i++) { + if (strncmp(lf.hr[i].hash, name, 4)) { + continue; + } + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, lf.hr[i].nk_offset, name, &key_off)); + if (key_off != 0) + break; + } + if (key_off == 0) + return WERR_NOT_FOUND; + } else if (!strncmp((char *)data.data, "lh", 2)) { + struct lh_block lh; + struct tdr_pull pull; + uint16_t i; + uint32_t hash; + + DEBUG(10, ("Subkeys in LH list\n")); + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { + DEBUG(0, ("Error parsing LH list\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(lh.header, "lh", 2)); + + if (lh.key_count != nk->num_subkeys) { + DEBUG(0, ("Subkey counts don't match\n")); + return WERR_GENERAL_FAILURE; + } + + hash = regf_create_lh_hash(name); + for (i = 0; i < lh.key_count; i++) { + if (lh.hr[i].base37 != hash) { + continue; + } + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, lh.hr[i].nk_offset, name, &key_off)); + if (key_off != 0) + break; + } + if (key_off == 0) + return WERR_NOT_FOUND; + } else if (!strncmp((char *)data.data, "ri", 2)) { + struct ri_block ri; + struct tdr_pull pull; + uint16_t i, j; + + DEBUG(10, ("Subkeys in RI list\n")); + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_ri_block(&pull, nk, &ri))) { + DEBUG(0, ("Error parsing RI list\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(ri.header, "ri", 2)); + + for (i = 0; i < ri.key_count; i++) { + DATA_BLOB list_data; + + /* Get sublist data blob */ + list_data = hbin_get(private_data->hive, ri.offset[i]); + if (list_data.data == NULL) { + DEBUG(0, ("Error getting RI list.")); + return WERR_GENERAL_FAILURE; + } + + ZERO_STRUCT(pull); + pull.data = list_data; + + if (!strncmp((char *)list_data.data, "li", 2)) { + struct li_block li; + + if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { + DEBUG(0, ("Error parsing LI list from RI\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(li.header, "li", 2)); + + for (j = 0; j < li.key_count; j++) { + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, + li.nk_offset[j], name, &key_off)); + if (key_off) + break; + } + } else if (!strncmp((char *)list_data.data, "lh", 2)) { + struct lh_block lh; + uint32_t hash; + + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { + DEBUG(0, ("Error parsing LH list from RI\n")); + return WERR_GENERAL_FAILURE; + } + SMB_ASSERT(!strncmp(lh.header, "lh", 2)); + + hash = regf_create_lh_hash(name); + for (j = 0; j < lh.key_count; j++) { + if (lh.hr[j].base37 != hash) { + continue; + } + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, + lh.hr[j].nk_offset, name, &key_off)); + if (key_off) + break; + } + } + if (key_off) + break; + } + if (!key_off) + return WERR_NOT_FOUND; + } else { + DEBUG(0, ("Unknown subkey list type.\n")); + return WERR_GENERAL_FAILURE; + } + + *ret = (struct hive_key *)regf_get_key (ctx, private_data->hive, key_off); + return WERR_OK; +} + +static WERROR regf_set_sec_desc (struct hive_key *key, + const struct security_descriptor *sec_desc) +{ + const struct regf_key_data *private_data = + (const struct regf_key_data *)key; + struct sk_block cur_sk, sk, new_sk; + struct regf_data *regf = private_data->hive; + struct nk_block root; + DATA_BLOB data; + uint32_t sk_offset, cur_sk_offset; + bool update_cur_sk = false; + + /* Get the root nk */ + hbin_get_tdr(regf, regf->header->data_offset, regf, + (tdr_pull_fn_t) tdr_pull_nk_block, &root); + + /* Push the security descriptor to a blob */ + if (NT_STATUS_IS_ERR(ndr_push_struct_blob(&data, regf, sec_desc, + (ndr_push_flags_fn_t)ndr_push_security_descriptor))) { + DEBUG(0, ("Unable to push security descriptor\n")); + return WERR_GENERAL_FAILURE; + } + + /* Get the current security descriptor for the key */ + if (!hbin_get_tdr(regf, private_data->nk->sk_offset, regf, + (tdr_pull_fn_t) tdr_pull_sk_block, &cur_sk)) { + DEBUG(0, ("Unable to find security descriptor for current key\n")); + return WERR_BADFILE; + } + /* If there's no change, change nothing. */ + if (memcmp(data.data, cur_sk.sec_desc, MIN(data.length, cur_sk.rec_size)) == 0) { + return WERR_OK; + } + + /* Delete the current sk if only this key is using it */ + if (cur_sk.ref_cnt == 1) { + /* Get the previous security descriptor for the key */ + if (!hbin_get_tdr(regf, cur_sk.prev_offset, regf, + (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + DEBUG(0, ("Unable to find prev security descriptor for current key\n")); + return WERR_BADFILE; + } + /* Change and store the previous security descriptor */ + sk.next_offset = cur_sk.next_offset; + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, cur_sk.prev_offset, &sk); + + /* Get the next security descriptor for the key */ + if (!hbin_get_tdr(regf, cur_sk.next_offset, regf, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + DEBUG(0, ("Unable to find next security descriptor for current key\n")); + return WERR_BADFILE; + } + /* Change and store the next security descriptor */ + sk.prev_offset = cur_sk.prev_offset; + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, cur_sk.next_offset, &sk); + + hbin_free(regf, private_data->nk->sk_offset); + } else { + /* This key will no longer be referring to this sk */ + cur_sk.ref_cnt--; + update_cur_sk = true; + } + + sk_offset = root.sk_offset; + + do { + cur_sk_offset = sk_offset; + if (!hbin_get_tdr(regf, sk_offset, regf, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + DEBUG(0, ("Unable to find security descriptor\n")); + return WERR_BADFILE; + } + if (memcmp(data.data, sk.sec_desc, MIN(data.length, sk.rec_size)) == 0) { + private_data->nk->sk_offset = sk_offset; + sk.ref_cnt++; + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, sk_offset, &sk); + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, private_data->offset, private_data->nk); + return WERR_OK; + } + sk_offset = sk.next_offset; + } while (sk_offset != root.sk_offset); + + ZERO_STRUCT(new_sk); + new_sk.header = "sk"; + new_sk.prev_offset = cur_sk_offset; + new_sk.next_offset = root.sk_offset; + new_sk.ref_cnt = 1; + new_sk.rec_size = data.length; + new_sk.sec_desc = data.data; + + sk_offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_sk_block, &new_sk); + if (sk_offset == -1) { + DEBUG(0, ("Error storing sk block\n")); + return WERR_GENERAL_FAILURE; + } + private_data->nk->sk_offset = sk_offset; + + if (update_cur_sk) { + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, private_data->nk->sk_offset, &cur_sk); + } + + /* Get the previous security descriptor for the key */ + if (!hbin_get_tdr(regf, new_sk.prev_offset, regf, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + DEBUG(0, ("Unable to find security descriptor for previous key\n")); + return WERR_BADFILE; + } + /* Change and store the previous security descriptor */ + sk.next_offset = sk_offset; + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, cur_sk.prev_offset, &sk); + + /* Get the next security descriptor for the key (always root, as we append) */ + if (!hbin_get_tdr(regf, new_sk.next_offset, regf, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + DEBUG(0, ("Unable to find security descriptor for current key\n")); + return WERR_BADFILE; + } + /* Change and store the next security descriptor (always root, as we append) */ + sk.prev_offset = sk_offset; + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, root.sk_offset, &sk); + + + /* Store the nk. */ + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, private_data->offset, private_data->nk); + return WERR_OK; +} + +static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, const struct hive_key *key, + struct security_descriptor **sd) +{ + const struct regf_key_data *private_data = + (const struct regf_key_data *)key; + struct sk_block sk; + struct regf_data *regf = private_data->hive; + DATA_BLOB data; + + if (!hbin_get_tdr(regf, private_data->nk->sk_offset, ctx, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + DEBUG(0, ("Unable to find security descriptor\n")); + return WERR_GENERAL_FAILURE; + } + + if (strcmp(sk.header, "sk") != 0) { + DEBUG(0, ("Expected 'sk', got '%s'\n", sk.header)); + return WERR_GENERAL_FAILURE; + } + + *sd = talloc(ctx, struct security_descriptor); + W_ERROR_HAVE_NO_MEMORY(*sd); + + data.data = sk.sec_desc; + data.length = sk.rec_size; + if (NT_STATUS_IS_ERR(ndr_pull_struct_blob(&data, ctx, *sd, (ndr_pull_flags_fn_t)ndr_pull_security_descriptor))) { + DEBUG(0, ("Error parsing security descriptor\n")); + return WERR_GENERAL_FAILURE; + } + + return WERR_OK; +} + +static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, + const char *name, uint32_t key_offset, uint32_t *ret) +{ + DATA_BLOB data; + + /* Create a new key if necessary */ + if (list_offset == -1) { + if (regf->header->version.major != 1) { + DEBUG(0, ("Can't store keys in unknown registry format\n")); + return WERR_NOT_SUPPORTED; + } + if (regf->header->version.minor < 3) { + /* Store LI */ + struct li_block li; + ZERO_STRUCT(li); + li.header = "li"; + li.key_count = 1; + + li.nk_offset = talloc_array(regf, uint32_t, 1); + W_ERROR_HAVE_NO_MEMORY(li.nk_offset); + li.nk_offset[0] = key_offset; + + *ret = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_li_block, &li); + + talloc_free(li.nk_offset); + } else if (regf->header->version.minor == 3 || regf->header->version.minor == 4) { + /* Store LF */ + struct lf_block lf; + ZERO_STRUCT(lf); + lf.header = "lf"; + lf.key_count = 1; + + lf.hr = talloc_array(regf, struct hash_record, 1); + W_ERROR_HAVE_NO_MEMORY(lf.hr); + lf.hr[0].nk_offset = key_offset; + lf.hr[0].hash = talloc_strndup(lf.hr, name, 4); + W_ERROR_HAVE_NO_MEMORY(lf.hr[0].hash); + + *ret = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_lf_block, &lf); + + talloc_free(lf.hr); + } else if (regf->header->version.minor == 5) { + /* Store LH */ + struct lh_block lh; + ZERO_STRUCT(lh); + lh.header = "lh"; + lh.key_count = 1; + + lh.hr = talloc_array(regf, struct lh_hash, 1); + W_ERROR_HAVE_NO_MEMORY(lh.hr); + lh.hr[0].nk_offset = key_offset; + lh.hr[0].base37 = regf_create_lh_hash(name); + + *ret = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_lh_block, &lh); + + talloc_free(lh.hr); + } + return WERR_OK; + } + + data = hbin_get(regf, list_offset); + if (!data.data) { + DEBUG(0, ("Unable to find subkey list\n")); + return WERR_BADFILE; + } + + if (!strncmp((char *)data.data, "li", 2)) { + struct tdr_pull pull; + struct li_block li; + + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, regf, &li))) { + DEBUG(0, ("Error parsing LI list\n")); + return WERR_BADFILE; + } + + if (strncmp(li.header, "li", 2) != 0) { + abort(); + DEBUG(0, ("LI header corrupt\n")); + return WERR_BADFILE; + } + + li.nk_offset = talloc_realloc(regf, li.nk_offset, uint32_t, li.key_count+1); + W_ERROR_HAVE_NO_MEMORY(li.nk_offset); + li.nk_offset[li.key_count] = key_offset; + li.key_count++; + *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t)tdr_push_li_block, list_offset, &li); + + talloc_free(li.nk_offset); + } else if (!strncmp((char *)data.data, "lf", 2)) { + struct tdr_pull pull; + struct lf_block lf; + + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, regf, &lf))) { + DEBUG(0, ("Error parsing LF list\n")); + return WERR_BADFILE; + } + SMB_ASSERT(!strncmp(lf.header, "lf", 2)); + + lf.hr = talloc_realloc(regf, lf.hr, struct hash_record, lf.key_count+1); + W_ERROR_HAVE_NO_MEMORY(lf.hr); + lf.hr[lf.key_count].nk_offset = key_offset; + lf.hr[lf.key_count].hash = talloc_strndup(lf.hr, name, 4); + W_ERROR_HAVE_NO_MEMORY(lf.hr[lf.key_count].hash); + lf.key_count++; + *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t)tdr_push_lf_block, list_offset, &lf); + + talloc_free(lf.hr); + } else if (!strncmp((char *)data.data, "lh", 2)) { + struct tdr_pull pull; + struct lh_block lh; + + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, regf, &lh))) { + DEBUG(0, ("Error parsing LH list\n")); + return WERR_BADFILE; + } + SMB_ASSERT(!strncmp(lh.header, "lh", 2)); + + lh.hr = talloc_realloc(regf, lh.hr, struct lh_hash, lh.key_count+1); + W_ERROR_HAVE_NO_MEMORY(lh.hr); + lh.hr[lh.key_count].nk_offset = key_offset; + lh.hr[lh.key_count].base37 = regf_create_lh_hash(name); + lh.key_count++; + *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t)tdr_push_lh_block, list_offset, &lh); + + talloc_free(lh.hr); + } else if (!strncmp((char *)data.data, "ri", 2)) { + /* FIXME */ + DEBUG(0, ("Adding to 'ri' subkey list is not supported yet.\n")); + return WERR_NOT_SUPPORTED; + } else { + DEBUG(0, ("Cannot add to unknown subkey list\n")); + return WERR_BADFILE; + } + + return WERR_OK; +} + +static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, + uint32_t key_offset, uint32_t *ret) +{ + DATA_BLOB data; + + data = hbin_get(regf, list_offset); + if (!data.data) { + DEBUG(0, ("Unable to find subkey list\n")); + return WERR_BADFILE; + } + + if (strncmp((char *)data.data, "li", 2) == 0) { + struct li_block li; + struct tdr_pull pull; + uint16_t i; + bool found_offset = false; + + DEBUG(10, ("Subkeys in LI list\n")); + + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, regf, &li))) { + DEBUG(0, ("Error parsing LI list\n")); + return WERR_BADFILE; + } + + SMB_ASSERT(!strncmp(li.header, "li", 2)); + + for (i = 0; i < li.key_count; i++) { + if (found_offset) { + li.nk_offset[i-1] = li.nk_offset[i]; + } + if (li.nk_offset[i] == key_offset) { + found_offset = true; + continue; + } + } + if (!found_offset) { + DEBUG(0, ("Subkey not found\n")); + return WERR_NOT_FOUND; + } + li.key_count--; + + /* If the there are no entries left, free the subkey list */ + if (li.key_count == 0) { + hbin_free(regf, list_offset); + *ret = -1; + } + + /* Store li block */ + *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_li_block, list_offset, &li); + } else if (strncmp((char *)data.data, "lf", 2) == 0) { + struct lf_block lf; + struct tdr_pull pull; + uint16_t i; + bool found_offset = false; + + DEBUG(10, ("Subkeys in LF list\n")); + + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, regf, &lf))) { + DEBUG(0, ("Error parsing LF list\n")); + return WERR_BADFILE; + } + + SMB_ASSERT(!strncmp(lf.header, "lf", 2)); + + for (i = 0; i < lf.key_count; i++) { + if (found_offset) { + lf.hr[i-1] = lf.hr[i]; + continue; + } + if (lf.hr[i].nk_offset == key_offset) { + found_offset = 1; + continue; + } + } + if (!found_offset) { + DEBUG(0, ("Subkey not found\n")); + return WERR_NOT_FOUND; + } + lf.key_count--; + + /* If the there are no entries left, free the subkey list */ + if (lf.key_count == 0) { + hbin_free(regf, list_offset); + *ret = -1; + return WERR_OK; + } + + /* Store lf block */ + *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_lf_block, list_offset, &lf); + } else if (strncmp((char *)data.data, "lh", 2) == 0) { + struct lh_block lh; + struct tdr_pull pull; + uint16_t i; + bool found_offset = false; + + DEBUG(10, ("Subkeys in LH list\n")); + + ZERO_STRUCT(pull); + pull.data = data; + + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, regf, &lh))) { + DEBUG(0, ("Error parsing LF list\n")); + return WERR_BADFILE; + } + + SMB_ASSERT(!strncmp(lh.header, "lh", 2)); + + for (i = 0; i < lh.key_count; i++) { + if (found_offset) { + lh.hr[i-1] = lh.hr[i]; + continue; + } + if (lh.hr[i].nk_offset == key_offset) { + found_offset = 1; + continue; + } + } + if (!found_offset) { + DEBUG(0, ("Subkey not found\n")); + return WERR_NOT_FOUND; + } + lh.key_count--; + + /* If the there are no entries left, free the subkey list */ + if (lh.key_count == 0) { + hbin_free(regf, list_offset); + *ret = -1; + return WERR_OK; + } + + /* Store lh block */ + *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_lh_block, list_offset, &lh); + } else if (strncmp((char *)data.data, "ri", 2) == 0) { + /* FIXME */ + DEBUG(0, ("Sorry, deletion from ri block is not supported yet.\n")); + return WERR_NOT_SUPPORTED; + } else { + DEBUG (0, ("Unknown header found in subkey list.\n")); + return WERR_BADFILE; + } + return WERR_OK; +} + +static WERROR regf_del_value (struct hive_key *key, const char *name) +{ + const struct regf_key_data *private_data = + (const struct regf_key_data *)key; + struct regf_data *regf = private_data->hive; + struct nk_block *nk = private_data->nk; + struct vk_block vk; + uint32_t vk_offset; + bool found_offset = false; + DATA_BLOB values; + uint32_t i; + + if (nk->values_offset == -1) { + return WERR_NOT_FOUND; + } + + values = hbin_get(regf, nk->values_offset); + + for (i = 0; i < nk->num_values; i++) { + if (found_offset) { + ((uint32_t *)values.data)[i-1] = ((uint32_t *) values.data)[i]; + } else { + vk_offset = IVAL(values.data, i * 4); + if (!hbin_get_tdr(regf, vk_offset, private_data, + (tdr_pull_fn_t)tdr_pull_vk_block, &vk)) { + DEBUG(0, ("Unable to get VK block at %d\n", vk_offset)); + return WERR_BADFILE; + } + if (strcmp(vk.data_name, name) == 0) { + hbin_free(regf, vk_offset); + found_offset = true; + } + } + } + if (!found_offset) { + return WERR_NOT_FOUND; + } else { + nk->num_values--; + values.length = (nk->num_values)*4; + } + + /* Store values list and nk */ + if (nk->num_values == 0) { + hbin_free(regf, nk->values_offset); + nk->values_offset = -1; + } else { + nk->values_offset = hbin_store_resize(regf, nk->values_offset, values); + } + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, private_data->offset, nk); + + return regf_save_hbin(private_data->hive); +} + + +static WERROR regf_del_key(const struct hive_key *parent, const char *name) +{ + const struct regf_key_data *private_data = + (const struct regf_key_data *)parent; + struct regf_key_data *key; + struct nk_block *parent_nk; + WERROR error; + + SMB_ASSERT(private_data); + + parent_nk = private_data->nk; + + if (parent_nk->subkeys_offset == -1) { + DEBUG(4, ("Subkey list is empty, this key cannot contain subkeys.\n")); + return WERR_NOT_FOUND; + } + + /* Find the key */ + if (!W_ERROR_IS_OK(regf_get_subkey_by_name(parent_nk, parent, name, + (struct hive_key **)&key))) { + DEBUG(0, ("Key '%s' not found\n", name)); + return WERR_NOT_FOUND; + } + + if (key->nk->subkeys_offset != -1 || + key->nk->values_offset != -1) { + DEBUG(0, ("Key '%s' is not empty.\n", name)); + return WERR_FILE_EXISTS; + } + + /* Delete it from the subkey list. */ + error = regf_sl_del_entry(private_data->hive, parent_nk->subkeys_offset, + key->offset, &parent_nk->subkeys_offset); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Can't store new subkey list for parent key. Won't delete.\n")); + return error; + } + + /* Re-store parent key */ + parent_nk->num_subkeys--; + hbin_store_tdr_resize(private_data->hive, + (tdr_push_fn_t) tdr_push_nk_block, + private_data->offset, parent_nk); + + if (key->nk->clsname_offset != -1) { + hbin_free(private_data->hive, key->nk->clsname_offset); + } + hbin_free(private_data->hive, key->offset); + + return regf_save_hbin(private_data->hive); +} + +static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent, + const char *name, const char *classname, + struct security_descriptor *sec_desc, + struct hive_key **ret) +{ + const struct regf_key_data *private_data = + (const struct regf_key_data *)parent; + struct nk_block *parent_nk = private_data->nk, nk; + struct nk_block *root; + struct regf_data *regf = private_data->hive; + uint32_t offset; + WERROR error; + + nk.header = "nk"; + nk.type = REG_SUB_KEY; + unix_to_nt_time(&nk.last_change, time(NULL)); + nk.uk1 = 0; + nk.parent_offset = private_data->offset; + nk.num_subkeys = 0; + nk.uk2 = 0; + nk.subkeys_offset = -1; + nk.unknown_offset = -1; + nk.num_values = 0; + nk.values_offset = -1; + memset(nk.unk3, 0, 5); + nk.clsname_offset = -1; /* FIXME: fill in */ + nk.clsname_length = 0; + nk.key_name = name; + + /* Get the security descriptor of the root key */ + root = talloc_zero(ctx, struct nk_block); + W_ERROR_HAVE_NO_MEMORY(root); + + if (!hbin_get_tdr(regf, regf->header->data_offset, root, + (tdr_pull_fn_t)tdr_pull_nk_block, root)) { + DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset)); + return WERR_GENERAL_FAILURE; + } + nk.sk_offset = root->sk_offset; + talloc_free(root); + + /* Store the new nk key */ + offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_nk_block, &nk); + + error = regf_sl_add_entry(regf, parent_nk->subkeys_offset, name, offset, &parent_nk->subkeys_offset); + if (!W_ERROR_IS_OK(error)) { + hbin_free(regf, offset); + return error; + } + + parent_nk->num_subkeys++; + + /* Since the subkey offset of the parent can change, store it again */ + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, + nk.parent_offset, parent_nk); + + *ret = (struct hive_key *)regf_get_key(ctx, regf, offset); + + return regf_save_hbin(private_data->hive); +} + +static WERROR regf_set_value(struct hive_key *key, const char *name, + uint32_t type, const DATA_BLOB data) +{ + const struct regf_key_data *private_data = + (const struct regf_key_data *)key; + struct regf_data *regf = private_data->hive; + struct nk_block *nk = private_data->nk; + struct vk_block vk; + uint32_t i; + uint32_t tmp_vk_offset, vk_offset, old_vk_offset = -1; + DATA_BLOB values; + + ZERO_STRUCT(vk); + + /* find the value offset, if it exists */ + if (nk->values_offset != -1) { + values = hbin_get(regf, nk->values_offset); + + for (i = 0; i < nk->num_values; i++) { + tmp_vk_offset = IVAL(values.data, i * 4); + if (!hbin_get_tdr(regf, tmp_vk_offset, private_data, + (tdr_pull_fn_t)tdr_pull_vk_block, &vk)) { + DEBUG(0, ("Unable to get VK block at %d\n", tmp_vk_offset)); + return WERR_GENERAL_FAILURE; + } + if (strcmp(vk.data_name, name) == 0) { + old_vk_offset = tmp_vk_offset; + break; + } + } + /* Free data, if any */ + if (!(vk.data_length & 0x80000000)) { + hbin_free(regf, vk.data_offset); + } + } + if (old_vk_offset == -1) { + vk.header = "vk"; + vk.name_length = strlen(name); + if (name != NULL && name[0] != 0) { + vk.flag = 1; + vk.data_name = name; + } else { + vk.data_name = NULL; + vk.flag = 0; + } + } + /* Set the type and data */ + vk.data_length = data.length; + vk.data_type = type; + if (type == REG_DWORD) { + vk.data_length |= 0x80000000; + vk.data_offset = *(uint32_t *)data.data; + } else { + /* Store data somewhere */ + vk.data_offset = hbin_store(regf, data); + } + if (old_vk_offset == -1) { + /* Store new vk */ + vk_offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_vk_block, &vk); + } else { + /* Store vk at offset */ + vk_offset = hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_vk_block, old_vk_offset ,&vk); + } + + /* Re-allocate the value list */ + if (nk->values_offset == -1) { + nk->values_offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_uint32, &vk_offset); + nk->num_values = 1; + } else { + + /* Change if we're changing, otherwise we're adding the value */ + if (old_vk_offset != -1) { + /* Find and overwrite the offset. */ + for (i = 0; i < nk->num_values; i++) { + if (IVAL(values.data, i * 4) == old_vk_offset) { + SIVAL(values.data, i * 4, vk_offset); + break; + } + } + } else { + /* Create a new value list */ + DATA_BLOB value_list; + + value_list.length = (nk->num_values+1)*4; + value_list.data = (void *)talloc_array(private_data, uint32_t, nk->num_values+1); + W_ERROR_HAVE_NO_MEMORY(value_list.data); + memcpy(value_list.data, values.data, nk->num_values * 4); + + SIVAL(value_list.data, nk->num_values * 4, vk_offset); + nk->num_values++; + nk->values_offset = hbin_store_resize(regf, nk->values_offset, value_list); + } + + } + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, private_data->offset, nk); + return regf_save_hbin(private_data->hive); +} + +static WERROR regf_save_hbin(struct regf_data *regf) +{ + struct tdr_push *push = talloc_zero(regf, struct tdr_push); + int i; + + W_ERROR_HAVE_NO_MEMORY(push); + + if (lseek(regf->fd, 0, SEEK_SET) == -1) { + DEBUG(0, ("Error lseeking in regf file\n")); + return WERR_GENERAL_FAILURE; + } + + /* Recompute checksum */ + if (NT_STATUS_IS_ERR(tdr_push_regf_hdr(push, regf->header))) { + DEBUG(0, ("Failed to push regf header\n")); + return WERR_GENERAL_FAILURE; + } + regf->header->chksum = regf_hdr_checksum(push->data.data); + talloc_free(push); + + if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, + (tdr_push_fn_t)tdr_push_regf_hdr, regf->header))) { + DEBUG(0, ("Error writing registry file header\n")); + return WERR_GENERAL_FAILURE; + } + + if (lseek(regf->fd, 0x1000, SEEK_SET) == -1) { + DEBUG(0, ("Error lseeking to 0x1000 in regf file\n")); + return WERR_GENERAL_FAILURE; + } + + for (i = 0; regf->hbins[i]; i++) { + if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, + (tdr_push_fn_t)tdr_push_hbin_block, + regf->hbins[i]))) { + DEBUG(0, ("Error writing HBIN block\n")); + return WERR_GENERAL_FAILURE; + } + } + + return WERR_OK; +} + +WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location, + int minor_version, struct hive_key **key) +{ + struct regf_data *regf; + struct regf_hdr *regf_hdr; + struct tdr_pull pull; + int i; + struct nk_block nk; + WERROR error; + + regf = (struct regf_data *)talloc_zero(NULL, struct regf_data); + + W_ERROR_HAVE_NO_MEMORY(regf); + + DEBUG(5, ("Attempting to create registry file\n")); + + /* Get the header */ + regf->fd = creat(location, 0644); + + if (regf->fd == -1) { + DEBUG(0,("Could not create file: %s, %s\n", location, + strerror(errno))); + talloc_free(regf); + return WERR_GENERAL_FAILURE; + } + + regf_hdr = talloc_zero(regf, struct regf_hdr); + W_ERROR_HAVE_NO_MEMORY(regf_hdr); + regf_hdr->REGF_ID = "regf"; + unix_to_nt_time(®f_hdr->modtime, time(NULL)); + regf_hdr->version.major = 1; + regf_hdr->version.minor = minor_version; + regf_hdr->last_block = 0x1000; /* Block size */ + regf_hdr->description = talloc_strdup(regf_hdr, "registry created by Samba 4"); + W_ERROR_HAVE_NO_MEMORY(regf_hdr->description); + regf_hdr->chksum = 0; + + regf->header = regf_hdr; + + pull.offset = 0x1000; + + i = 0; + /* Create all hbin blocks */ + regf->hbins = talloc_array(regf, struct hbin_block *, 1); + W_ERROR_HAVE_NO_MEMORY(regf->hbins); + regf->hbins[0] = NULL; + + regf_hdr->data_offset = -1; /* FIXME */ + + nk.header = "nk"; + nk.type = REG_SUB_KEY; + unix_to_nt_time(&nk.last_change, time(NULL)); + nk.uk1 = 0; + nk.parent_offset = -1; + nk.num_subkeys = 0; + nk.uk2 = 0; + nk.subkeys_offset = -1; + nk.unknown_offset = -1; + nk.num_values = 0; + nk.values_offset = -1; + memset(nk.unk3, 0, 5); + nk.clsname_offset = -1; /* FIXME: fill in */ + nk.clsname_length = 0; + nk.key_name = ""; + + nk.sk_offset = -1; /* FIXME: fill in */ + + /* Store the new nk key */ + regf->header->data_offset = hbin_store_tdr(regf, + (tdr_push_fn_t)tdr_push_nk_block, &nk); + + *key = (struct hive_key *)regf_get_key(parent_ctx, regf, regf->header->data_offset); + + /* We can drop our own reference now that *key will have created one */ + talloc_free(regf); + + error = regf_save_hbin(regf); + if (!W_ERROR_IS_OK(error)) { + return error; + } + + return WERR_OK; +} + +WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key) +{ + struct regf_data *regf; + struct regf_hdr *regf_hdr; + struct tdr_pull pull; + int i; + + regf = (struct regf_data *)talloc_zero(NULL, struct regf_data); + + W_ERROR_HAVE_NO_MEMORY(regf); + + DEBUG(5, ("Attempting to load registry file\n")); + + /* Get the header */ + regf->fd = open(location, O_RDWR); + + if (regf->fd == -1) { + DEBUG(0,("Could not load file: %s, %s\n", location, + strerror(errno))); + talloc_free(regf); + return WERR_GENERAL_FAILURE; + } + + ZERO_STRUCT(pull); + pull.data.data = (uint8_t*)fd_load(regf->fd, &pull.data.length, regf); + + if (pull.data.data == NULL) { + DEBUG(0, ("Error reading data\n")); + talloc_free(regf); + return WERR_GENERAL_FAILURE; + } + + regf_hdr = talloc(regf, struct regf_hdr); + W_ERROR_HAVE_NO_MEMORY(regf_hdr); + + if (NT_STATUS_IS_ERR(tdr_pull_regf_hdr(&pull, regf_hdr, regf_hdr))) { + talloc_free(regf); + return WERR_GENERAL_FAILURE; + } + + regf->header = regf_hdr; + + if (strcmp(regf_hdr->REGF_ID, "regf") != 0) { + DEBUG(0, ("Unrecognized NT registry header id: %s, %s\n", + regf_hdr->REGF_ID, location)); + talloc_free(regf); + return WERR_GENERAL_FAILURE; + } + + /* Validate the header ... */ + if (regf_hdr_checksum(pull.data.data) != regf_hdr->chksum) { + DEBUG(0, ("Registry file checksum error: %s: %d,%d\n", + location, regf_hdr->chksum, + regf_hdr_checksum(pull.data.data))); + talloc_free(regf); + return WERR_GENERAL_FAILURE; + } + + pull.offset = 0x1000; + + i = 0; + /* Read in all hbin blocks */ + regf->hbins = talloc_array(regf, struct hbin_block *, 1); + W_ERROR_HAVE_NO_MEMORY(regf->hbins); + + regf->hbins[0] = NULL; + + while (pull.offset < pull.data.length && pull.offset <= regf->header->last_block) { + struct hbin_block *hbin = talloc(regf->hbins, struct hbin_block); + + W_ERROR_HAVE_NO_MEMORY(hbin); + + if (NT_STATUS_IS_ERR(tdr_pull_hbin_block(&pull, hbin, hbin))) { + DEBUG(0, ("[%d] Error parsing HBIN block\n", i)); + talloc_free(regf); + return WERR_FOOBAR; + } + + if (strcmp(hbin->HBIN_ID, "hbin") != 0) { + DEBUG(0, ("[%d] Expected 'hbin', got '%s'\n", i, hbin->HBIN_ID)); + talloc_free(regf); + return WERR_FOOBAR; + } + + regf->hbins[i] = hbin; + i++; + regf->hbins = talloc_realloc(regf, regf->hbins, struct hbin_block *, i+2); + regf->hbins[i] = NULL; + } + + DEBUG(1, ("%d HBIN blocks read\n", i)); + + *key = (struct hive_key *)regf_get_key(parent_ctx, regf, + regf->header->data_offset); + + /* We can drop our own reference now that *key will have created one */ + talloc_free(regf); + + return WERR_OK; +} + +static struct hive_operations reg_backend_regf = { + .name = "regf", + .get_key_info = regf_get_info, + .enum_key = regf_get_subkey_by_index, + .get_key_by_name = regf_get_subkey_by_name, + .get_value_by_name = regf_get_value_by_name, + .enum_value = regf_get_value, + .get_sec_desc = regf_get_sec_desc, + .set_sec_desc = regf_set_sec_desc, + .add_key = regf_add_key, + .set_value = regf_set_value, + .del_key = regf_del_key, + .delete_value = regf_del_value, +}; diff --git a/source4/lib/registry/regf.idl b/source4/lib/registry/regf.idl index 46af4ffdc5..ffd7072b7a 100644 --- a/source4/lib/registry/regf.idl +++ b/source4/lib/registry/regf.idl @@ -45,8 +45,8 @@ interface regf uint32 data_offset; uint32 last_block; [value(1)] uint32 uk7; /* 1 */ - [charset(UTF16)] uint16 description[0x40]; - uint32 padding[83]; /* Padding */ + [charset(UTF16)] uint16 description[0x20]; + uint32 padding[99]; /* Padding */ /* Checksum of first 0x200 bytes XOR-ed */ uint32 chksum; }; @@ -66,7 +66,7 @@ interface regf uint8 data[offset_to_next-0x20]; /* data is filled with: uint32 length; - Negative if in used, positive otherwise + Negative if in use, positive otherwise Always a multiple of 8 uint8_t data[length]; Free space marker if 0xffffffff diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 09d61c6b4f..acfe056616 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. Registry interface Copyright (C) Gerald Carter 2002. - Copyright (C) Jelmer Vernooij 2003-2004. + Copyright (C) Jelmer Vernooij 2003-2007. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,9 +21,12 @@ #ifndef _REGISTRY_H /* _REGISTRY_H */ #define _REGISTRY_H +struct registry_context; + #include "core.h" #include "talloc/talloc.h" #include "librpc/gen_ndr/security.h" +#include "lib/registry/hive.h" /* Handles for the predefined keys */ #define HKEY_CLASSES_ROOT 0x80000000 @@ -36,6 +39,9 @@ #define HKEY_PERFORMANCE_TEXT 0x80000050 #define HKEY_PERFORMANCE_NLSTEXT 0x80000060 +#define HKEY_FIRST HKEY_CLASSES_ROOT +#define HKEY_LAST HKEY_PERFORMANCE_NLSTEXT + struct reg_predefined_key { uint32_t handle; const char *name; @@ -52,17 +58,16 @@ extern const struct reg_predefined_key reg_predefined_keys[]; #define REGISTRY_INTERFACE_VERSION 1 +struct reg_key_operations; + /* structure to store the registry handles */ struct registry_key { - const char *name; - const char *path; - const char *class_name; - NTTIME last_mod; - struct registry_hive *hive; - void *backend_data; + struct registry_context *context; }; +#include "lib/registry/patchfile.h" + struct registry_value { const char *name; @@ -74,109 +79,87 @@ struct registry_value typedef void (*reg_key_notification_function) (void); typedef void (*reg_value_notification_function) (void); -/* - * Container for function pointers to enumeration routines - * for virtual registry view - * - * Backends can provide : - * - just one hive (example: nt4, w95) - * - several hives (example: rpc). - * - * Backends should always do case-insensitive compares - * (everything is case-insensitive but case-preserving, - * just like the FS) - * - * There is no save function as all operations are expected to - * be atomic. - */ - -struct hive_operations { - const char *name; - - /* Implement this one */ - WERROR (*open_hive) (struct registry_hive *, struct registry_key **); - - /* Or this one */ - WERROR (*open_key) (TALLOC_CTX *, const struct registry_key *, const char *name, struct registry_key **); - - WERROR (*num_subkeys) (const struct registry_key *, uint32_t *count); - WERROR (*num_values) (const struct registry_key *, uint32_t *count); - WERROR (*get_subkey_by_index) (TALLOC_CTX *, const struct registry_key *, int idx, struct registry_key **); - - /* Can not contain more than one level */ - WERROR (*get_subkey_by_name) (TALLOC_CTX *, const struct registry_key *, const char *name, struct registry_key **); - WERROR (*get_value_by_index) (TALLOC_CTX *, const struct registry_key *, int idx, struct registry_value **); - - /* Can not contain more than one level */ - WERROR (*get_value_by_name) (TALLOC_CTX *, const struct registry_key *, const char *name, struct registry_value **); - - /* Security control */ - WERROR (*key_get_sec_desc) (TALLOC_CTX *, const struct registry_key *, struct security_descriptor **); - WERROR (*key_set_sec_desc) (const struct registry_key *, const struct security_descriptor *); - - /* Notification */ - WERROR (*request_key_change_notify) (const struct registry_key *, reg_key_notification_function); - WERROR (*request_value_change_notify) (const struct registry_value *, reg_value_notification_function); - - /* Key management */ - WERROR (*add_key)(TALLOC_CTX *, const struct registry_key *, const char *name, uint32_t access_mask, struct security_descriptor *, struct registry_key **); - WERROR (*del_key)(const struct registry_key *, const char *name); - WERROR (*flush_key) (const struct registry_key *); - - /* Value management */ - WERROR (*set_value)(const struct registry_key *, const char *name, uint32_t type, const DATA_BLOB data); - WERROR (*del_value)(const struct registry_key *, const char *valname); -}; - struct cli_credentials; +struct registry_context; -struct registry_hive -{ - const struct hive_operations *functions; - struct registry_key *root; - struct auth_session_info *session_info; - struct cli_credentials *credentials; - void *backend_data; - const char *location; -}; - -/* Handle to a full registry - * contains zero or more hives */ -struct registry_context { - void *backend_data; - struct cli_credentials *credentials; - struct auth_session_info *session_info; - WERROR (*get_predefined_key) (struct registry_context *, uint32_t hkey, struct registry_key **); -}; - -struct reg_init_function_entry { - const struct hive_operations *hive_functions; - struct reg_init_function_entry *prev, *next; -}; - -/* Representing differences between registry files */ - -struct reg_diff_value -{ +struct registry_operations { const char *name; - enum { REG_DIFF_DEL_VAL, REG_DIFF_SET_VAL } changetype; - uint32_t type; - DATA_BLOB data; -}; -struct reg_diff_key -{ - const char *name; - enum { REG_DIFF_CHANGE_KEY, REG_DIFF_DEL_KEY } changetype; - uint32_t numvalues; - struct reg_diff_value *values; -}; - -struct reg_diff -{ - const char *format; - uint32_t numkeys; - struct reg_diff_key *keys; + WERROR (*get_key_info) (TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char **classname, + uint32_t *numsubkeys, + uint32_t *numvalues, + NTTIME *last_change_time); + + WERROR (*flush_key) (struct registry_key *key); + + WERROR (*get_predefined_key) (const struct registry_context *ctx, + uint32_t key_id, + struct registry_key **key); + + WERROR (*open_key) (TALLOC_CTX *mem_ctx, + struct registry_key *parent, + const char *path, + struct registry_key **key); + + WERROR (*create_key) (TALLOC_CTX *mem_ctx, + struct registry_key *parent, + const char *name, + const char *key_class, + struct security_descriptor *security, + struct registry_key **key); + + WERROR (*delete_key) (struct registry_key *key, const char *name); + + WERROR (*delete_value) (struct registry_key *key, const char *name); + + WERROR (*enum_key) (TALLOC_CTX *mem_ctx, + const struct registry_key *key, uint32_t idx, + const char **name, + const char **keyclass, + NTTIME *last_changed_time); + + WERROR (*enum_value) (TALLOC_CTX *mem_ctx, + const struct registry_key *key, uint32_t idx, + const char **name, + uint32_t *type, + DATA_BLOB *data); + + WERROR (*get_security) (TALLOC_CTX *mem_ctx, + const struct registry_key *key, + struct security_descriptor **security); + + WERROR (*set_security) (struct registry_key *key, + const struct security_descriptor *security); + + WERROR (*load_key) (struct registry_key *key, + const char *key_name, + const char *path); + + WERROR (*unload_key) (struct registry_key *key, const char *name); + + WERROR (*notify_value_change) (struct registry_key *key, + reg_value_notification_function fn); + + WERROR (*get_value) (TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char *name, + uint32_t *type, + DATA_BLOB *data); + + WERROR (*set_value) (struct registry_key *key, + const char *name, + uint32_t type, + const DATA_BLOB data); +}; + +/** + * Handle to a full registry + * contains zero or more hives + */ +struct registry_context { + const struct registry_operations *ops; }; struct auth_session_info; @@ -186,60 +169,110 @@ struct event_context; #define _PUBLIC_ #endif +/** + * Open the locally defined registry. + */ _PUBLIC_ WERROR reg_open_local (TALLOC_CTX *mem_ctx, struct registry_context **ctx, struct auth_session_info *session_info, struct cli_credentials *credentials); +_PUBLIC_ WERROR reg_open_samba (TALLOC_CTX *mem_ctx, + struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials); + +/** + * Open the registry on a remote machine. + */ _PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, struct auth_session_info *session_info, struct cli_credentials *credentials, const char *location, struct event_context *ev); -_PUBLIC_ NTSTATUS registry_register(const void *_hive_ops); -_PUBLIC_ NTSTATUS registry_init(void); -_PUBLIC_ BOOL reg_has_backend(const char *backend); -_PUBLIC_ int reg_list_predefs(TALLOC_CTX *mem_ctx, char ***predefs, uint32_t **hkeys); +_PUBLIC_ WERROR reg_open_wine(struct registry_context **ctx, const char *path); + _PUBLIC_ const char *reg_get_predef_name(uint32_t hkey); -_PUBLIC_ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, const char *name, struct registry_key **key); -_PUBLIC_ WERROR reg_get_predefined_key(struct registry_context *ctx, uint32_t hkey, struct registry_key **key); -_PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *backend, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, struct registry_key **root); -_PUBLIC_ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, struct registry_key **result); -_PUBLIC_ WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *key, int idx, struct registry_value **val); -_PUBLIC_ WERROR reg_key_num_subkeys(const struct registry_key *key, uint32_t *count); -_PUBLIC_ WERROR reg_key_num_values(const struct registry_key *key, uint32_t *count); -_PUBLIC_ WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *key, int idx, struct registry_key **subkey); -WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char *name, struct registry_key **subkey); -_PUBLIC_ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char *name, struct registry_value **val); +_PUBLIC_ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, + const char *name, + struct registry_key **key); +_PUBLIC_ WERROR reg_get_predefined_key(const struct registry_context *ctx, + uint32_t hkey, + struct registry_key **key); + +_PUBLIC_ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, + const char *name, struct registry_key **result); + +_PUBLIC_ WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, + const struct registry_key *key, uint32_t idx, + const char **name, + uint32_t *type, + DATA_BLOB *data); +_PUBLIC_ WERROR reg_key_get_info(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char **class_name, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time); +_PUBLIC_ WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + int idx, + const char **name, + const char **classname, + NTTIME *last_mod_time); +WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char *name, + struct registry_key **subkey); +_PUBLIC_ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char *name, + uint32_t *type, + DATA_BLOB *data); _PUBLIC_ WERROR reg_key_del(struct registry_key *parent, const char *name); -_PUBLIC_ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, const struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *desc, struct registry_key **newkey); -_PUBLIC_ WERROR reg_val_set(struct registry_key *key, const char *value, uint32_t type, DATA_BLOB data); +_PUBLIC_ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, + struct registry_key *parent, const char *name, + const char *classname, + struct security_descriptor *desc, + struct registry_key **newkey); +_PUBLIC_ WERROR reg_val_set(struct registry_key *key, const char *value, + uint32_t type, DATA_BLOB data); _PUBLIC_ WERROR reg_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, struct security_descriptor **secdesc); -_PUBLIC_ WERROR reg_del_value(const struct registry_key *key, const char *valname); -_PUBLIC_ WERROR reg_key_flush(const struct registry_key *key); -_PUBLIC_ WERROR reg_key_subkeysizes(const struct registry_key *key, uint32_t *max_subkeylen, uint32_t *max_subkeysize); -_PUBLIC_ WERROR reg_key_valuesizes(const struct registry_key *key, uint32_t *max_valnamelen, uint32_t *max_valbufsize); +_PUBLIC_ WERROR reg_del_value(struct registry_key *key, const char *valname); +_PUBLIC_ WERROR reg_key_flush(struct registry_key *key); +WERROR reg_create_key (TALLOC_CTX *mem_ctx, + struct registry_key *parent, -/* Utility functions */ + const char *name, + const char *key_class, + struct security_descriptor *security, + struct registry_key **key); + + + +/* Utility functions */ _PUBLIC_ const char *str_regtype(int type); -_PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, DATA_BLOB *data); -_PUBLIC_ char *reg_val_description(TALLOC_CTX *mem_ctx, struct registry_value *val) ; +_PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, + const DATA_BLOB data); +_PUBLIC_ char *reg_val_description(TALLOC_CTX *mem_ctx, const char *name, + uint32_t type, const DATA_BLOB data); _PUBLIC_ BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data); -char *reg_path_win2unix(char *path) ; -char *reg_path_unix2win(char *path) ; WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result); WERROR reg_key_del_abs(struct registry_context *ctx, const char *path); WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx, const char *path, uint32_t access_mask, struct security_descriptor *sec_desc, struct registry_key **result); +WERROR reg_load_key(struct registry_context *ctx, struct registry_key *key, + const char *name, const char *filename); +WERROR reg_mount_hive(struct registry_context *rctx, + struct hive_key *hive_key, + uint32_t key_id, + const char **elements); -/* Patch files */ - -_PUBLIC_ struct reg_diff *reg_generate_diff(TALLOC_CTX *mem_ctx, struct registry_context *ctx1, struct registry_context *ctx2); -_PUBLIC_ WERROR reg_diff_save(const struct reg_diff *diff, const char *filename); -_PUBLIC_ struct reg_diff *reg_diff_load(TALLOC_CTX *ctx, const char *fn); -_PUBLIC_ BOOL reg_diff_apply (const struct reg_diff *diff, struct registry_context *ctx); +struct registry_key *reg_import_hive_key(struct registry_context *ctx, + struct hive_key *hive, + uint32_t predef_key, + const char **elements); -NTSTATUS registry_rpc_init(void); #endif /* _REGISTRY_H */ diff --git a/source4/lib/registry/rpc.c b/source4/lib/registry/rpc.c new file mode 100644 index 0000000000..59d41d591a --- /dev/null +++ b/source4/lib/registry/rpc.c @@ -0,0 +1,399 @@ +/* + Samba Unix/Linux SMB implementation + RPC backend for the registry library + Copyright (C) 2003-2007 Jelmer Vernooij, jelmer@samba.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "includes.h" +#include "registry.h" +#include "librpc/gen_ndr/ndr_winreg_c.h" + +struct rpc_key { + struct registry_key key; + struct policy_handle pol; + struct dcerpc_pipe *pipe; + + uint32_t num_values; + uint32_t num_subkeys; + uint32_t max_valnamelen; + uint32_t max_valdatalen; +}; + +struct rpc_registry_context { + struct registry_context context; + struct dcerpc_pipe *pipe; +}; + +static struct registry_operations reg_backend_rpc; + +/** + * This is the RPC backend for the registry library. + */ + +static void init_winreg_String(struct winreg_String *name, const char *s) +{ + name->name = s; +} + + +#define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *hnd) \ +{ \ + struct winreg_Open ## u r; \ + NTSTATUS status; \ + \ + r.in.system_name = NULL; \ + r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; \ + r.out.handle = hnd;\ + \ + status = dcerpc_winreg_Open ## u(p, mem_ctx, &r); \ + if (NT_STATUS_IS_ERR(status)) {\ + DEBUG(0,("Error executing open\n"));\ + return ntstatus_to_werror(status);\ + }\ +\ + return r.out.result;\ +} + +openhive(HKLM) +openhive(HKCU) +openhive(HKPD) +openhive(HKU) +openhive(HKCR) +openhive(HKDD) +openhive(HKCC) + +static struct { + uint32_t hkey; + WERROR (*open) (struct dcerpc_pipe *p, TALLOC_CTX *, struct policy_handle *h); +} known_hives[] = { + { HKEY_LOCAL_MACHINE, open_HKLM }, + { HKEY_CURRENT_USER, open_HKCU }, + { HKEY_CLASSES_ROOT, open_HKCR }, + { HKEY_PERFORMANCE_DATA, open_HKPD }, + { HKEY_USERS, open_HKU }, + { HKEY_DYN_DATA, open_HKDD }, + { HKEY_CURRENT_CONFIG, open_HKCC }, + { 0, NULL } +}; + +static WERROR rpc_query_key(const struct registry_key *k); + +static WERROR rpc_get_predefined_key(struct registry_context *ctx, + uint32_t hkey_type, + struct registry_key **k) +{ + int n; + struct rpc_registry_context *rctx = talloc_get_type(ctx, + struct rpc_registry_context); + struct rpc_key *mykeydata; + + for(n = 0; known_hives[n].hkey; n++) { + if(known_hives[n].hkey == hkey_type) + break; + } + + if (known_hives[n].open == NULL) { + DEBUG(1, ("No such hive %d\n", hkey_type)); + return WERR_NO_MORE_ITEMS; + } + + mykeydata = talloc(ctx, struct rpc_key); + mykeydata->pipe = rctx->pipe; + mykeydata->num_values = -1; + mykeydata->num_subkeys = -1; + return known_hives[n].open(mykeydata->pipe, *k, &(mykeydata->pol)); +} + +#if 0 +static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) +{ + struct winreg_OpenKey r; + struct rpc_key_data *mykeydata; + + k->backend_data = mykeydata = talloc(mem_ctx, struct rpc_key_data); + mykeydata->num_values = -1; + mykeydata->num_subkeys = -1; + + /* Then, open the handle using the hive */ + + memset(&r, 0, sizeof(struct winreg_OpenKey)); + r.in.handle = &(((struct rpc_key_data *)k->hive->root->backend_data)->pol); + init_winreg_String(&r.in.keyname, k->path); + r.in.unknown = 0x00000000; + r.in.access_mask = 0x02000000; + r.out.handle = &mykeydata->pol; + + dcerpc_winreg_OpenKey((struct dcerpc_pipe *)k->hive->backend_data, mem_ctx, &r); + + return r.out.result; +} +#endif + +static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, + const char *name, struct registry_key **key) +{ + struct rpc_key *mykeydata = talloc_get_type(h, struct rpc_key), + *newkeydata; + struct winreg_OpenKey r; + + mykeydata = talloc(mem_ctx, struct rpc_key); + + /* Then, open the handle using the hive */ + memset(&r, 0, sizeof(struct winreg_OpenKey)); + r.in.parent_handle = &mykeydata->pol; + init_winreg_String(&r.in.keyname, name); + r.in.unknown = 0x00000000; + r.in.access_mask = 0x02000000; + r.out.handle = &newkeydata->pol; + + dcerpc_winreg_OpenKey(mykeydata->pipe, mem_ctx, &r); + + return r.out.result; +} + +static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, + const struct registry_key *parent, + uint32_t n, + const char **value_name, + uint32_t *type, + DATA_BLOB *data) +{ + struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key); + WERROR error; + struct winreg_EnumValue r; + uint32_t len1, zero = 0; + NTSTATUS status; + struct winreg_StringBuf name; + uint8_t u8; + + if (mykeydata->num_values == -1) { + error = rpc_query_key(parent); + if(!W_ERROR_IS_OK(error)) return error; + } + + len1 = mykeydata->max_valdatalen; + + name.length = 0; + name.size = mykeydata->max_valnamelen * 2; + name.name = ""; + + r.in.handle = &mykeydata->pol; + r.in.enum_index = n; + r.in.name = &name; + r.in.type = type; + r.in.value = &u8; + r.in.length = &zero; + r.in.size = &len1; + r.out.name = &name; + + status = dcerpc_winreg_EnumValue(mykeydata->pipe, mem_ctx, &r); + if(NT_STATUS_IS_ERR(status)) { + DEBUG(0, ("Error in EnumValue: %s\n", nt_errstr(status))); + return WERR_GENERAL_FAILURE; + } + + if(NT_STATUS_IS_OK(status) && + W_ERROR_IS_OK(r.out.result) && r.out.length) { + *value_name = talloc_strdup(mem_ctx, r.out.name->name); + *data = data_blob_talloc(mem_ctx, r.out.value, *r.out.length); + return WERR_OK; + } + + return r.out.result; +} + +static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, + const struct registry_key *parent, + uint32_t n, + const char **name, + const char **keyclass, + NTTIME *last_changed_time) +{ + struct winreg_EnumKey r; + struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key); + NTSTATUS status; + struct winreg_StringBuf namebuf, classbuf; + NTTIME change_time = 0; + + namebuf.length = 0; + namebuf.size = 1024; + namebuf.name = NULL; + classbuf.length = 0; + classbuf.size = 0; + classbuf.name = NULL; + + r.in.handle = &mykeydata->pol; + r.in.enum_index = n; + r.in.name = &namebuf; + r.in.keyclass = &classbuf; + r.in.last_changed_time = &change_time; + r.out.name = &namebuf; + + status = dcerpc_winreg_EnumKey(mykeydata->pipe, mem_ctx, &r); + if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { + *name = talloc_strdup(mem_ctx, r.out.name->name); + *keyclass = talloc_strdup(mem_ctx, r.out.keyclass->name); + *last_changed_time = *r.out.last_changed_time; + } + + return r.out.result; +} + +static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, + struct registry_key *parent, const char *name, + const char *key_class, + struct security_descriptor *sec, + struct registry_key **key) +{ + NTSTATUS status; + struct winreg_CreateKey r; + struct rpc_key *parentkd = talloc_get_type(parent, struct rpc_key); + struct rpc_key *rpck = talloc(mem_ctx, struct rpc_key); + + init_winreg_String(&r.in.name, name); + init_winreg_String(&r.in.keyclass, NULL); + + r.in.handle = &parentkd->pol; + r.out.new_handle = &rpck->pol; + r.in.options = 0; + r.in.access_mask = SEC_STD_ALL; + r.in.secdesc = NULL; + + status = dcerpc_winreg_CreateKey(parentkd->pipe, mem_ctx, &r); + + if (!NT_STATUS_IS_OK(status)) { + talloc_free(rpck); + DEBUG(1, ("CreateKey failed - %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); + } + + if (W_ERROR_IS_OK(r.out.result)) { + rpck->pipe = talloc_reference(rpck, parentkd->pipe); + *key = (struct registry_key *)rpck; + } + + return r.out.result; +} + +static WERROR rpc_query_key(const struct registry_key *k) +{ + NTSTATUS status; + struct winreg_QueryInfoKey r; + struct rpc_key *mykeydata = talloc_get_type(k, struct rpc_key); + TALLOC_CTX *mem_ctx = talloc_init("query_key"); + + r.in.classname = talloc(mem_ctx, struct winreg_String); + init_winreg_String(r.in.classname, NULL); + r.in.handle = &mykeydata->pol; + + status = dcerpc_winreg_QueryInfoKey(mykeydata->pipe, mem_ctx, &r); + talloc_free(mem_ctx); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("QueryInfoKey failed - %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); + } + + if (W_ERROR_IS_OK(r.out.result)) { + mykeydata->num_subkeys = *r.out.num_subkeys; + mykeydata->num_values = *r.out.num_values; + mykeydata->max_valnamelen = *r.out.max_valnamelen; + mykeydata->max_valdatalen = *r.out.max_valbufsize; + } + + return r.out.result; +} + +static WERROR rpc_del_key(struct registry_key *parent, const char *name) +{ + NTSTATUS status; + struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key); + struct winreg_DeleteKey r; + TALLOC_CTX *mem_ctx = talloc_init("del_key"); + + r.in.handle = &mykeydata->pol; + init_winreg_String(&r.in.key, name); + + status = dcerpc_winreg_DeleteKey(mykeydata->pipe, mem_ctx, &r); + + talloc_free(mem_ctx); + + return r.out.result; +} + +static WERROR rpc_get_info(TALLOC_CTX *mem_ctx, const struct registry_key *key, + const char **classname, + uint32_t *numsubkeys, + uint32_t *numvalue) +{ + struct rpc_key *mykeydata = talloc_get_type(key, struct rpc_key); + WERROR error; + + if(mykeydata->num_values == -1) { + error = rpc_query_key(key); + if(!W_ERROR_IS_OK(error)) return error; + } + + /* FIXME: *classname = talloc_strdup(mem_ctx, mykeydata->classname); */ + *numvalue = mykeydata->num_values; + *numsubkeys = mykeydata->num_subkeys; + return WERR_OK; +} + +static struct registry_operations reg_backend_rpc = { + .name = "rpc", + .open_key = rpc_open_key, + .enum_key = rpc_get_subkey_by_index, + .enum_value = rpc_get_value_by_index, + .create_key = rpc_add_key, + .delete_key = rpc_del_key, + .get_key_info = rpc_get_info, +}; + +_PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + const char *location, struct event_context *ev) +{ + NTSTATUS status; + struct dcerpc_pipe *p; + struct rpc_registry_context *rctx; + + dcerpc_init(); + + rctx = talloc(NULL, struct rpc_registry_context); + + /* Default to local smbd if no connection is specified */ + if (!location) { + location = talloc_strdup(ctx, "ncalrpc:"); + } + + status = dcerpc_pipe_connect(*ctx /* TALLOC_CTX */, + &p, location, + &ndr_table_winreg, + credentials, ev); + rctx->pipe = p; + + if(NT_STATUS_IS_ERR(status)) { + DEBUG(1, ("Unable to open '%s': %s\n", location, nt_errstr(status))); + talloc_free(*ctx); + *ctx = NULL; + return ntstatus_to_werror(status); + } + + *ctx = (struct registry_context *)rctx; + + return WERR_OK; +} diff --git a/source4/lib/registry/samba.c b/source4/lib/registry/samba.c new file mode 100644 index 0000000000..244c467a2c --- /dev/null +++ b/source4/lib/registry/samba.c @@ -0,0 +1,85 @@ +/* + Unix SMB/CIFS implementation. + Copyright (C) Jelmer Vernooij 2004-2007. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "registry.h" + +/** + * @file + * @brief Samba-specific registry functions + */ + +WERROR mount_samba_hive(struct registry_context *ctx, + struct auth_session_info *auth_info, + struct cli_credentials *creds, + const char *name, + uint32_t hive_id) +{ + WERROR error; + struct hive_key *hive; + const char *location; + + location = talloc_asprintf(ctx, "%s/%s.ldb", lp_private_dir(), name); + + error = reg_open_hive(ctx, location, auth_info, creds, &hive); + if (!W_ERROR_IS_OK(error)) + return error; + + return reg_mount_hive(ctx, hive, hive_id, NULL); +} + + +_PUBLIC_ WERROR reg_open_samba (TALLOC_CTX *mem_ctx, + struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials) +{ + WERROR result; + + result = reg_open_local(mem_ctx, ctx, session_info, credentials); + if (!W_ERROR_IS_OK(result)) { + return result; + } + + mount_samba_hive(*ctx, session_info, credentials, + "hklm", HKEY_LOCAL_MACHINE); + + mount_samba_hive(*ctx, session_info, credentials, + "hkcr", HKEY_CLASSES_ROOT); + + /* FIXME: Should be mounted from NTUSER.DAT in the home directory of the + * current user */ + mount_samba_hive(*ctx, session_info, credentials, + "hkcu", HKEY_CURRENT_USER); + + mount_samba_hive(*ctx, session_info, credentials, + "hku", HKEY_USERS); + + /* FIXME: Different hive backend for HKEY_CLASSES_ROOT: merged view of HKEY_LOCAL_MACHINE\Software\Classes + * and HKEY_CURRENT_USER\Software\Classes */ + + /* FIXME: HKEY_CURRENT_CONFIG is an alias for HKEY_LOCAL_MACHINE\System\CurrentControlSet\Hardware Profiles\Current */ + + /* FIXME: HKEY_PERFORMANCE_DATA is dynamically generated */ + + /* FIXME: HKEY_LOCAL_MACHINE\Hardware is autogenerated */ + + /* FIXME: HKEY_LOCAL_MACHINE\Security\SAM is an alias for HKEY_LOCAL_MACHINE\SAM */ + + return WERR_OK; +} diff --git a/source4/lib/registry/tests/diff.c b/source4/lib/registry/tests/diff.c new file mode 100644 index 0000000000..220da88601 --- /dev/null +++ b/source4/lib/registry/tests/diff.c @@ -0,0 +1,105 @@ +/* + Unix SMB/CIFS implementation. + + local testing of registry diff functionality + + Copyright (C) Jelmer Vernooij 2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "lib/registry/registry.h" +#include "lib/cmdline/popt_common.h" +#include "torture/torture.h" +#include "librpc/gen_ndr/winreg.h" + +static bool test_generate_diff(struct torture_context *test) +{ + /* WERROR reg_generate_diff(struct registry_context *ctx1, + struct registry_context *ctx2, + const struct reg_diff_callbacks *callbacks, + void *callback_data) + */ + return true; +} + + +static bool test_diff_load(struct torture_context *test) +{ + /* WERROR reg_diff_load(const char *filename, const struct reg_diff_callbacks *callbacks, void *callback_data) */ + + return true; +} + +static bool test_diff_apply(struct torture_context *test) +{ + /* +_PUBLIC_ WERROR reg_diff_apply (const char *filename, struct registry_context *ctx) + */ + + return true; +} + +static const char *added_key = NULL; + +static WERROR test_add_key (void *callback_data, const char *key_name) +{ + added_key = talloc_strdup(callback_data, key_name); + + return WERR_OK; +} + +static bool test_generate_diff_key_add(struct torture_context *test) +{ + struct reg_diff_callbacks cb; + struct registry_key rk; + + return true; + + ZERO_STRUCT(cb); + + cb.add_key = test_add_key; + + if (W_ERROR_IS_OK(reg_generate_diff_key(&rk, NULL, "bla", &cb, test))) + return false; + + torture_assert_str_equal(test, added_key, "bla", "key added"); + + return true; +} + +static bool test_generate_diff_key_null(struct torture_context *test) +{ + struct reg_diff_callbacks cb; + + ZERO_STRUCT(cb); + + if (!W_ERROR_IS_OK(reg_generate_diff_key(NULL, NULL, "", &cb, NULL))) + return false; + + return true; +} + +struct torture_suite *torture_registry_diff(TALLOC_CTX *mem_ctx) +{ + struct torture_suite *suite = torture_suite_create(mem_ctx, + "DIFF"); + torture_suite_add_simple_test(suite, "test_generate_diff_key_add", test_generate_diff_key_add); + torture_suite_add_simple_test(suite, "test_generate_diff_key_null", test_generate_diff_key_null); + torture_suite_add_simple_test(suite, "test_diff_apply", test_diff_apply); + torture_suite_add_simple_test(suite, "test_generate_diff", test_generate_diff); + torture_suite_add_simple_test(suite, "test_diff_load", test_diff_load); + return suite; +} diff --git a/source4/lib/registry/tests/generic.c b/source4/lib/registry/tests/generic.c index 1f0c89e058..6595f86b18 100644 --- a/source4/lib/registry/tests/generic.c +++ b/source4/lib/registry/tests/generic.c @@ -3,7 +3,7 @@ local testing of registry library - Copyright (C) Jelmer Vernooij 2005 + Copyright (C) Jelmer Vernooij 2005-2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,6 +25,10 @@ #include "torture/torture.h" #include "librpc/gen_ndr/winreg.h" +struct torture_suite *torture_registry_hive(TALLOC_CTX *mem_ctx); +struct torture_suite *torture_registry_registry(TALLOC_CTX *mem_ctx); +struct torture_suite *torture_registry_diff(TALLOC_CTX *mem_ctx); + static bool test_str_regtype(struct torture_context *ctx) { torture_assert_str_equal(ctx, str_regtype(1), "REG_SZ", "REG_SZ failed"); @@ -38,7 +42,8 @@ static bool test_reg_val_data_string_dword(struct torture_context *ctx) { uint32_t d = 0x20; DATA_BLOB db = { (uint8_t *)&d, sizeof(d) }; - torture_assert_str_equal(ctx, "0x20", reg_val_data_string(ctx, REG_DWORD, &db), "dword failed"); + torture_assert_str_equal(ctx, "0x20", + reg_val_data_string(ctx, REG_DWORD, db), "dword failed"); return true; } @@ -46,9 +51,9 @@ static bool test_reg_val_data_string_sz(struct torture_context *ctx) { DATA_BLOB db; db.length = convert_string_talloc(ctx, CH_UNIX, CH_UTF16, "bla", 3, (void **)&db.data); - torture_assert_str_equal(ctx, "bla", reg_val_data_string(ctx, REG_SZ, &db), "sz failed"); + torture_assert_str_equal(ctx, "bla", reg_val_data_string(ctx, REG_SZ, db), "sz failed"); db.length = 4; - torture_assert_str_equal(ctx, "bl", reg_val_data_string(ctx, REG_SZ, &db), "sz failed"); + torture_assert_str_equal(ctx, "bl", reg_val_data_string(ctx, REG_SZ, db), "sz failed"); return true; } @@ -56,7 +61,9 @@ static bool test_reg_val_data_string_binary(struct torture_context *ctx) { uint8_t x[] = { 0x1, 0x2, 0x3, 0x4 }; DATA_BLOB db = { x, 4 }; - torture_assert_str_equal(ctx, "01020304", reg_val_data_string(ctx, REG_BINARY, &db), "binary failed"); + torture_assert_str_equal(ctx, "01020304", + reg_val_data_string(ctx, REG_BINARY, db), + "binary failed"); return true; } @@ -64,18 +71,20 @@ static bool test_reg_val_data_string_binary(struct torture_context *ctx) static bool test_reg_val_data_string_empty(struct torture_context *ctx) { DATA_BLOB db = { NULL, 0 }; - torture_assert_str_equal(ctx, "", reg_val_data_string(ctx, REG_BINARY, &db), "empty failed"); + torture_assert_str_equal(ctx, "", + reg_val_data_string(ctx, REG_BINARY, db), "empty failed"); return true; } static bool test_reg_val_description(struct torture_context *ctx) { - struct registry_value val; - val.name = "camel"; - val.data_type = REG_SZ; - val.data.length = convert_string_talloc(ctx, CH_UNIX, CH_UTF16, "stationary traveller", - strlen("stationary traveller"), (void **)&val.data.data); - torture_assert_str_equal(ctx, "camel = REG_SZ : stationary traveller", reg_val_description(ctx, &val), + DATA_BLOB data; + data.length = convert_string_talloc(ctx, CH_UNIX, CH_UTF16, + "stationary traveller", + strlen("stationary traveller"), + (void **)&data.data); + torture_assert_str_equal(ctx, "camel = REG_SZ : stationary traveller", + reg_val_description(ctx, "camel", REG_SZ, data), "reg_val_description failed"); return true; } @@ -83,12 +92,11 @@ static bool test_reg_val_description(struct torture_context *ctx) static bool test_reg_val_description_nullname(struct torture_context *ctx) { - struct registry_value val; - val.name = NULL; - val.data_type = REG_SZ; - val.data.length = convert_string_talloc(ctx, CH_UNIX, CH_UTF16, "west berlin", - strlen("west berlin"), (void **)&val.data.data); - torture_assert_str_equal(ctx, " = REG_SZ : west berlin", reg_val_description(ctx, &val), + DATA_BLOB data; + data.length = convert_string_talloc(ctx, CH_UNIX, CH_UTF16, "west berlin", + strlen("west berlin"), (void **)&data.data); + torture_assert_str_equal(ctx, " = REG_SZ : west berlin", + reg_val_description(ctx, NULL, REG_SZ, data), "description with null name failed"); return true; } @@ -98,12 +106,22 @@ struct torture_suite *torture_registry(TALLOC_CTX *mem_ctx) struct torture_suite *suite = torture_suite_create(mem_ctx, "REGISTRY"); torture_suite_add_simple_test(suite, "str_regtype", test_str_regtype); - torture_suite_add_simple_test(suite, "reg_val_data_string dword", test_reg_val_data_string_dword); - torture_suite_add_simple_test(suite, "reg_val_data_string sz", test_reg_val_data_string_sz); - torture_suite_add_simple_test(suite, "reg_val_data_string binary", test_reg_val_data_string_binary); - torture_suite_add_simple_test(suite, "reg_val_data_string empty", test_reg_val_data_string_empty); - torture_suite_add_simple_test(suite, "reg_val_description", test_reg_val_description); - torture_suite_add_simple_test(suite, "reg_val_description null", test_reg_val_description_nullname); + torture_suite_add_simple_test(suite, "reg_val_data_string dword", + test_reg_val_data_string_dword); + torture_suite_add_simple_test(suite, "reg_val_data_string sz", + test_reg_val_data_string_sz); + torture_suite_add_simple_test(suite, "reg_val_data_string binary", + test_reg_val_data_string_binary); + torture_suite_add_simple_test(suite, "reg_val_data_string empty", + test_reg_val_data_string_empty); + torture_suite_add_simple_test(suite, "reg_val_description", + test_reg_val_description); + torture_suite_add_simple_test(suite, "reg_val_description null", + test_reg_val_description_nullname); + + torture_suite_add_suite(suite, torture_registry_hive(mem_ctx)); + torture_suite_add_suite(suite, torture_registry_registry(mem_ctx)); + torture_suite_add_suite(suite, torture_registry_diff(mem_ctx)); return suite; } diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c new file mode 100644 index 0000000000..a04bc1168e --- /dev/null +++ b/source4/lib/registry/tests/hive.c @@ -0,0 +1,383 @@ +/* + Unix SMB/CIFS implementation. + + local testing of registry library - hives + + Copyright (C) Jelmer Vernooij 2005-2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "lib/registry/registry.h" +#include "lib/cmdline/popt_common.h" +#include "torture/torture.h" +#include "librpc/gen_ndr/winreg.h" +#include "system/filesys.h" + +NTSTATUS torture_temp_dir(struct torture_context *tctx, const char *prefix, + const char **tempdir); + +static bool test_del_nonexistant_key(struct torture_context *tctx, + const void *test_data) +{ + const struct hive_key *root = test_data; + WERROR error = hive_key_del(root, "bla"); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + "invalid return code"); + + return true; +} + +static bool test_keyinfo_root(struct torture_context *tctx, + const void *test_data) +{ + uint32_t num_subkeys, num_values; + const struct hive_key *root = test_data; + WERROR error; + + /* This is a new backend. There should be no subkeys and no + * values */ + error = hive_key_get_info(tctx, root, NULL, &num_subkeys, &num_values, + NULL); + torture_assert_werr_ok(tctx, error, "reg_key_num_subkeys()"); + + torture_assert_int_equal(tctx, num_subkeys, 0, "New key has non-zero subkey count"); + + torture_assert_werr_ok(tctx, error, "reg_key_num_values"); + + torture_assert_int_equal(tctx, num_values, 0, "New key has non-zero value count"); + + return true; +} + +static bool test_keyinfo_nums(struct torture_context *tctx, + const void *test_data) +{ + uint32_t num_subkeys, num_values; + const struct hive_key *root = test_data; + WERROR error; + struct hive_key *subkey; + uint32_t data = 42; + + error = hive_key_add_name(tctx, root, "Nested Keyll", NULL, + NULL, &subkey); + torture_assert_werr_ok(tctx, error, "hive_key_add_name"); + + error = hive_set_value(root, "Answer", REG_DWORD, + data_blob_talloc(tctx, &data, sizeof(data))); + torture_assert_werr_ok(tctx, error, "hive_set_value"); + + /* This is a new backend. There should be no subkeys and no + * values */ + error = hive_key_get_info(tctx, root, NULL, &num_subkeys, &num_values, + NULL); + torture_assert_werr_ok(tctx, error, "reg_key_num_subkeys()"); + + torture_assert_int_equal(tctx, num_subkeys, 1, "subkey count"); + + torture_assert_werr_ok(tctx, error, "reg_key_num_values"); + + torture_assert_int_equal(tctx, num_values, 1, "value count"); + + return true; +} + +static bool test_add_subkey(struct torture_context *tctx, + const void *test_data) +{ + WERROR error; + struct hive_key *subkey; + const struct hive_key *root = test_data; + TALLOC_CTX *mem_ctx = tctx; + + error = hive_key_add_name(mem_ctx, root, "Nested Key", NULL, + NULL, &subkey); + torture_assert_werr_ok(tctx, error, "hive_key_add_name"); + + error = hive_key_del(root, "Nested Key"); + torture_assert_werr_ok(tctx, error, "reg_key_del"); + + return true; +} + +static bool test_flush_key(struct torture_context *tctx, + const void *test_data) +{ + const struct hive_key *root = test_data; + + torture_assert_werr_ok(tctx, hive_key_flush(root), "flush key"); + + return true; +} + +static bool test_del_key(struct torture_context *tctx, const void *test_data) +{ + WERROR error; + struct hive_key *subkey; + const struct hive_key *root = test_data; + TALLOC_CTX *mem_ctx = tctx; + + error = hive_key_add_name(mem_ctx, root, "Nested Key", NULL, + NULL, &subkey); + torture_assert_werr_ok(tctx, error, "hive_key_add_name"); + + error = hive_key_del(root, "Nested Key"); + torture_assert_werr_ok(tctx, error, "reg_key_del"); + + error = hive_key_del(root, "Nested Key"); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "reg_key_del"); + + return true; +} + +static bool test_set_value(struct torture_context *tctx, + const void *test_data) +{ + WERROR error; + struct hive_key *subkey; + const struct hive_key *root = test_data; + TALLOC_CTX *mem_ctx = tctx; + uint32_t data = 42; + + error = hive_key_add_name(mem_ctx, root, "YA Nested Key", NULL, + NULL, &subkey); + torture_assert_werr_ok(tctx, error, "hive_key_add_name"); + + error = hive_set_value(subkey, "Answer", REG_DWORD, + data_blob_talloc(mem_ctx, &data, sizeof(data))); + torture_assert_werr_ok(tctx, error, "hive_set_value"); + + return true; +} + +static bool test_get_value(struct torture_context *tctx, const void *test_data) +{ + WERROR error; + struct hive_key *subkey; + const struct hive_key *root = test_data; + TALLOC_CTX *mem_ctx = tctx; + uint32_t data = 42; + uint32_t type; + DATA_BLOB value; + + error = hive_key_add_name(mem_ctx, root, "EYA Nested Key", NULL, + NULL, &subkey); + torture_assert_werr_ok(tctx, error, "hive_key_add_name"); + + error = hive_get_value(mem_ctx, subkey, "Answer", &type, &value); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + "getting missing value"); + + error = hive_set_value(subkey, "Answer", REG_DWORD, + data_blob_talloc(mem_ctx, &data, sizeof(data))); + torture_assert_werr_ok(tctx, error, "hive_set_value"); + + error = hive_get_value(mem_ctx, subkey, "Answer", &type, &value); + torture_assert_werr_ok(tctx, error, "getting value"); + + torture_assert(tctx, memcmp(value.data, &data, 4) == 0, "value data"); + + torture_assert_int_equal(tctx, value.length, 4, "value length"); + torture_assert_int_equal(tctx, type, REG_DWORD, "value type"); + + return true; +} + +static bool test_del_value(struct torture_context *tctx, const void *test_data) +{ + WERROR error; + struct hive_key *subkey; + const struct hive_key *root = test_data; + TALLOC_CTX *mem_ctx = tctx; + uint32_t data = 42; + uint32_t type; + DATA_BLOB value; + + error = hive_key_add_name(mem_ctx, root, "EEYA Nested Key", NULL, + NULL, &subkey); + torture_assert_werr_ok(tctx, error, "hive_key_add_name"); + + error = hive_set_value(subkey, "Answer", REG_DWORD, + data_blob_talloc(mem_ctx, &data, sizeof(data))); + torture_assert_werr_ok(tctx, error, "hive_set_value"); + + error = hive_del_value(subkey, "Answer"); + torture_assert_werr_ok(tctx, error, "deleting value"); + + error = hive_get_value(mem_ctx, subkey, "Answer", &type, &value); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "getting value"); + + error = hive_del_value(subkey, "Answer"); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "deleting value"); + + return true; +} + +static bool test_list_values(struct torture_context *tctx, + const void *test_data) +{ + WERROR error; + struct hive_key *subkey; + const struct hive_key *root = test_data; + TALLOC_CTX *mem_ctx = tctx; + uint32_t data = 42; + uint32_t type; + DATA_BLOB value; + const char *name; + + error = hive_key_add_name(mem_ctx, root, "AYAYA Nested Key", NULL, + NULL, &subkey); + torture_assert_werr_ok(tctx, error, "hive_key_add_name"); + + error = hive_set_value(subkey, "Answer", REG_DWORD, + data_blob_talloc(mem_ctx, &data, sizeof(data))); + torture_assert_werr_ok(tctx, error, "hive_set_value"); + + error = hive_get_value_by_index(mem_ctx, subkey, 0, &name, &type, &value); + torture_assert_werr_ok(tctx, error, "getting value"); + + torture_assert_str_equal(tctx, name, "Answer", "value name"); + torture_assert(tctx, memcmp(value.data, &data, 4) == 0, "value data"); + + torture_assert_int_equal(tctx, value.length, 4, "value length"); + torture_assert_int_equal(tctx, type, REG_DWORD, "value type"); + + error = hive_get_value_by_index(mem_ctx, subkey, 1, &name, &type, &value); + torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS, + "getting missing value"); + + return true; +} + +static void tcase_add_tests(struct torture_tcase *tcase) +{ + torture_tcase_add_simple_test(tcase, "del_nonexistant_key", + test_del_nonexistant_key); + torture_tcase_add_simple_test(tcase, "add_subkey", test_add_subkey); + torture_tcase_add_simple_test(tcase, "flush_key", test_flush_key); + torture_tcase_add_simple_test(tcase, "get_info", test_keyinfo_root); + torture_tcase_add_simple_test(tcase, "get_info_nums", test_keyinfo_nums); + torture_tcase_add_simple_test(tcase, "set_value", test_set_value); + torture_tcase_add_simple_test(tcase, "get_value", test_get_value); + torture_tcase_add_simple_test(tcase, "list_values", test_list_values); + torture_tcase_add_simple_test(tcase, "del_key", test_del_key); + torture_tcase_add_simple_test(tcase, "del_value", test_del_value); +} + +static bool hive_setup_dir(struct torture_context *tctx, void **data) +{ + struct hive_key *key; + WERROR error; + const char *dirname; + NTSTATUS status; + + status = torture_temp_dir(tctx, "hive-dir", &dirname); + if (!NT_STATUS_IS_OK(status)) + return false; + + rmdir(dirname); + + error = reg_create_directory(tctx, dirname, &key); + if (!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Unable to initialize dir hive\n"); + return false; + } + + *data = key; + + return true; +} + +static bool hive_setup_ldb(struct torture_context *tctx, void **data) +{ + struct hive_key *key; + WERROR error; + const char *dirname; + NTSTATUS status; + + status = torture_temp_dir(tctx, "hive-ldb", &dirname); + if (!NT_STATUS_IS_OK(status)) + return false; + + rmdir(dirname); + + error = reg_open_ldb_file(tctx, dirname, NULL, NULL, &key); + if (!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Unable to initialize ldb hive\n"); + return false; + } + + *data = key; + + return true; +} + +static bool hive_setup_regf(struct torture_context *tctx, void **data) +{ + struct hive_key *key; + WERROR error; + const char *dirname; + NTSTATUS status; + + status = torture_temp_dir(tctx, "hive-dir", &dirname); + if (!NT_STATUS_IS_OK(status)) + return false; + + rmdir(dirname); + + error = reg_create_regf_file(tctx, dirname, 5, &key); + if (!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Unable to create new regf file\n"); + return false; + } + + *data = key; + + return true; +} + +static bool test_dir_refuses_null_location(struct torture_context *tctx) +{ + torture_assert_werr_equal(tctx, WERR_INVALID_PARAM, + reg_open_directory(NULL, NULL, NULL), + "reg_open_directory accepts NULL location"); + return true; +} + +struct torture_suite *torture_registry_hive(TALLOC_CTX *mem_ctx) +{ + struct torture_tcase *tcase; + struct torture_suite *suite = torture_suite_create(mem_ctx, + "HIVE"); + + torture_suite_add_simple_test(suite, "dir-refuses-null-location", + test_dir_refuses_null_location); + + + tcase = torture_suite_add_tcase(suite, "dir"); + torture_tcase_set_fixture(tcase, hive_setup_dir, NULL); + tcase_add_tests(tcase); + + tcase = torture_suite_add_tcase(suite, "ldb"); + torture_tcase_set_fixture(tcase, hive_setup_ldb, NULL); + tcase_add_tests(tcase); + + tcase = torture_suite_add_tcase(suite, "regf"); + torture_tcase_set_fixture(tcase, hive_setup_regf, NULL); + tcase_add_tests(tcase); + + return suite; +} diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c new file mode 100644 index 0000000000..851f74fa3c --- /dev/null +++ b/source4/lib/registry/tests/registry.c @@ -0,0 +1,486 @@ +/* + Unix SMB/CIFS implementation. + + local testing of registry library - registry backend + + Copyright (C) Jelmer Vernooij 2005-2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "lib/registry/registry.h" +#include "lib/cmdline/popt_common.h" +#include "torture/torture.h" +#include "librpc/gen_ndr/winreg.h" +#include "system/filesys.h" + +NTSTATUS torture_temp_dir(struct torture_context *tctx, const char *prefix, + const char **tempdir); + +/** + * Test obtaining a predefined key. + */ +static bool test_get_predefined(struct torture_context *tctx, + const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *root; + WERROR error; + + error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root); + torture_assert_werr_ok(tctx, error, + "getting predefined key failed"); + return true; +} + +/** + * Test creating a new subkey + */ +static bool test_create_subkey(struct torture_context *tctx, + const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *root, *newkey; + WERROR error; + + error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root); + torture_assert_werr_ok(tctx, error, + "getting predefined key failed"); + + error = reg_key_add_name(rctx, root, "Bad Bentheim", NULL, NULL, &newkey); + torture_assert_werr_ok(tctx, error, "Creating key return code"); + torture_assert(tctx, newkey != NULL, "Creating new key"); + + return true; +} + +/** + * Test creating a new nested subkey + */ +static bool test_create_nested_subkey(struct torture_context *tctx, + const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *root, *newkey1, *newkey2; + WERROR error; + + error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root); + torture_assert_werr_ok(tctx, error, + "getting predefined key failed"); + + error = reg_key_add_name(rctx, root, "Hamburg", NULL, NULL, + &newkey1); + torture_assert_werr_ok(tctx, error, "Creating key return code"); + torture_assert(tctx, newkey2 != NULL, "Creating new key"); + + error = reg_key_add_name(rctx, root, "Hamburg\\Hamburg", NULL, NULL, + &newkey2); + torture_assert_werr_ok(tctx, error, "Creating key return code"); + torture_assert(tctx, newkey2 != NULL, "Creating new key"); + + return true; +} + +/** + * Test creating a new subkey + */ +static bool test_key_add_abs_top(struct torture_context *tctx, + const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *root; + WERROR error; + + error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT", 0, NULL, &root); + torture_assert_werr_equal(tctx, error, WERR_ALREADY_EXISTS, "create top level"); + + return true; +} + +/** + * Test creating a new subkey + */ +static bool test_key_add_abs(struct torture_context *tctx, + const void *_data) +{ + WERROR error; + const struct registry_context *rctx = _data; + struct registry_key *root, *result1, *result2; + + error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT\\bloe", 0, NULL, &result1); + torture_assert_werr_ok(tctx, error, "create lowest"); + + error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT\\bloe\\bla", 0, NULL, &result1); + torture_assert_werr_ok(tctx, error, "create nested"); + + error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root); + torture_assert_werr_ok(tctx, error, + "getting predefined key failed"); + + error = reg_open_key(tctx, root, "bloe", &result2); + torture_assert_werr_ok(tctx, error, "opening key"); + + error = reg_open_key(tctx, root, "bloe\\bla", &result2); + torture_assert_werr_ok(tctx, error, "opening key"); + + return true; +} + + +static bool test_del_key(struct torture_context *tctx, const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *root, *newkey; + WERROR error; + + error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root); + torture_assert_werr_ok(tctx, error, + "getting predefined key failed"); + + error = reg_key_add_name(rctx, root, "Hamburg", NULL, NULL, &newkey); + + torture_assert_werr_ok(tctx, error, "Creating key return code"); + torture_assert(tctx, newkey != NULL, "Creating new key"); + + error = reg_key_del(root, "Hamburg"); + torture_assert_werr_ok(tctx, error, "Delete key"); + + error = reg_key_del(root, "Hamburg"); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + "Delete missing key"); + + return true; +} + +/** + * Convenience function for opening the HKEY_CLASSES_ROOT hive and + * creating a single key for testing purposes. + */ +static bool create_test_key(struct torture_context *tctx, + const struct registry_context *rctx, + const char *name, + struct registry_key **root, + struct registry_key **subkey) +{ + WERROR error; + + error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, root); + torture_assert_werr_ok(tctx, error, + "getting predefined key failed"); + + error = reg_key_add_name(rctx, *root, name, NULL, NULL, subkey); + torture_assert_werr_ok(tctx, error, "Creating key return code"); + + return true; +} + + +static bool test_flush_key(struct torture_context *tctx, const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *root, *subkey; + WERROR error; + + if (!create_test_key(tctx, rctx, "Munchen", &root, &subkey)) + return false; + + error = reg_key_flush(subkey); + torture_assert_werr_ok(tctx, error, "flush key"); + + return true; +} + +static bool test_query_key(struct torture_context *tctx, const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *root, *subkey; + WERROR error; + NTTIME last_changed_time; + uint32_t num_subkeys, num_values; + const char *classname; + + if (!create_test_key(tctx, rctx, "Munchen", &root, &subkey)) + return false; + + error = reg_key_get_info(tctx, subkey, &classname, + &num_subkeys, &num_values, + &last_changed_time); + + torture_assert_werr_ok(tctx, error, "get info key"); + torture_assert(tctx, classname == NULL, "classname"); + torture_assert_int_equal(tctx, num_subkeys, 0, "num subkeys"); + torture_assert_int_equal(tctx, num_values, 0, "num values"); + + return true; +} + +static bool test_query_key_nums(struct torture_context *tctx, const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *root, *subkey1, *subkey2; + WERROR error; + uint32_t num_subkeys, num_values; + uint32_t data = 42; + + if (!create_test_key(tctx, rctx, "Berlin", &root, &subkey1)) + return false; + + error = reg_key_add_name(rctx, subkey1, "Bentheim", NULL, NULL, &subkey2); + torture_assert_werr_ok(tctx, error, "Creating key return code"); + + error = reg_val_set(subkey1, "Answer", REG_DWORD, + data_blob_talloc(tctx, &data, sizeof(data))); + torture_assert_werr_ok(tctx, error, "set value"); + + error = reg_key_get_info(tctx, subkey1, NULL, &num_subkeys, + &num_values, NULL); + + torture_assert_werr_ok(tctx, error, "get info key"); + torture_assert_int_equal(tctx, num_subkeys, 1, "num subkeys"); + torture_assert_int_equal(tctx, num_values, 1, "num values"); + + return true; +} + +/** + * Test that the subkeys of a key can be enumerated, that + * the returned parameters for get_subkey_by_index are optional and + * that enumerating the parents of a non-top-level node works. + */ +static bool test_list_subkeys(struct torture_context *tctx, const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *subkey = NULL, *root; + WERROR error; + NTTIME last_mod_time; + const char *classname, *name; + + if (!create_test_key(tctx, rctx, "Goettingen", &root, &subkey)) + return false; + + error = reg_key_get_subkey_by_index(tctx, root, 0, &name, &classname, + &last_mod_time); + + torture_assert_werr_ok(tctx, error, "Enum keys return code"); + torture_assert_str_equal(tctx, name, "Goettingen", "Enum keys data"); + + + error = reg_key_get_subkey_by_index(tctx, root, 0, NULL, NULL, NULL); + + torture_assert_werr_ok(tctx, error, "Enum keys with NULL arguments return code"); + + error = reg_key_get_subkey_by_index(tctx, root, 1, NULL, NULL, NULL); + + torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS, + "Invalid error for no more items"); + + error = reg_key_get_subkey_by_index(tctx, subkey, 0, NULL, NULL, NULL); + + torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS, + "Invalid error for no more items"); + + return true; +} + +/** + * Test setting a value + */ +static bool test_set_value(struct torture_context *tctx, const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *subkey = NULL, *root; + WERROR error; + uint32_t data = 42; + + if (!create_test_key(tctx, rctx, "Dusseldorf", &root, &subkey)) + return false; + + error = reg_val_set(subkey, "Answer", REG_DWORD, + data_blob_talloc(tctx, &data, sizeof(data))); + torture_assert_werr_ok (tctx, error, "setting value"); + + return true; +} + +/** + * Test getting a value + */ +static bool test_get_value(struct torture_context *tctx, const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *subkey = NULL, *root; + WERROR error; + DATA_BLOB data; + uint32_t value = 42; + uint32_t type; + + if (!create_test_key(tctx, rctx, "Duisburg", &root, &subkey)) + return false; + + error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, + &data); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + "getting missing value"); + + error = reg_val_set(subkey, __FUNCTION__, REG_DWORD, + data_blob_talloc(tctx, &value, 4)); + torture_assert_werr_ok (tctx, error, "setting value"); + + error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, + &data); + torture_assert_werr_ok(tctx, error, "getting value"); + + torture_assert_int_equal(tctx, 4, data.length, "value length ok"); + torture_assert(tctx, memcmp(data.data, &value, 4) == 0, "value content ok"); + torture_assert_int_equal(tctx, REG_DWORD, type, "value type"); + + return true; +} + +/** + * Test unsetting a value + */ +static bool test_del_value(struct torture_context *tctx, const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *subkey = NULL, *root; + WERROR error; + DATA_BLOB data; + uint32_t value = 42; + uint32_t type; + + if (!create_test_key(tctx, rctx, "Duisburg", &root, &subkey)) + return false; + + error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, + &data); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + "getting missing value"); + + error = reg_val_set(subkey, __FUNCTION__, REG_DWORD, + data_blob_talloc(tctx, &value, 4)); + torture_assert_werr_ok (tctx, error, "setting value"); + + error = reg_del_value(subkey, __FUNCTION__); + torture_assert_werr_ok (tctx, error, "unsetting value"); + + error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, &data); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + "getting missing value"); + + return true; +} + +/** + * Test listing values + */ +static bool test_list_values(struct torture_context *tctx, const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *subkey = NULL, *root; + WERROR error; + DATA_BLOB data; + uint32_t value = 42; + uint32_t type; + const char *name; + + if (!create_test_key(tctx, rctx, "Bonn", &root, &subkey)) + return false; + + error = reg_val_set(subkey, "bar", REG_DWORD, + data_blob_talloc(tctx, &value, 4)); + torture_assert_werr_ok (tctx, error, "setting value"); + + error = reg_key_get_value_by_index(tctx, subkey, 0, &name, &type, &data); + torture_assert_werr_ok(tctx, error, "getting value"); + + torture_assert_str_equal(tctx, name, "bar", "value name"); + torture_assert_int_equal(tctx, 4, data.length, "value length"); + torture_assert(tctx, memcmp(data.data, &value, 4) == 0, "value content"); + torture_assert_int_equal(tctx, REG_DWORD, type, "value type"); + + error = reg_key_get_value_by_index(tctx, subkey, 1, &name, &type, &data); + torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS, + "getting missing value"); + + return true; +} + +static bool setup_local_registry(struct torture_context *tctx, void **data) +{ + struct registry_context *rctx; + WERROR error; + const char *tempdir; + NTSTATUS status; + struct hive_key *hive_key; + + error = reg_open_local(tctx, &rctx, NULL, NULL); + if (!W_ERROR_IS_OK(error)) + return false; + + status = torture_temp_dir(tctx, "registry-local", &tempdir); + if (!NT_STATUS_IS_OK(status)) + return false; + + error = reg_open_ldb_file(tctx, + talloc_asprintf(tctx, "%s/classes_root.ldb", tempdir), + NULL, + NULL, + &hive_key); + if (!W_ERROR_IS_OK(error)) + return false; + + error = reg_mount_hive(rctx, hive_key, HKEY_CLASSES_ROOT, NULL); + if (!W_ERROR_IS_OK(error)) + return false; + + *data = rctx; + + return true; +} + +static void tcase_add_tests(struct torture_tcase *tcase) +{ + torture_tcase_add_simple_test(tcase, "list_subkeys", test_list_subkeys); + torture_tcase_add_simple_test(tcase, "get_predefined_key", + test_get_predefined); + torture_tcase_add_simple_test(tcase, "create_key", test_create_subkey); + torture_tcase_add_simple_test(tcase, "create_key", + test_create_nested_subkey); + torture_tcase_add_simple_test(tcase, "key_add_abs", test_key_add_abs); + torture_tcase_add_simple_test(tcase, "key_add_abs_top", test_key_add_abs_top); + torture_tcase_add_simple_test(tcase, "set_value", test_set_value); + torture_tcase_add_simple_test(tcase, "get_value", test_get_value); + torture_tcase_add_simple_test(tcase, "list_values", test_list_values); + torture_tcase_add_simple_test(tcase, "del_key", test_del_key); + torture_tcase_add_simple_test(tcase, "del_value", test_del_value); + torture_tcase_add_simple_test(tcase, "flush_key", test_flush_key); + torture_tcase_add_simple_test(tcase, "query_key", test_query_key); + torture_tcase_add_simple_test(tcase, "query_key_nums", test_query_key_nums); +} + +struct torture_suite *torture_registry_registry(TALLOC_CTX *mem_ctx) +{ + struct torture_tcase *tcase; + struct torture_suite *suite = torture_suite_create(mem_ctx, + "REGISTRY"); + + tcase = torture_suite_add_tcase(suite, "local"); + torture_tcase_set_fixture(tcase, setup_local_registry, NULL); + tcase_add_tests(tcase); + + return suite; +} diff --git a/source4/lib/registry/tools/common.c b/source4/lib/registry/tools/common.c new file mode 100644 index 0000000000..c8b0945c2c --- /dev/null +++ b/source4/lib/registry/tools/common.c @@ -0,0 +1,75 @@ +/* + Unix SMB/CIFS implementation. + Popt routines specifically for registry + + Copyright (C) Jelmer Vernooij 2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "auth/credentials/credentials.h" +#include "lib/registry/registry.h" + +struct registry_context *reg_common_open_remote(const char *remote, struct cli_credentials *creds) +{ + struct registry_context *h; + WERROR error; + + error = reg_open_remote(&h, NULL, creds, remote, NULL); + + if (!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Unable to open remote registry at %s:%s \n", remote, win_errstr(error)); + return NULL; + } + + return h; +} + +struct registry_key *reg_common_open_file(const char *path, struct cli_credentials *creds) +{ + struct hive_key *hive_root; + struct registry_context *h; + WERROR error; + + error = reg_open_hive(NULL, path, NULL, creds, &hive_root); + + if(!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Unable to open '%s': %s \n", path, win_errstr(error)); + return NULL; + } + + error = reg_open_local(NULL, &h, NULL, creds); + if (!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Unable to initialize local registry: %s\n", win_errstr(error)); + return NULL; + } + + return reg_import_hive_key(h, hive_root, -1, NULL); +} + +struct registry_context *reg_common_open_local(struct cli_credentials *creds) +{ + WERROR error; + struct registry_context *h; + + error = reg_open_samba(NULL, &h, NULL, creds); + + if(!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Unable to open local registry:%s \n", win_errstr(error)); + return NULL; + } + + return h; +} diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 6eb8a78caf..8030457f5c 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -2,7 +2,8 @@ Unix SMB/CIFS implementation. simple registry frontend - Copyright (C) Jelmer Vernooij 2004-2005 + Copyright (C) Jelmer Vernooij 2004-2007 + Copyright (C) Wilco Baan Hofman 2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,63 +23,115 @@ #include "lib/registry/registry.h" #include "lib/events/events.h" #include "lib/cmdline/popt_common.h" +#include "lib/registry/tools/common.h" -int main(int argc, char **argv) +enum reg_backend { REG_UNKNOWN, REG_LOCAL, REG_REMOTE, REG_NULL }; + +static struct registry_context *open_backend(poptContext pc, enum reg_backend backend, const char *remote_host) +{ + WERROR error; + struct registry_context *ctx; + + switch (backend) { + case REG_UNKNOWN: + poptPrintUsage(pc, stderr, 0); + return NULL; + case REG_LOCAL: + error = reg_open_samba(NULL, &ctx, NULL, cmdline_credentials); + break; + case REG_REMOTE: + error = reg_open_remote(&ctx, NULL, cmdline_credentials, remote_host, NULL); + break; + case REG_NULL: + error = reg_open_local(NULL, &ctx, NULL, cmdline_credentials); + break; + } + + if (!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Error: %s\n", win_errstr(error)); + return NULL; + } + + return ctx; +} + +int main(int argc, const char **argv) { int opt; poptContext pc; char *outputfile = NULL; + enum reg_backend backend1 = REG_UNKNOWN, backend2 = REG_UNKNOWN; + const char *remote1 = NULL, *remote2 = NULL; struct registry_context *h1 = NULL, *h2 = NULL; - int from_null = 0; WERROR error; - struct reg_diff *diff; struct poptOption long_options[] = { POPT_AUTOHELP - {"output", 'o', POPT_ARG_STRING, &outputfile, 'o', "output file to use", NULL }, - {"null", 'n', POPT_ARG_NONE, &from_null, 'n', "Diff from NULL", NULL }, - {"remote", 'R', POPT_ARG_STRING, NULL, 0, "Connect to remote server" , NULL }, - {"local", 'L', POPT_ARG_NONE, NULL, 0, "Open local registry", NULL }, + {"output", 'o', POPT_ARG_STRING, &outputfile, 0, "output file to use", NULL }, + {"null", 'n', POPT_ARG_NONE, NULL, 'n', "Diff from NULL", NULL }, + {"remote", 'R', POPT_ARG_STRING, NULL, 'R', "Connect to remote server" , NULL }, + {"local", 'L', POPT_ARG_NONE, NULL, 'L', "Open local registry", NULL }, POPT_COMMON_SAMBA POPT_COMMON_CREDENTIALS POPT_COMMON_VERSION { NULL } }; + TALLOC_CTX *ctx; + void *callback_data; + struct reg_diff_callbacks *callbacks; - registry_init(); + ctx = talloc_init("regdiff"); - pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); + pc = poptGetContext(argv[0], argc, argv, long_options,0); while((opt = poptGetNextOpt(pc)) != -1) { error = WERR_OK; switch(opt) { case 'L': - if (!h1 && !from_null) error = reg_open_local(NULL, &h1, NULL, cmdline_credentials); - else if (!h2) error = reg_open_local(NULL, &h2, NULL, cmdline_credentials); + if (backend1 == REG_UNKNOWN) + backend1 = REG_LOCAL; + else if (backend2 == REG_UNKNOWN) + backend2 = REG_LOCAL; + break; + case 'n': + if (backend1 == REG_UNKNOWN) + backend1 = REG_NULL; + else if (backend2 == REG_UNKNOWN) + backend2 = REG_NULL; break; case 'R': - if (!h1 && !from_null) - error = reg_open_remote(&h1, NULL, cmdline_credentials, - poptGetOptArg(pc), NULL); - else if (!h2) error = reg_open_remote(&h2, NULL, cmdline_credentials, - poptGetOptArg(pc), NULL); + if (backend1 == REG_UNKNOWN) { + backend1 = REG_REMOTE; + remote1 = poptGetOptArg(pc); + } else if (backend2 == REG_UNKNOWN) { + backend2 = REG_REMOTE; + remote2 = poptGetOptArg(pc); + } break; } - if (!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Error: %s\n", win_errstr(error)); - return 1; - } } + h1 = open_backend(pc, backend1, remote1); + if (h1 == NULL) + return 1; + + h2 = open_backend(pc, backend2, remote2); + if (h2 == NULL) + return 1; + poptFreeContext(pc); - diff = reg_generate_diff(NULL, h1, h2); - if (!diff) { - fprintf(stderr, "Unable to generate diff between keys\n"); + error = reg_dotreg_diff_save(ctx, outputfile, &callbacks, &callback_data); + if (!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Problem saving registry diff to '%s': %s\n", outputfile, win_errstr(error)); return -1; } - reg_diff_save(diff, outputfile); + error = reg_generate_diff(h1, h2, callbacks, callback_data); + if (!W_ERROR_IS_OK(error)) { + fprintf(stderr, "Unable to generate diff between keys: %s\n", win_errstr(error)); + return -1; + } return 0; } diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 83ad5575ef..1e6d15a7af 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. simple registry frontend - Copyright (C) 2004-2005 Jelmer Vernooij, jelmer@samba.org + Copyright (C) 2004-2007 Jelmer Vernooij, jelmer@samba.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,6 +22,8 @@ #include "lib/events/events.h" #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" +#include "lib/registry/tools/common.h" +#include "lib/registry/patchfile.h" int main(int argc, char **argv) { @@ -29,12 +31,12 @@ int main(int argc, char **argv) poptContext pc; const char *patch; struct registry_context *h; + const char *file = NULL; const char *remote = NULL; - struct reg_diff *diff; - WERROR error; struct poptOption long_options[] = { POPT_AUTOHELP {"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL}, + {"file", 'F', POPT_ARG_STRING, &file, 0, "file path", NULL }, POPT_COMMON_SAMBA POPT_COMMON_CREDENTIALS { NULL } @@ -45,29 +47,24 @@ int main(int argc, char **argv) while((opt = poptGetNextOpt(pc)) != -1) { } - registry_init(); - if (remote) { - error = reg_open_remote (&h, NULL, cmdline_credentials, remote, NULL); + h = reg_common_open_remote (remote, cmdline_credentials); } else { - error = reg_open_local (NULL, &h, NULL, cmdline_credentials); + h = reg_common_open_local (cmdline_credentials); } - - if (W_ERROR_IS_OK(error)) { - fprintf(stderr, "Error: %s\n", win_errstr(error)); + + if (h == NULL) return 1; - } patch = poptGetArg(pc); - poptFreeContext(pc); - - diff = reg_diff_load(NULL, patch); - if (!diff) { - fprintf(stderr, "Unable to load registry patch from `%s'\n", patch); + if (patch == NULL) { + poptPrintUsage(pc, stderr, 0); return 1; } - reg_diff_apply(diff, h); + poptFreeContext(pc); + + reg_diff_apply(patch, h); return 0; } diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index f431c81bf8..0887bc91f3 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. simple registry frontend - Copyright (C) Jelmer Vernooij 2004 + Copyright (C) Jelmer Vernooij 2004-2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,8 +25,15 @@ #include "system/time.h" #include "lib/smbreadline/smbreadline.h" #include "librpc/gen_ndr/ndr_security.h" +#include "lib/registry/tools/common.h" -/* +struct regshell_context { + struct registry_context *registry; + const char *path; + struct registry_key *current; +}; + +/* * * ck/cd - change key * ls - list values/keys * rmval/rm - remove value @@ -40,29 +47,40 @@ * exit */ -static struct registry_key *cmd_info(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) +static WERROR cmd_info(struct regshell_context *ctx, int argc, char **argv) { struct security_descriptor *sec_desc = NULL; time_t last_mod; WERROR error; + const char *classname; + NTTIME last_change; + + error = reg_key_get_info(ctx, ctx->current, &classname, NULL, NULL, &last_change); + if (!W_ERROR_IS_OK(error)) { + printf("Error getting key info: %s\n", win_errstr(error)); + return error; + } + - printf("Name: %s\n", cur->name); - printf("Full path: %s\n", cur->path); - printf("Key Class: %s\n", cur->class_name); - last_mod = nt_time_to_unix(cur->last_mod); + printf("Name: %s\n", strchr(ctx->path, '\\')?strrchr(ctx->path, '\\')+1: + ctx->path); + printf("Full path: %s\n", ctx->path); + printf("Key Class: %s\n", classname); + last_mod = nt_time_to_unix(last_change); printf("Time Last Modified: %s\n", ctime(&last_mod)); - error = reg_get_sec_desc(mem_ctx, cur, &sec_desc); + error = reg_get_sec_desc(ctx, ctx->current, &sec_desc); if (!W_ERROR_IS_OK(error)) { printf("Error getting security descriptor\n"); - } else { - ndr_print_debug((ndr_print_fn_t)ndr_print_security_descriptor, "Security", sec_desc); - } + return error; + } + ndr_print_debug((ndr_print_fn_t)ndr_print_security_descriptor, "Security", sec_desc); talloc_free(sec_desc); - return cur; + + return WERR_OK; } -static struct registry_key *cmd_predef(TALLOC_CTX *mem_ctx, struct registry_context *ctx, struct registry_key *cur, int argc, char **argv) +static WERROR cmd_predef(struct regshell_context *ctx, int argc, char **argv) { struct registry_key *ret = NULL; if (argc < 2) { @@ -70,165 +88,195 @@ static struct registry_key *cmd_predef(TALLOC_CTX *mem_ctx, struct registry_cont } 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); + WERROR error = reg_get_predefined_key_by_name(ctx->registry, 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 error; } } - return ret; + + return WERR_OK; } -static struct registry_key *cmd_pwd(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) +static WERROR cmd_pwd(struct regshell_context *ctx, + int argc, char **argv) { - printf("%s\n", cur->path); - return cur; + printf("%s\n", ctx->path); + return WERR_OK; } -static struct registry_key *cmd_set(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) +static WERROR cmd_set(struct regshell_context *ctx, int argc, char **argv) { struct registry_value val; WERROR error; if (argc < 4) { fprintf(stderr, "Usage: set value-name type value\n"); - return cur; + return WERR_INVALID_PARAM; } - if (!reg_string_to_val(mem_ctx, argv[2], argv[3], &val.data_type, &val.data)) { + if (!reg_string_to_val(ctx, argv[2], argv[3], &val.data_type, + &val.data)) { fprintf(stderr, "Unable to interpret data\n"); - return cur; + return WERR_INVALID_PARAM; } - error = reg_val_set(cur, argv[1], val.data_type, val.data); + error = reg_val_set(ctx->current, argv[1], val.data_type, val.data); if (!W_ERROR_IS_OK(error)) { fprintf(stderr, "Error setting value: %s\n", win_errstr(error)); - return NULL; + return error; } - return cur; + + return WERR_OK; } -static struct registry_key *cmd_ck(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) +static WERROR cmd_ck(struct regshell_context *ctx, int argc, char **argv) { struct registry_key *new = NULL; WERROR error; + if(argc < 2) { - new = cur; + new = ctx->current; } else { - error = reg_open_key(mem_ctx, cur, argv[1], &new); + error = reg_open_key(ctx->registry, ctx->current, argv[1], &new); if(!W_ERROR_IS_OK(error)) { DEBUG(0, ("Error opening specified key: %s\n", win_errstr(error))); - return NULL; + return error; } } - printf("Current path is: %s\n", new->path); + ctx->path = talloc_asprintf(ctx, "%s\\%s", ctx->path, argv[1]); + printf("Current path is: %s\n", ctx->path); + ctx->current = new; - return new; + return WERR_OK; } -static struct registry_key *cmd_print(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) +static WERROR cmd_print(struct regshell_context *ctx, int argc, char **argv) { - struct registry_value *value; + uint32_t value_type; + DATA_BLOB value_data; WERROR error; if (argc != 2) { fprintf(stderr, "Usage: print "); - return NULL; + return WERR_INVALID_PARAM; } - error = reg_key_get_value_by_name(mem_ctx, cur, argv[1], &value); + error = reg_key_get_value_by_name(ctx, ctx->current, argv[1], + &value_type, &value_data); if (!W_ERROR_IS_OK(error)) { fprintf(stderr, "No such value '%s'\n", argv[1]); - return NULL; + return error; } - printf("%s\n%s\n", str_regtype(value->data_type), reg_val_data_string(mem_ctx, value->data_type, &value->data)); - return NULL; + printf("%s\n%s\n", str_regtype(value_type), + reg_val_data_string(ctx, value_type, value_data)); + + return WERR_OK; } -static struct registry_key *cmd_ls(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) +static WERROR cmd_ls(struct regshell_context *ctx, int argc, char **argv) { int i; WERROR error; struct registry_value *value; - struct registry_key *sub; - for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(mem_ctx, cur, i, &sub)); i++) { - printf("K %s\n", sub->name); + uint32_t data_type; + DATA_BLOB data; + const char *name; + + for (i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(ctx, ctx->current, i, &name, NULL, NULL)); i++) { + printf("K %s\n", name); } - if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { + if (!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { DEBUG(0, ("Error occured while browsing thru keys: %s\n", win_errstr(error))); } - for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(mem_ctx, cur, i, &value)); i++) { - printf("V \"%s\" %s %s\n", value->name, str_regtype(value->data_type), reg_val_data_string(mem_ctx, value->data_type, &value->data)); + for (i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(ctx, ctx->current, i, &name, &data_type, &data)); i++) { + printf("V \"%s\" %s %s\n", value->name, str_regtype(data_type), + reg_val_data_string(ctx, data_type, data)); } - return NULL; + return WERR_OK; } -static struct registry_key *cmd_mkkey(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) +static WERROR cmd_mkkey(struct regshell_context *ctx, int argc, char **argv) { struct registry_key *tmp; + WERROR error; + if(argc < 2) { fprintf(stderr, "Usage: mkkey \n"); - return NULL; + return WERR_INVALID_PARAM; } + + error = reg_key_add_name(ctx, ctx->current, argv[1], 0, NULL, &tmp); - if(!W_ERROR_IS_OK(reg_key_add_name(mem_ctx, cur, argv[1], 0, NULL, &tmp))) { + if (!W_ERROR_IS_OK(error)) { fprintf(stderr, "Error adding new subkey '%s'\n", argv[1]); - return NULL; + return error; } - return NULL; + return WERR_OK; } -static struct registry_key *cmd_rmkey(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) +static WERROR cmd_rmkey(struct regshell_context *ctx, + int argc, char **argv) { + WERROR error; + if(argc < 2) { fprintf(stderr, "Usage: rmkey \n"); - return NULL; + return WERR_INVALID_PARAM; } - if(!W_ERROR_IS_OK(reg_key_del(cur, argv[1]))) { + error = reg_key_del(ctx->current, argv[1]); + if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Error deleting '%s'\n", argv[1]); + return error; } else { fprintf(stderr, "Successfully deleted '%s'\n", argv[1]); } - return NULL; + return WERR_OK; } -static struct registry_key *cmd_rmval(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) +static WERROR cmd_rmval(struct regshell_context *ctx, int argc, char **argv) { + WERROR error; + if(argc < 2) { fprintf(stderr, "Usage: rmval \n"); - return NULL; + return WERR_INVALID_PARAM; } - if(!W_ERROR_IS_OK(reg_del_value(cur, argv[1]))) { + error = reg_del_value(ctx->current, argv[1]); + if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Error deleting value '%s'\n", argv[1]); + return error; } else { fprintf(stderr, "Successfully deleted value '%s'\n", argv[1]); } - return NULL; + return WERR_OK; } -static struct registry_key *cmd_exit(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *cur, int argc, char **argv) +static WERROR cmd_exit(struct regshell_context *ctx, + int argc, char **argv) { exit(0); - return NULL; + return WERR_OK; } -static struct registry_key *cmd_help(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *, int, char **); +static WERROR cmd_help(struct regshell_context *ctx, int, char **); static struct { const char *name; const char *alias; const char *help; - struct registry_key *(*handle)(TALLOC_CTX *mem_ctx, struct registry_context *ctx,struct registry_key *, int argc, char **argv); + WERROR (*handle)(struct regshell_context *ctx, + int argc, char **argv); } regshell_cmds[] = { {"ck", "cd", "Change current key", cmd_ck }, {"info", "i", "Show detailed information of a key", cmd_info }, @@ -245,17 +293,19 @@ static struct { {NULL } }; -static struct registry_key *cmd_help(TALLOC_CTX *mem_ctx, struct registry_context *ctx, struct registry_key *cur, int argc, char **argv) +static WERROR cmd_help(struct regshell_context *ctx, + int argc, char **argv) { int i; printf("Available commands:\n"); for(i = 0; regshell_cmds[i].name; i++) { printf("%s - %s\n", regshell_cmds[i].name, regshell_cmds[i].help); } - return NULL; + return WERR_OK; } -static struct registry_key *process_cmd(TALLOC_CTX *mem_ctx, struct registry_context *ctx, struct registry_key *k, char *line) +static WERROR process_cmd(struct regshell_context *ctx, + char *line) { int argc; char **argv = NULL; @@ -263,19 +313,19 @@ static struct registry_key *process_cmd(TALLOC_CTX *mem_ctx, struct registry_con if ((ret = poptParseArgvString(line, &argc, (const char ***) &argv)) != 0) { fprintf(stderr, "regshell: %s\n", poptStrerror(ret)); - return k; + return WERR_INVALID_PARAM; } 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, ctx, k, argc, argv); + return regshell_cmds[i].handle(ctx, argc, argv); } } fprintf(stderr, "No such command '%s'\n", argv[0]); - return k; + return WERR_INVALID_PARAM; } #define MAX_COMPLETIONS 100 @@ -333,7 +383,7 @@ cleanup: static char **reg_complete_key(const char *text, int start, int end) { struct registry_key *base; - struct registry_key *subkey; + const char *subkeyname; int i, j = 1; int samelen = 0; int len; @@ -351,10 +401,11 @@ static char **reg_complete_key(const char *text, int start, int end) len = strlen(text); for(i = 0; j < MAX_COMPLETIONS-1; i++) { - status = reg_key_get_subkey_by_index(mem_ctx, base, i, &subkey); + status = reg_key_get_subkey_by_index(mem_ctx, base, i, &subkeyname, + NULL, NULL); if(W_ERROR_IS_OK(status)) { - if(!strncmp(text, subkey->name, len)) { - matches[j] = strdup(subkey->name); + if(!strncmp(text, subkeyname, len)) { + matches[j] = strdup(subkeyname); j++; if (j == 1) @@ -381,7 +432,8 @@ static char **reg_complete_key(const char *text, int start, int end) if (j == 2) { /* Exact match */ asprintf(&matches[0], "%s%s", base_n, matches[1]); } else { - asprintf(&matches[0], "%s%s", base_n, talloc_strndup(mem_ctx, matches[1], samelen)); + asprintf(&matches[0], "%s%s", base_n, + talloc_strndup(mem_ctx, matches[1], samelen)); } talloc_free(mem_ctx); @@ -400,19 +452,17 @@ static char **reg_completion(const char *text, int start, int end) } } - int main(int argc, char **argv) +int main(int argc, char **argv) { int opt; - const char *backend = NULL; - struct registry_key *curkey = NULL; + const char *file = NULL; poptContext pc; - WERROR error; - TALLOC_CTX *mem_ctx = talloc_init("cmd"); const char *remote = NULL; - struct registry_context *h = NULL; + struct regshell_context *ctx; + bool ret = true; struct poptOption long_options[] = { POPT_AUTOHELP - {"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL}, + {"file", 'F', POPT_ARG_STRING, &file, 0, "open hive file", NULL }, {"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL}, POPT_COMMON_SAMBA POPT_COMMON_CREDENTIALS @@ -425,64 +475,62 @@ static char **reg_completion(const char *text, int start, int end) while((opt = poptGetNextOpt(pc)) != -1) { } - registry_init(); + ctx = talloc_zero(NULL, struct regshell_context); - if (remote) { - error = reg_open_remote (&h, NULL, cmdline_credentials, remote, NULL); - } else if (backend) { - error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, cmdline_credentials, &curkey); + if (remote != NULL) { + ctx->registry = reg_common_open_remote(remote, cmdline_credentials); + } else if (file != NULL) { + ctx->current = reg_common_open_file(file, cmdline_credentials); + ctx->registry = ctx->current->context; + ctx->path = talloc_strdup(ctx, ""); } else { - error = reg_open_local(NULL, &h, NULL, cmdline_credentials); + ctx->registry = reg_common_open_local(cmdline_credentials); } - if(!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Unable to open registry\n"); + if (ctx->registry == NULL) return 1; - } - if (h) { + if (ctx->current == NULL) { int i; for (i = 0; reg_predefined_keys[i].handle; i++) { WERROR err; - err = reg_get_predefined_key(h, reg_predefined_keys[i].handle, &curkey); + err = reg_get_predefined_key(ctx->registry, + reg_predefined_keys[i].handle, + &ctx->current); if (W_ERROR_IS_OK(err)) { + ctx->path = talloc_strdup(ctx, reg_predefined_keys[i].name); break; } else { - curkey = NULL; + ctx->current = NULL; } } } - if (!curkey) { + if (ctx->current == NULL) { fprintf(stderr, "Unable to access any of the predefined keys\n"); return -1; } poptFreeContext(pc); - while(True) { + while (true) { char *line, *prompt; - if(curkey->hive->root->name) { - asprintf(&prompt, "%s:%s> ", curkey->hive->root->name, curkey->path); - } else { - asprintf(&prompt, "%s> ", curkey->path); - } + asprintf(&prompt, "%s> ", ctx->path); - current_key = curkey; /* No way to pass a void * pointer - via readline :-( */ + current_key = ctx->current; /* No way to pass a void * pointer + via readline :-( */ line = smb_readline(prompt, NULL, reg_completion); - if(!line) + if (line == NULL) break; - if(line[0] != '\n') { - struct registry_key *new = process_cmd(mem_ctx, h, curkey, line); - if(new)curkey = new; + if (line[0] != '\n') { + ret = W_ERROR_IS_OK(process_cmd(ctx, line)); } } - talloc_free(mem_ctx); + talloc_free(ctx); - return 0; + return (ret?0:1); } diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index d026d2824f..8d2460a93e 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. simple registry frontend - Copyright (C) Jelmer Vernooij 2004 + Copyright (C) Jelmer Vernooij 2004-2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,52 +20,66 @@ #include "includes.h" #include "lib/registry/registry.h" +#include "lib/registry/tools/common.h" #include "lib/events/events.h" #include "lib/cmdline/popt_common.h" -static void print_tree(int l, struct registry_key *p, int fullpath, int novals) +/** + * Print a registry key recursively + * + * @param level Level at which to print + * @param p Key to print + * @param fullpath Whether the full pat hshould be printed or just the last bit + * @param novals Whether values should not be printed + */ +static void print_tree(int level, struct registry_key *p, + const char *name, + bool fullpath, bool novals) { struct registry_key *subkey; - struct registry_value *value; + const char *valuename; + const char *keyname; + uint32_t value_type; + DATA_BLOB value_data; struct security_descriptor *sec_desc; WERROR error; int i; TALLOC_CTX *mem_ctx; - for(i = 0; i < l; i++) putchar(' '); - - /* Hive name */ - if(p->hive->root == p) { - if(p->hive->root->name) printf("%s\n", p->hive->root->name); else printf("\n"); - } else { - if(!p->name) printf("\n"); - if(fullpath) printf("%s\n", p->path); - else printf("%s\n", p->name?p->name:"(NULL)"); - } + for(i = 0; i < level; i++) putchar(' '); puts(name); mem_ctx = talloc_init("print_tree"); - for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(mem_ctx, p, i, &subkey)); i++) { - print_tree(l+1, subkey, fullpath, novals); + for (i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(mem_ctx, p, i, &keyname, NULL, NULL)); i++) { + SMB_ASSERT(strlen(keyname) > 0); + if (!W_ERROR_IS_OK(reg_open_key(mem_ctx, p, keyname, &subkey))) + continue; + print_tree(level+1, subkey, (fullpath && strlen(name))? + talloc_asprintf(mem_ctx, "%s\\%s", name, keyname): + keyname, fullpath, novals); } talloc_free(mem_ctx); if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while fetching subkeys for '%s': %s\n", p->path, win_errstr(error))); + DEBUG(0, ("Error occured while fetching subkeys for '%s': %s\n", + name, win_errstr(error))); } - if(!novals) { + if (!novals) { mem_ctx = talloc_init("print_tree"); - for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(mem_ctx, p, i, &value)); i++) { + for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(mem_ctx, + p, i, &valuename, &value_type, &value_data)); i++) { int j; char *desc; - for(j = 0; j < l+1; j++) putchar(' '); - desc = reg_val_description(mem_ctx, value); + for(j = 0; j < level+1; j++) putchar(' '); + desc = reg_val_description(mem_ctx, valuename, value_type, + value_data); printf("%s\n", desc); } talloc_free(mem_ctx); if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while fetching values for '%s': %s\n", p->path, win_errstr(error))); + DEBUG(0, ("Error occured while fetching values for '%s': %s\n", + name, win_errstr(error))); } } @@ -79,21 +93,22 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals) int main(int argc, char **argv) { int opt, i; - const char *backend = NULL; + const char *file = NULL; const char *remote = NULL; poptContext pc; struct registry_context *h = NULL; - struct registry_key *root = NULL; + struct registry_key *start_key = NULL; WERROR error; - int fullpath = 0, no_values = 0; + bool fullpath = false, no_values = false; struct poptOption long_options[] = { POPT_AUTOHELP - {"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL}, - {"fullpath", 'f', POPT_ARG_NONE, &fullpath, 0, "show full paths", NULL}, + {"file", 'F', POPT_ARG_STRING, &file, 0, "file path", NULL }, {"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL }, + {"fullpath", 'f', POPT_ARG_NONE, &fullpath, 0, "show full paths", NULL}, {"no-values", 'V', POPT_ARG_NONE, &no_values, 0, "don't show values", NULL}, POPT_COMMON_SAMBA POPT_COMMON_CREDENTIALS + POPT_COMMON_VERSION { NULL } }; @@ -102,48 +117,35 @@ int main(int argc, char **argv) while((opt = poptGetNextOpt(pc)) != -1) { } - registry_init(); - - if (remote) { - error = reg_open_remote(&h, NULL, cmdline_credentials, remote, NULL); - - if(!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Unable to open remote registry at %s:%s \n", remote, win_errstr(error)); - return 1; - } - - } else if (backend) { - error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, cmdline_credentials, &root); - - if(!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Unable to open '%s' with backend '%s':%s \n", poptGetArg(pc), backend, win_errstr(error)); - return 1; - } + if (remote != NULL) { + h = reg_common_open_remote(remote, cmdline_credentials); + } else if (file != NULL) { + start_key = reg_common_open_file(file, cmdline_credentials); } else { - error = reg_open_local (NULL, &h, NULL, cmdline_credentials); - - if(!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Unable to open local registry:%s \n", win_errstr(error)); - return 1; - } - + h = reg_common_open_local(cmdline_credentials); } + if (h == NULL && start_key == NULL) + return 1; + poptFreeContext(pc); error = WERR_OK; - if (root != NULL) { - print_tree(0, root, fullpath, no_values); + if (start_key != NULL) { + print_tree(0, start_key, "", fullpath, no_values); } else { for(i = 0; reg_predefined_keys[i].handle; i++) { - error = reg_get_predefined_key(h, reg_predefined_keys[i].handle, &root); + error = reg_get_predefined_key(h, reg_predefined_keys[i].handle, + &start_key); if (!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Skipping %s\n", reg_predefined_keys[i].name); + fprintf(stderr, "Skipping %s: %s\n", reg_predefined_keys[i].name, + win_errstr(error)); continue; } - SMB_ASSERT(root); - print_tree(0, root, fullpath, no_values); + SMB_ASSERT(start_key != NULL); + print_tree(0, start_key, reg_predefined_keys[i].name, fullpath, + no_values); } } diff --git a/source4/lib/registry/util.c b/source4/lib/registry/util.c new file mode 100644 index 0000000000..47716f89cf --- /dev/null +++ b/source4/lib/registry/util.c @@ -0,0 +1,242 @@ +/* + Unix SMB/CIFS implementation. + Transparent registry backend handling + Copyright (C) Jelmer Vernooij 2003-2007. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "lib/registry/registry.h" +#include "librpc/gen_ndr/winreg.h" + +/** + * @file + * @brief Registry utility functions + */ + +static const struct { + uint32_t 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 */ +_PUBLIC_ const char *str_regtype(int type) +{ + 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"; +} + +_PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, + const DATA_BLOB data) +{ + char *ret = NULL; + + if (data.length == 0) + return talloc_strdup(mem_ctx, ""); + + switch (type) { + case REG_EXPAND_SZ: + case REG_SZ: + convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, data.data, data.length, + (void **)&ret); + return ret; + + case REG_BINARY: + ret = data_blob_hex_string(mem_ctx, &data); + return ret; + + case REG_DWORD: + if (*(int *)data.data == 0) + return talloc_strdup(mem_ctx, "0"); + + return talloc_asprintf(mem_ctx, "0x%x", *(int *)data.data); + + case REG_MULTI_SZ: + /* FIXME */ + break; + + default: + break; + } + + return ret; +} + +/** Generate a string that describes a registry value */ +_PUBLIC_ char *reg_val_description(TALLOC_CTX *mem_ctx, const char *name, + uint32_t data_type, + const DATA_BLOB data) +{ + return talloc_asprintf(mem_ctx, "%s = %s : %s", name?name:"", + str_regtype(data_type), + reg_val_data_string(mem_ctx, data_type, data)); +} + +_PUBLIC_ BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data) +{ + int i; + *type = -1; + + /* Find the correct type */ + for (i = 0; reg_value_types[i].name; i++) { + if (!strcmp(reg_value_types[i].name, type_str)) { + *type = reg_value_types[i].id; + break; + } + } + + if (*type == -1) + return False; + + /* Convert data appropriately */ + + switch (*type) + { + case REG_SZ: + case REG_EXPAND_SZ: + data->length = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, data_str, strlen(data_str), (void **)&data->data); + break; + + case REG_DWORD: { + uint32_t tmp = strtol(data_str, NULL, 0); + *data = data_blob_talloc(mem_ctx, &tmp, 4); + } + break; + + case REG_NONE: + ZERO_STRUCTP(data); + break; + + case REG_BINARY: + *data = strhex_to_data_blob(data_str); + talloc_steal(mem_ctx, data->data); + break; + + default: + /* FIXME */ + return False; + } + return True; +} + +/** Open a key by name (including the predefined key name!) */ +WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result) +{ + struct registry_key *predef; + WERROR error; + int predeflength; + char *predefname; + + if (strchr(name, '\\') != NULL) + predeflength = strchr(name, '\\')-name; + else + predeflength = strlen(name); + + predefname = talloc_strndup(mem_ctx, name, predeflength); + error = reg_get_predefined_key_by_name(handle, predefname, &predef); + talloc_free(predefname); + + if (!W_ERROR_IS_OK(error)) { + return error; + } + + if (strchr(name, '\\')) { + return reg_open_key(mem_ctx, predef, strchr(name, '\\')+1, result); + } else { + *result = predef; + return WERR_OK; + } +} + +static WERROR get_abs_parent(TALLOC_CTX *mem_ctx, struct registry_context *ctx, + const char *path, struct registry_key **parent, + const char **name) +{ + char *parent_name; + WERROR error; + + if (strchr(path, '\\') == NULL) { + return WERR_FOOBAR; + } + + parent_name = talloc_strndup(mem_ctx, path, strrchr(path, '\\')-path); + + error = reg_open_key_abs(mem_ctx, ctx, parent_name, parent); + if (!W_ERROR_IS_OK(error)) { + return error; + } + + *name = talloc_strdup(mem_ctx, strrchr(path, '\\')+1); + + return WERR_OK; +} + +WERROR reg_key_del_abs(struct registry_context *ctx, const char *path) +{ + struct registry_key *parent; + const char *n; + TALLOC_CTX *mem_ctx = talloc_init("reg_key_del_abs"); + WERROR error; + + if (!strchr(path, '\\')) { + return WERR_FOOBAR; + } + + error = get_abs_parent(mem_ctx, ctx, path, &parent, &n); + if (W_ERROR_IS_OK(error)) { + error = reg_key_del(parent, n); + } + + talloc_free(mem_ctx); + + return error; +} + +WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx, + const char *path, uint32_t access_mask, + struct security_descriptor *sec_desc, + struct registry_key **result) +{ + struct registry_key *parent; + const char *n; + WERROR error; + + if (!strchr(path, '\\')) { + return WERR_ALREADY_EXISTS; + } + + error = get_abs_parent(mem_ctx, ctx, path, &parent, &n); + if (!W_ERROR_IS_OK(error)) { + DEBUG(2, ("Opening parent of %s failed with %s\n", path, + win_errstr(error))); + return error; + } + + error = reg_key_add_name(mem_ctx, parent, n, NULL, sec_desc, result); + + return error; +} diff --git a/source4/lib/registry/wine.c b/source4/lib/registry/wine.c new file mode 100644 index 0000000000..2cb0b9955e --- /dev/null +++ b/source4/lib/registry/wine.c @@ -0,0 +1,45 @@ +/* + Unix SMB/CIFS implementation. + Registry interface + Copyright (C) Jelmer Vernooij 2007. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "lib/registry/common/registry.h" +#include "windows/registry.h" + +static WERROR wine_open_reg (struct registry_hive *h, struct registry_key **key) +{ + /* FIXME: Open h->location and mmap it */ +} + +static REG_OPS reg_backend_wine = { + .name = "wine", + .open_hive = wine_open_reg, + +}; + +NTSTATUS registry_wine_init(void) +{ + register_backend("registry", ®_backend_wine); + return NT_STATUS_OK; +} + +WERROR reg_open_wine(struct registry_key **ctx) +{ + /* FIXME: Open ~/.wine/system.reg, etc */ + return WERR_NOT_SUPPORTED; +} -- cgit From ec180e2475bbdac03a3030f700d243799a4532a4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 26 Aug 2007 15:55:06 +0000 Subject: r24668: Fix header installation. (This used to be commit e9e66693505e5b9f136bd24f5f76ccd0ae574d99) --- source4/lib/registry/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index de276d2b5e..4e8a075dd3 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -43,7 +43,7 @@ PUBLIC_HEADERS = registry.h [SUBSYSTEM::registry_common] PUBLIC_DEPENDENCIES = registry OBJ_FILES = tools/common.o -PUBLIC_PROTO_HEADER = tools/common.h +PRIVATE_PROTO_HEADER = tools/common.h ################################################ # Start BINARY regdiff -- cgit From f96b1778a42d8388fd1c6384cd7c90b6e4bcd437 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 26 Aug 2007 19:58:40 +0000 Subject: r24674: Make sure results are always on a new line, fix typo in test name. (This used to be commit 40c1635b39b4acff0acecc734583daa0217215ce) --- source4/lib/registry/tests/registry.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 851f74fa3c..0fda7587dc 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -46,6 +46,22 @@ static bool test_get_predefined(struct torture_context *tctx, return true; } +/** + * Test obtaining a predefined key. + */ +static bool test_get_predefined_unknown(struct torture_context *tctx, + const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *root; + WERROR error; + + error = reg_get_predefined_key(rctx, 1337, &root); + torture_assert_werr_equal(tctx, error, WERR_BADFILE, + "getting predefined key failed"); + return true; +} + /** * Test creating a new subkey */ @@ -200,6 +216,9 @@ static bool test_flush_key(struct torture_context *tctx, const void *_data) error = reg_key_flush(subkey); torture_assert_werr_ok(tctx, error, "flush key"); + torture_assert_werr_equal(tctx, reg_key_flush(NULL), + WERR_INVALID_PARAM, "flush key"); + return true; } @@ -457,6 +476,8 @@ static void tcase_add_tests(struct torture_tcase *tcase) torture_tcase_add_simple_test(tcase, "list_subkeys", test_list_subkeys); torture_tcase_add_simple_test(tcase, "get_predefined_key", test_get_predefined); + torture_tcase_add_simple_test(tcase, "get_predefined_key", + test_get_predefined_unknown); torture_tcase_add_simple_test(tcase, "create_key", test_create_subkey); torture_tcase_add_simple_test(tcase, "create_key", test_create_nested_subkey); -- cgit From 3c9f28334c62167c80589b348c7662388342a922 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 26 Aug 2007 21:52:27 +0000 Subject: r24683: Add two more tests. (This used to be commit c87576743b09773489478e6eebeb3a282d6ec21b) --- source4/lib/registry/tests/generic.c | 2 ++ source4/lib/registry/tests/registry.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/generic.c b/source4/lib/registry/tests/generic.c index 6595f86b18..549ed6282d 100644 --- a/source4/lib/registry/tests/generic.c +++ b/source4/lib/registry/tests/generic.c @@ -101,6 +101,8 @@ static bool test_reg_val_description_nullname(struct torture_context *ctx) return true; } + + struct torture_suite *torture_registry(TALLOC_CTX *mem_ctx) { struct torture_suite *suite = torture_suite_create(mem_ctx, diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 0fda7587dc..2aab034ff3 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -57,6 +57,37 @@ static bool test_get_predefined_unknown(struct torture_context *tctx, WERROR error; error = reg_get_predefined_key(rctx, 1337, &root); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + "getting predefined key failed"); + return true; +} + +static bool test_predef_key_by_name(struct torture_context *tctx, + const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *root; + WERROR error; + + error = reg_get_predefined_key_by_name(rctx, "HKEY_CLASSES_ROOT", &root); + torture_assert_werr_ok(tctx, error, + "getting predefined key failed"); + + error = reg_get_predefined_key_by_name(rctx, "HKEY_classes_ROOT", &root); + torture_assert_werr_ok(tctx, error, + "getting predefined key case insensitively failed"); + + return true; +} + +static bool test_predef_key_by_name_invalid(struct torture_context *tctx, + const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *root; + WERROR error; + + error = reg_get_predefined_key_by_name(tctx, "BLA", &root); torture_assert_werr_equal(tctx, error, WERR_BADFILE, "getting predefined key failed"); return true; @@ -491,6 +522,10 @@ static void tcase_add_tests(struct torture_tcase *tcase) torture_tcase_add_simple_test(tcase, "flush_key", test_flush_key); torture_tcase_add_simple_test(tcase, "query_key", test_query_key); torture_tcase_add_simple_test(tcase, "query_key_nums", test_query_key_nums); + torture_tcase_add_simple_test(tcase, "test_predef_key_by_name", + test_predef_key_by_name); + torture_tcase_add_simple_test(tcase, "test_predef_key_by_name_invalid", + test_predef_key_by_name_invalid); } struct torture_suite *torture_registry_registry(TALLOC_CTX *mem_ctx) -- cgit From 6ca139026956916a4a956dd36d10d7f5a72272b8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 26 Aug 2007 22:12:02 +0000 Subject: r24684: Be a bit less verbose (This used to be commit 7a7af62dc4485d832436ed39dfba41b417ec2b10) --- source4/lib/registry/ldb.c | 4 ++-- source4/lib/registry/regf.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 8ee4d9f932..8a34fa7a54 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -295,11 +295,11 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL, &res); if (ret != LDB_SUCCESS) { - DEBUG(0, ("Error opening key '%s': %s\n", + DEBUG(3, ("Error opening key '%s': %s\n", ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); return WERR_FOOBAR; } else if (res->count == 0) { - DEBUG(0, ("Key '%s' not found\n", ldb_dn_get_linearized(ldap_path))); + DEBUG(3, ("Key '%s' not found\n", ldb_dn_get_linearized(ldap_path))); talloc_free(res); return WERR_NOT_FOUND; } diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 7fa71033d9..d74ffd2b4b 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -1303,7 +1303,7 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, } } if (!found_offset) { - DEBUG(0, ("Subkey not found\n")); + DEBUG(2, ("Subkey not found\n")); return WERR_NOT_FOUND; } li.key_count--; @@ -1345,7 +1345,7 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, } } if (!found_offset) { - DEBUG(0, ("Subkey not found\n")); + DEBUG(2, ("Subkey not found\n")); return WERR_NOT_FOUND; } lf.key_count--; @@ -1487,7 +1487,7 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name) /* Find the key */ if (!W_ERROR_IS_OK(regf_get_subkey_by_name(parent_nk, parent, name, (struct hive_key **)&key))) { - DEBUG(0, ("Key '%s' not found\n", name)); + DEBUG(2, ("Key '%s' not found\n", name)); return WERR_NOT_FOUND; } -- cgit From 2edf63b6d647eba131e213bd9dbc543100396930 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 27 Aug 2007 13:13:08 +0000 Subject: r24703: Use standard registry diff files when provisioning rather than LDIF files for the registry files. (This used to be commit 67ad556b7388e5d82756e0a3cfc596e44136329c) --- source4/lib/registry/hive.c | 2 ++ source4/lib/registry/patchfile.c | 4 +++- source4/lib/registry/samba.c | 5 +++++ 3 files changed, 10 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/hive.c b/source4/lib/registry/hive.c index b2c826b93d..97ce883e66 100644 --- a/source4/lib/registry/hive.c +++ b/source4/lib/registry/hive.c @@ -39,6 +39,8 @@ _PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, fd = open(location, O_RDWR); if (fd == -1) { + if (errno == ENOENT) + return WERR_NOT_FOUND; return WERR_BADFILE; } diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index 50c8f54397..8df873d56b 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -252,7 +252,9 @@ _PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1, /** * Load diff file */ -_PUBLIC_ WERROR reg_diff_load(const char *filename, const struct reg_diff_callbacks *callbacks, void *callback_data) +_PUBLIC_ WERROR reg_diff_load(const char *filename, + const struct reg_diff_callbacks *callbacks, + void *callback_data) { int fd; char hdr[4]; diff --git a/source4/lib/registry/samba.c b/source4/lib/registry/samba.c index 244c467a2c..6aaaa118d0 100644 --- a/source4/lib/registry/samba.c +++ b/source4/lib/registry/samba.c @@ -36,7 +36,12 @@ WERROR mount_samba_hive(struct registry_context *ctx, location = talloc_asprintf(ctx, "%s/%s.ldb", lp_private_dir(), name); + error = reg_open_hive(ctx, location, auth_info, creds, &hive); + + if (W_ERROR_EQUAL(error, WERR_NOT_FOUND)) + error = reg_open_ldb_file(ctx, location, auth_info, creds, &hive); + if (!W_ERROR_IS_OK(error)) return error; -- cgit From 349cc1e14b5d6c3225427f76c8703ab7537b6daa Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 27 Aug 2007 13:53:18 +0000 Subject: r24704: Fix bug in the registry patch code.. all the more proves this code needs tests. (This used to be commit aa98d219571c4a7af1e5a0f8483cc17a4b6b36e2) --- source4/lib/registry/patchfile_dotreg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/patchfile_dotreg.c b/source4/lib/registry/patchfile_dotreg.c index f11ceb1be0..1b4bffe819 100644 --- a/source4/lib/registry/patchfile_dotreg.c +++ b/source4/lib/registry/patchfile_dotreg.c @@ -211,7 +211,7 @@ _PUBLIC_ WERROR reg_dotreg_diff_load(int fd, const struct reg_diff_callbacks *ca } /* Delete value */ - if (strcmp(p, "-")) { + if (strcmp(p, "-") == 0) { error = callbacks->del_value(callback_data, curkey, line); if (!W_ERROR_IS_OK(error)) { DEBUG(0, ("Error deleting value %s in key %s\n", line, curkey)); -- cgit From 61ffa08f4c95e29d301de9fbabd6e71c2dbc1056 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 27 Aug 2007 18:10:19 +0000 Subject: r24712: No longer expose the 'BOOL' data type in any interfaces. (This used to be commit 1ce32673d960c8b05b6c1b1b99e1976a402417ae) --- source4/lib/registry/registry.h | 2 +- source4/lib/registry/util.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index acfe056616..ded5e4cc48 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -257,7 +257,7 @@ _PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, const DATA_BLOB data); _PUBLIC_ char *reg_val_description(TALLOC_CTX *mem_ctx, const char *name, uint32_t type, const DATA_BLOB data); -_PUBLIC_ BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data); +_PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data); WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result); WERROR reg_key_del_abs(struct registry_context *ctx, const char *path); WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx, const char *path, uint32_t access_mask, struct security_descriptor *sec_desc, struct registry_key **result); diff --git a/source4/lib/registry/util.c b/source4/lib/registry/util.c index 47716f89cf..6afd1bc44c 100644 --- a/source4/lib/registry/util.c +++ b/source4/lib/registry/util.c @@ -96,7 +96,7 @@ _PUBLIC_ char *reg_val_description(TALLOC_CTX *mem_ctx, const char *name, reg_val_data_string(mem_ctx, data_type, data)); } -_PUBLIC_ BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data) +_PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data) { int i; *type = -1; @@ -110,7 +110,7 @@ _PUBLIC_ BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const } if (*type == -1) - return False; + return false; /* Convert data appropriately */ @@ -138,9 +138,9 @@ _PUBLIC_ BOOL reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const default: /* FIXME */ - return False; + return false; } - return True; + return true; } /** Open a key by name (including the predefined key name!) */ -- cgit From ed8d04ead92839d54ca67f55a8e2be9723dc6b0d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 27 Aug 2007 18:43:18 +0000 Subject: r24717: Some more easy bool conversions, update TODO for registry (This used to be commit fc8771fb6aab815e63334da0159032f7ecd0a931) --- source4/lib/registry/TODO | 29 ----------------------------- 1 file changed, 29 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/TODO b/source4/lib/registry/TODO index 5f1e7d034b..b5809b84ed 100644 --- a/source4/lib/registry/TODO +++ b/source4/lib/registry/TODO @@ -1,34 +1,5 @@ - ..\..\, \bla\blie support in regshell - finish rpc_server -reg_backend_dir: - - value support - -reg_backend_creg.c: - - write support - -reg_backend_regf: - - write support - -reg_backend_rpc: - - value enum support - - write support - - rewrite - -reg_backend_ldb: - - finish - -reg_backend_wine.c: - - finish - regshell: - support for security descriptors - -gregedit.c: - - support for editing values / adding values / deleting values - - support for adding/deleting keys - - support for security descriptors - -- pass parsed paths around rather than strings (i.e. just a list of strings) -- integrate various registry tools ? -- finish new patchfile code -- cgit From 616c45f16a56527f54d428a7fbeabcc9952459f5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 27 Aug 2007 18:56:46 +0000 Subject: r24718: Fix some compiler warnings. (This used to be commit 08f7389ab7312d350e056b1ba98da86d80944424) --- source4/lib/registry/rpc.c | 17 +++++++++++++---- source4/lib/registry/tests/diff.c | 4 +--- source4/lib/registry/tests/registry.c | 2 +- 3 files changed, 15 insertions(+), 8 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/rpc.c b/source4/lib/registry/rpc.c index 59d41d591a..e4157fe424 100644 --- a/source4/lib/registry/rpc.c +++ b/source4/lib/registry/rpc.c @@ -90,7 +90,7 @@ static struct { static WERROR rpc_query_key(const struct registry_key *k); -static WERROR rpc_get_predefined_key(struct registry_context *ctx, +static WERROR rpc_get_predefined_key(const struct registry_context *ctx, uint32_t hkey_type, struct registry_key **k) { @@ -336,7 +336,8 @@ static WERROR rpc_del_key(struct registry_key *parent, const char *name) static WERROR rpc_get_info(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char **classname, uint32_t *numsubkeys, - uint32_t *numvalue) + uint32_t *numvalue, + NTTIME *last_changed_time) { struct rpc_key *mykeydata = talloc_get_type(key, struct rpc_key); WERROR error; @@ -347,8 +348,14 @@ static WERROR rpc_get_info(TALLOC_CTX *mem_ctx, const struct registry_key *key, } /* FIXME: *classname = talloc_strdup(mem_ctx, mykeydata->classname); */ - *numvalue = mykeydata->num_values; - *numsubkeys = mykeydata->num_subkeys; + /* FIXME: *last_changed_time = mykeydata->last_changed_time */ + + if (numvalue != NULL) + *numvalue = mykeydata->num_values; + + if (numsubkeys != NULL) + *numsubkeys = mykeydata->num_subkeys; + return WERR_OK; } @@ -360,6 +367,7 @@ static struct registry_operations reg_backend_rpc = { .create_key = rpc_add_key, .delete_key = rpc_del_key, .get_key_info = rpc_get_info, + .get_predefined_key = rpc_get_predefined_key, }; _PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, @@ -394,6 +402,7 @@ _PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, } *ctx = (struct registry_context *)rctx; + (*ctx)->ops = ®_backend_rpc; return WERR_OK; } diff --git a/source4/lib/registry/tests/diff.c b/source4/lib/registry/tests/diff.c index 220da88601..99a4589309 100644 --- a/source4/lib/registry/tests/diff.c +++ b/source4/lib/registry/tests/diff.c @@ -45,9 +45,7 @@ static bool test_diff_load(struct torture_context *test) static bool test_diff_apply(struct torture_context *test) { - /* -_PUBLIC_ WERROR reg_diff_apply (const char *filename, struct registry_context *ctx) - */ + /* _PUBLIC_ WERROR reg_diff_apply (const char *filename, struct registry_context *ctx) */ return true; } diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 2aab034ff3..dfc8e09d57 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -87,7 +87,7 @@ static bool test_predef_key_by_name_invalid(struct torture_context *tctx, struct registry_key *root; WERROR error; - error = reg_get_predefined_key_by_name(tctx, "BLA", &root); + error = reg_get_predefined_key_by_name(rctx, "BLA", &root); torture_assert_werr_equal(tctx, error, WERR_BADFILE, "getting predefined key failed"); return true; -- cgit From fb6adecf06d2a9ebd252cde2dde490e7b538bb0a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 27 Aug 2007 21:17:29 +0000 Subject: r24723: Install the right headers for use by samba-gtk. (This used to be commit 762e893d9ce4cc73bb1763a9520634bf921c0503) --- source4/lib/registry/config.mk | 2 +- source4/lib/registry/hive.h | 4 ++-- source4/lib/registry/patchfile.h | 8 +++---- source4/lib/registry/registry.h | 48 ++++++++++++++++++---------------------- 4 files changed, 29 insertions(+), 33 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 4e8a075dd3..670410ff6a 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -36,7 +36,7 @@ OBJ_FILES = \ PUBLIC_DEPENDENCIES = \ LIBSAMBA-UTIL CHARSET TDR_REGF LIBLDB \ RPC_NDR_WINREG -PUBLIC_HEADERS = registry.h +PUBLIC_HEADERS = registry.h hive.h patchfile.h # End MODULE registry_ldb ################################################ diff --git a/source4/lib/registry/hive.h b/source4/lib/registry/hive.h index 33759fdecc..ef44da373c 100644 --- a/source4/lib/registry/hive.h +++ b/source4/lib/registry/hive.h @@ -150,8 +150,8 @@ WERROR hive_key_get_info(TALLOC_CTX *mem_ctx, const struct hive_key *key, WERROR hive_key_add_name(TALLOC_CTX *ctx, const struct hive_key *parent_key, const char *name, const char *classname, struct security_descriptor *desc, struct hive_key **key); -_PUBLIC_ WERROR hive_key_del(const struct hive_key *key, const char *name); -_PUBLIC_ WERROR hive_get_key_by_name(TALLOC_CTX *mem_ctx, +WERROR hive_key_del(const struct hive_key *key, const char *name); +WERROR hive_get_key_by_name(TALLOC_CTX *mem_ctx, const struct hive_key *key, const char *name, struct hive_key **subkey); WERROR hive_enum_key(TALLOC_CTX *mem_ctx, diff --git a/source4/lib/registry/patchfile.h b/source4/lib/registry/patchfile.h index 194e2a132a..1c0b195a8c 100644 --- a/source4/lib/registry/patchfile.h +++ b/source4/lib/registry/patchfile.h @@ -34,16 +34,16 @@ struct reg_diff_callbacks { WERROR (*done) (void *callback_data); }; -_PUBLIC_ WERROR reg_diff_apply (const char *filename, +WERROR reg_diff_apply (const char *filename, struct registry_context *ctx); -_PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1, +WERROR reg_generate_diff(struct registry_context *ctx1, struct registry_context *ctx2, const struct reg_diff_callbacks *callbacks, void *callback_data); -_PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, +WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, struct reg_diff_callbacks **callbacks, void **callback_data); -_PUBLIC_ WERROR reg_generate_diff_key(struct registry_key *oldkey, +WERROR reg_generate_diff_key(struct registry_key *oldkey, struct registry_key *newkey, const char *path, const struct reg_diff_callbacks *callbacks, diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index ded5e4cc48..9839786e01 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -165,19 +165,15 @@ struct registry_context { struct auth_session_info; struct event_context; -#ifndef _PUBLIC_ -#define _PUBLIC_ -#endif - /** * Open the locally defined registry. */ -_PUBLIC_ WERROR reg_open_local (TALLOC_CTX *mem_ctx, +WERROR reg_open_local (TALLOC_CTX *mem_ctx, struct registry_context **ctx, struct auth_session_info *session_info, struct cli_credentials *credentials); -_PUBLIC_ WERROR reg_open_samba (TALLOC_CTX *mem_ctx, +WERROR reg_open_samba (TALLOC_CTX *mem_ctx, struct registry_context **ctx, struct auth_session_info *session_info, struct cli_credentials *credentials); @@ -185,36 +181,36 @@ _PUBLIC_ WERROR reg_open_samba (TALLOC_CTX *mem_ctx, /** * Open the registry on a remote machine. */ -_PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, +WERROR reg_open_remote(struct registry_context **ctx, struct auth_session_info *session_info, struct cli_credentials *credentials, const char *location, struct event_context *ev); -_PUBLIC_ WERROR reg_open_wine(struct registry_context **ctx, const char *path); +WERROR reg_open_wine(struct registry_context **ctx, const char *path); -_PUBLIC_ const char *reg_get_predef_name(uint32_t hkey); -_PUBLIC_ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, +const char *reg_get_predef_name(uint32_t hkey); +WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, const char *name, struct registry_key **key); -_PUBLIC_ WERROR reg_get_predefined_key(const struct registry_context *ctx, +WERROR reg_get_predefined_key(const struct registry_context *ctx, uint32_t hkey, struct registry_key **key); -_PUBLIC_ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, +WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, struct registry_key **result); -_PUBLIC_ WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, +WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *key, uint32_t idx, const char **name, uint32_t *type, DATA_BLOB *data); -_PUBLIC_ WERROR reg_key_get_info(TALLOC_CTX *mem_ctx, +WERROR reg_key_get_info(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char **class_name, uint32_t *num_subkeys, uint32_t *num_values, NTTIME *last_change_time); -_PUBLIC_ WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, +WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *key, int idx, const char **name, @@ -224,22 +220,22 @@ WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char *name, struct registry_key **subkey); -_PUBLIC_ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, +WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char *name, uint32_t *type, DATA_BLOB *data); -_PUBLIC_ WERROR reg_key_del(struct registry_key *parent, const char *name); -_PUBLIC_ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, +WERROR reg_key_del(struct registry_key *parent, const char *name); +WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, const char *classname, struct security_descriptor *desc, struct registry_key **newkey); -_PUBLIC_ WERROR reg_val_set(struct registry_key *key, const char *value, +WERROR reg_val_set(struct registry_key *key, const char *value, uint32_t type, DATA_BLOB data); -_PUBLIC_ WERROR reg_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, struct security_descriptor **secdesc); -_PUBLIC_ WERROR reg_del_value(struct registry_key *key, const char *valname); -_PUBLIC_ WERROR reg_key_flush(struct registry_key *key); +WERROR reg_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, struct security_descriptor **secdesc); +WERROR reg_del_value(struct registry_key *key, const char *valname); +WERROR reg_key_flush(struct registry_key *key); WERROR reg_create_key (TALLOC_CTX *mem_ctx, struct registry_key *parent, @@ -252,12 +248,12 @@ WERROR reg_create_key (TALLOC_CTX *mem_ctx, /* Utility functions */ -_PUBLIC_ const char *str_regtype(int type); -_PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, +const char *str_regtype(int type); +char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, const DATA_BLOB data); -_PUBLIC_ char *reg_val_description(TALLOC_CTX *mem_ctx, const char *name, +char *reg_val_description(TALLOC_CTX *mem_ctx, const char *name, uint32_t type, const DATA_BLOB data); -_PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data); +bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data); WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result); WERROR reg_key_del_abs(struct registry_context *ctx, const char *path); WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx, const char *path, uint32_t access_mask, struct security_descriptor *sec_desc, struct registry_key **result); -- cgit From 2cd9215e777820eec2cd6952aaa80c594facba32 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 27 Aug 2007 21:24:44 +0000 Subject: r24725: Don't segfault if hive file can't be found (This used to be commit 2daa8fa88dbc80a7c54c4b489b1037658d95755c) --- source4/lib/registry/tools/regshell.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 0887bc91f3..131d76fff5 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -481,6 +481,8 @@ int main(int argc, char **argv) ctx->registry = reg_common_open_remote(remote, cmdline_credentials); } else if (file != NULL) { ctx->current = reg_common_open_file(file, cmdline_credentials); + if (ctx->current == NULL) + return 1; ctx->registry = ctx->current->context; ctx->path = talloc_strdup(ctx, ""); } else { -- cgit From 5d518417f8dc64ce9bbfedc3ddb988d69961bde4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 27 Aug 2007 22:01:58 +0000 Subject: r24726: Add tests for getting/setting security descriptors (still failing at the moment) (This used to be commit ecdfaf56c09e75dc3ca37a3599c89661ad3485ff) --- source4/lib/registry/interface.c | 25 +++++++++++++++++++++++ source4/lib/registry/registry.h | 6 ++++++ source4/lib/registry/tests/registry.c | 37 +++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/interface.c b/source4/lib/registry/interface.c index 4d75e99f00..4950e1dacd 100644 --- a/source4/lib/registry/interface.c +++ b/source4/lib/registry/interface.c @@ -275,3 +275,28 @@ _PUBLIC_ WERROR reg_key_flush(struct registry_key *key) return key->context->ops->flush_key(key); } + +_PUBLIC_ WERROR reg_get_security(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + struct security_descriptor **security) +{ + if (key == NULL) + return WERR_INVALID_PARAM; + + if (key->context->ops->get_security == NULL) + return WERR_NOT_SUPPORTED; + + return key->context->ops->get_security(mem_ctx, key, security); +} + +_PUBLIC_ WERROR reg_set_security(struct registry_key *key, + struct security_descriptor *security) +{ + if (key == NULL) + return WERR_INVALID_PARAM; + + if (key->context->ops->set_security == NULL) + return WERR_NOT_SUPPORTED; + + return key->context->ops->set_security(key, security); +} diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 9839786e01..616bbb82dc 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -269,6 +269,12 @@ struct registry_key *reg_import_hive_key(struct registry_context *ctx, struct hive_key *hive, uint32_t predef_key, const char **elements); +WERROR reg_get_security(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + struct security_descriptor **security); + +WERROR reg_set_security(struct registry_key *key, + struct security_descriptor *security); #endif /* _REGISTRY_H */ diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index dfc8e09d57..fd2e98eac8 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -25,6 +25,7 @@ #include "lib/cmdline/popt_common.h" #include "torture/torture.h" #include "librpc/gen_ndr/winreg.h" +#include "libcli/security/security.h" #include "system/filesys.h" NTSTATUS torture_temp_dir(struct torture_context *tctx, const char *prefix, @@ -365,6 +366,40 @@ static bool test_set_value(struct torture_context *tctx, const void *_data) return true; } +/** + * Test getting/setting security descriptors + */ +static bool test_security(struct torture_context *tctx, const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *subkey = NULL, *root; + WERROR error; + uint32_t data = 42; + struct security_descriptor *osd, *nsd; + + if (!create_test_key(tctx, rctx, "Düsseldorf", &root, &subkey)) + return false; + + osd = security_descriptor_create(tctx, + NULL, NULL, + SID_NT_AUTHENTICATED_USERS, + SEC_ACE_TYPE_ACCESS_ALLOWED, + SEC_GENERIC_ALL, + SEC_ACE_FLAG_OBJECT_INHERIT, + NULL); + + error = reg_set_security(subkey, osd); + torture_assert_werr_ok(tctx, error, "setting security"); + + error = reg_get_security(tctx, subkey, &nsd); + torture_assert_werr_ok (tctx, error, "setting security"); + + torture_assert(tctx, security_descriptor_equal(osd, nsd), + "security descriptor changed!"); + + return true; +} + /** * Test getting a value */ @@ -524,6 +559,8 @@ static void tcase_add_tests(struct torture_tcase *tcase) torture_tcase_add_simple_test(tcase, "query_key_nums", test_query_key_nums); torture_tcase_add_simple_test(tcase, "test_predef_key_by_name", test_predef_key_by_name); + torture_tcase_add_simple_test(tcase, "security", + test_security); torture_tcase_add_simple_test(tcase, "test_predef_key_by_name_invalid", test_predef_key_by_name_invalid); } -- cgit From 82037a75eae9deaf6ec80b5ecc3bb89aab6e6dd8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 30 Aug 2007 23:15:12 +0000 Subject: r24814: Fix headers, trim core.h even more. (This used to be commit 9647f860bdd5c0a74583e886182bd041a45e7655) --- source4/lib/registry/hive.h | 3 +-- source4/lib/registry/registry.h | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/hive.h b/source4/lib/registry/hive.h index ef44da373c..36491f149b 100644 --- a/source4/lib/registry/hive.h +++ b/source4/lib/registry/hive.h @@ -21,8 +21,7 @@ #ifndef __REGISTRY_HIVE_H__ #define __REGISTRY_HIVE_H__ -#include "core.h" -#include "talloc.h" +#include #include "librpc/gen_ndr/security.h" /** diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 616bbb82dc..1d92a9edab 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -23,8 +23,7 @@ struct registry_context; -#include "core.h" -#include "talloc/talloc.h" +#include #include "librpc/gen_ndr/security.h" #include "lib/registry/hive.h" -- cgit From 033c2c07a3a080922a35cc674163b1768d0ff227 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 2 Sep 2007 16:17:12 +0000 Subject: r24898: Fix LOCAL-REGISTRY, do not silently ignore testcase setup failures. (This used to be commit 527ea7fccf4ace9cd9cbacf49820ecd208b8d570) --- source4/lib/registry/ldb.c | 3 +-- source4/lib/registry/tests/registry.c | 42 +++++++++++++---------------------- 2 files changed, 16 insertions(+), 29 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 8a34fa7a54..5ecbfa0407 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -327,8 +327,7 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, if (location == NULL) return WERR_INVALID_PARAM; - wrap = ldb_wrap_connect(parent_ctx, location, session_info, - credentials, 0, NULL); + wrap = ldb_wrap_connect(parent_ctx, location, session_info, credentials, 0, NULL); if (wrap == NULL) { DEBUG(1, (__FILE__": unable to connect\n")); diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index fd2e98eac8..9ac61b1bc0 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -132,7 +132,7 @@ static bool test_create_nested_subkey(struct torture_context *tctx, error = reg_key_add_name(rctx, root, "Hamburg", NULL, NULL, &newkey1); torture_assert_werr_ok(tctx, error, "Creating key return code"); - torture_assert(tctx, newkey2 != NULL, "Creating new key"); + torture_assert(tctx, newkey1 != NULL, "Creating new key"); error = reg_key_add_name(rctx, root, "Hamburg\\Hamburg", NULL, NULL, &newkey2); @@ -374,7 +374,6 @@ static bool test_security(struct torture_context *tctx, const void *_data) const struct registry_context *rctx = _data; struct registry_key *subkey = NULL, *root; WERROR error; - uint32_t data = 42; struct security_descriptor *osd, *nsd; if (!create_test_key(tctx, rctx, "Düsseldorf", &root, &subkey)) @@ -511,26 +510,20 @@ static bool setup_local_registry(struct torture_context *tctx, void **data) const char *tempdir; NTSTATUS status; struct hive_key *hive_key; + const char *filename; error = reg_open_local(tctx, &rctx, NULL, NULL); - if (!W_ERROR_IS_OK(error)) - return false; + torture_assert_werr_ok(tctx, error, "Opening local registry failed"); status = torture_temp_dir(tctx, "registry-local", &tempdir); - if (!NT_STATUS_IS_OK(status)) - return false; + torture_assert_ntstatus_ok(tctx, status, "Creating temp dir failed"); - error = reg_open_ldb_file(tctx, - talloc_asprintf(tctx, "%s/classes_root.ldb", tempdir), - NULL, - NULL, - &hive_key); - if (!W_ERROR_IS_OK(error)) - return false; + filename = talloc_asprintf(tctx, "%s/classes_root.ldb", tempdir); + error = reg_open_ldb_file(tctx, filename, NULL, NULL, &hive_key); + torture_assert_werr_ok(tctx, error, "Opening classes_root file failed"); error = reg_mount_hive(rctx, hive_key, HKEY_CLASSES_ROOT, NULL); - if (!W_ERROR_IS_OK(error)) - return false; + torture_assert_werr_ok(tctx, error, "Mounting hive failed"); *data = rctx; @@ -540,13 +533,10 @@ static bool setup_local_registry(struct torture_context *tctx, void **data) static void tcase_add_tests(struct torture_tcase *tcase) { torture_tcase_add_simple_test(tcase, "list_subkeys", test_list_subkeys); - torture_tcase_add_simple_test(tcase, "get_predefined_key", - test_get_predefined); - torture_tcase_add_simple_test(tcase, "get_predefined_key", - test_get_predefined_unknown); + torture_tcase_add_simple_test(tcase, "get_predefined_key", test_get_predefined); + torture_tcase_add_simple_test(tcase, "get_predefined_key", test_get_predefined_unknown); torture_tcase_add_simple_test(tcase, "create_key", test_create_subkey); - torture_tcase_add_simple_test(tcase, "create_key", - test_create_nested_subkey); + torture_tcase_add_simple_test(tcase, "create_key", test_create_nested_subkey); torture_tcase_add_simple_test(tcase, "key_add_abs", test_key_add_abs); torture_tcase_add_simple_test(tcase, "key_add_abs_top", test_key_add_abs_top); torture_tcase_add_simple_test(tcase, "set_value", test_set_value); @@ -558,18 +548,16 @@ static void tcase_add_tests(struct torture_tcase *tcase) torture_tcase_add_simple_test(tcase, "query_key", test_query_key); torture_tcase_add_simple_test(tcase, "query_key_nums", test_query_key_nums); torture_tcase_add_simple_test(tcase, "test_predef_key_by_name", - test_predef_key_by_name); - torture_tcase_add_simple_test(tcase, "security", - test_security); + test_predef_key_by_name); + torture_tcase_add_simple_test(tcase, "security", test_security); torture_tcase_add_simple_test(tcase, "test_predef_key_by_name_invalid", - test_predef_key_by_name_invalid); + test_predef_key_by_name_invalid); } struct torture_suite *torture_registry_registry(TALLOC_CTX *mem_ctx) { struct torture_tcase *tcase; - struct torture_suite *suite = torture_suite_create(mem_ctx, - "REGISTRY"); + struct torture_suite *suite = torture_suite_create(mem_ctx, "REGISTRY"); tcase = torture_suite_add_tcase(suite, "local"); torture_tcase_set_fixture(tcase, setup_local_registry, NULL); -- cgit From 6cf69fee189857ae6f85cd3f81a6a58364839942 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Sep 2007 13:31:15 +0000 Subject: r24994: Fix some C++ warnings. (This used to be commit 925abf74fa1ed5ae726bae8781ec549302786b39) --- source4/lib/registry/local.c | 4 ++-- source4/lib/registry/patchfile.c | 14 +++++++------- source4/lib/registry/patchfile_dotreg.c | 11 ++++++----- source4/lib/registry/patchfile_preg.c | 12 ++++++------ source4/lib/registry/samba.c | 2 +- source4/lib/registry/tools/common.c | 1 + 6 files changed, 23 insertions(+), 21 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index aefb11bde2..8ccb96cbdc 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -146,7 +146,7 @@ WERROR local_get_predefined_key (const struct registry_context *ctx, return WERR_OK; } -WERROR local_enum_key(TALLOC_CTX *mem_ctx, +static WERROR local_enum_key(TALLOC_CTX *mem_ctx, const struct registry_key *key, uint32_t idx, const char **name, const char **keyclass, @@ -169,7 +169,7 @@ static WERROR local_create_key (TALLOC_CTX *mem_ctx, struct hive_key *hivekey; const char **elements; int i; - char *last_part; + const char *last_part; last_part = strrchr(name, '\\'); if (last_part == NULL) { diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index 8df873d56b..99887c67bf 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -253,8 +253,8 @@ _PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1, * Load diff file */ _PUBLIC_ WERROR reg_diff_load(const char *filename, - const struct reg_diff_callbacks *callbacks, - void *callback_data) + const struct reg_diff_callbacks *callbacks, + void *callback_data) { int fd; char hdr[4]; @@ -295,7 +295,7 @@ _PUBLIC_ WERROR reg_diff_load(const char *filename, */ static WERROR reg_diff_apply_add_key(void *_ctx, const char *key_name) { - struct registry_context *ctx = _ctx; + struct registry_context *ctx = (struct registry_context *)_ctx; struct registry_key *tmp; WERROR error; @@ -310,7 +310,7 @@ static WERROR reg_diff_apply_add_key(void *_ctx, const char *key_name) static WERROR reg_diff_apply_del_key(void *_ctx, const char *key_name) { - struct registry_context *ctx = _ctx; + struct registry_context *ctx = (struct registry_context *)_ctx; WERROR error; error = reg_key_del_abs(ctx, key_name); @@ -325,7 +325,7 @@ static WERROR reg_diff_apply_del_key(void *_ctx, const char *key_name) static WERROR reg_diff_apply_set_value(void *_ctx, const char *path, const char *value_name, uint32_t value_type, DATA_BLOB value) { - struct registry_context *ctx = _ctx; + struct registry_context *ctx = (struct registry_context *)_ctx; struct registry_key *tmp; WERROR error; @@ -350,7 +350,7 @@ static WERROR reg_diff_apply_set_value(void *_ctx, const char *path, const char static WERROR reg_diff_apply_del_value (void *_ctx, const char *key_name, const char *value_name) { - struct registry_context *ctx = _ctx; + struct registry_context *ctx = (struct registry_context *)_ctx; struct registry_key *tmp; WERROR error; @@ -374,7 +374,7 @@ static WERROR reg_diff_apply_del_value (void *_ctx, const char *key_name, const static WERROR reg_diff_apply_del_all_values(void *_ctx, const char *key_name) { - struct registry_context *ctx = _ctx; + struct registry_context *ctx = (struct registry_context *)_ctx; struct registry_key *key; WERROR error; int i; diff --git a/source4/lib/registry/patchfile_dotreg.c b/source4/lib/registry/patchfile_dotreg.c index 1b4bffe819..32b70d2144 100644 --- a/source4/lib/registry/patchfile_dotreg.c +++ b/source4/lib/registry/patchfile_dotreg.c @@ -40,7 +40,7 @@ struct dotreg_data { static WERROR reg_dotreg_diff_add_key(void *_data, const char *key_name) { - struct dotreg_data *data = _data; + struct dotreg_data *data = (struct dotreg_data *)_data; fdprintf(data->fd, "\n[%s]\n", key_name); @@ -49,7 +49,7 @@ static WERROR reg_dotreg_diff_add_key(void *_data, const char *key_name) static WERROR reg_dotreg_diff_del_key(void *_data, const char *key_name) { - struct dotreg_data *data = _data; + struct dotreg_data *data = (struct dotreg_data *)_data; fdprintf(data->fd, "\n[-%s]\n", key_name); @@ -59,7 +59,7 @@ static WERROR reg_dotreg_diff_del_key(void *_data, const char *key_name) static WERROR reg_dotreg_diff_set_value(void *_data, const char *path, const char *value_name, uint32_t value_type, DATA_BLOB value) { - struct dotreg_data *data = _data; + struct dotreg_data *data = (struct dotreg_data *)_data; fdprintf(data->fd, "\"%s\"=%s:%s\n", value_name, str_regtype(value_type), @@ -70,7 +70,7 @@ static WERROR reg_dotreg_diff_set_value(void *_data, const char *path, static WERROR reg_dotreg_diff_del_value(void *_data, const char *path, const char *value_name) { - struct dotreg_data *data = _data; + struct dotreg_data *data = (struct dotreg_data *)_data; fdprintf(data->fd, "\"%s\"=-\n", value_name); @@ -130,7 +130,8 @@ _PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, /** * Load diff file */ -_PUBLIC_ WERROR reg_dotreg_diff_load(int fd, const struct reg_diff_callbacks *callbacks, void *callback_data) +_PUBLIC_ WERROR reg_dotreg_diff_load(int fd, + const struct reg_diff_callbacks *callbacks, void *callback_data) { char *line, *p, *q; char *curkey = NULL; diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c index 1c8d76538a..993de19f98 100644 --- a/source4/lib/registry/patchfile_preg.c +++ b/source4/lib/registry/patchfile_preg.c @@ -42,37 +42,37 @@ static WERROR preg_read_utf16(int fd, char *c) /* FIXME These functions need to be implemented */ static WERROR reg_preg_diff_add_key(void *_data, const char *key_name) { - struct preg_data *data = _data; + struct preg_data *data = (struct preg_data *)_data; return WERR_OK; } static WERROR reg_preg_diff_del_key(void *_data, const char *key_name) { - struct preg_data *data = _data; + struct preg_data *data = (struct preg_data *)_data; return WERR_OK; } static WERROR reg_preg_diff_set_value(void *_data, const char *key_name, const char *value_name, uint32_t value_type, DATA_BLOB value_data) { - struct preg_data *data = _data; + struct preg_data *data = (struct preg_data *)_data; return WERR_OK; } static WERROR reg_preg_diff_del_value(void *_data, const char *key_name, const char *value_name) { - struct preg_data *data = _data; + struct preg_data *data = (struct preg_data *)_data; return WERR_OK; } static WERROR reg_preg_diff_del_all_values(void *_data, const char *key_name) { - struct preg_data *data = _data; + struct preg_data *data = (struct preg_data *)_data; return WERR_OK; } static WERROR reg_preg_diff_done(void *_data) { - struct preg_data *data = _data; + struct preg_data *data = (struct preg_data *)_data; close(data->fd); talloc_free(data); diff --git a/source4/lib/registry/samba.c b/source4/lib/registry/samba.c index 6aaaa118d0..a5d6f76459 100644 --- a/source4/lib/registry/samba.c +++ b/source4/lib/registry/samba.c @@ -24,7 +24,7 @@ * @brief Samba-specific registry functions */ -WERROR mount_samba_hive(struct registry_context *ctx, +static WERROR mount_samba_hive(struct registry_context *ctx, struct auth_session_info *auth_info, struct cli_credentials *creds, const char *name, diff --git a/source4/lib/registry/tools/common.c b/source4/lib/registry/tools/common.c index c8b0945c2c..aa11eccbee 100644 --- a/source4/lib/registry/tools/common.c +++ b/source4/lib/registry/tools/common.c @@ -21,6 +21,7 @@ #include "includes.h" #include "auth/credentials/credentials.h" #include "lib/registry/registry.h" +#include "lib/registry/tools/common.h" struct registry_context *reg_common_open_remote(const char *remote, struct cli_credentials *creds) { -- cgit From cd962355abad90a2161765a7be7d26e63572cab7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Sep 2007 15:08:14 +0000 Subject: r25000: Fix some more C++ compatibility warnings. (This used to be commit 08bb1ef643ab906f1645cf6f32763dc73b1884e4) --- source4/lib/registry/local.c | 5 ++--- source4/lib/registry/patchfile_preg.c | 1 + source4/lib/registry/regf.c | 2 +- source4/lib/registry/tools/regshell.c | 6 ++---- 4 files changed, 6 insertions(+), 8 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index 8ccb96cbdc..035d556abf 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -139,9 +139,8 @@ WERROR local_get_predefined_key (const struct registry_context *ctx, return WERR_NOT_FOUND; *key = reg_import_hive_key(ctx, mp->key, - mp->path.predefined_key, - mp->path.elements - ); + mp->path.predefined_key, + mp->path.elements); return WERR_OK; } diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c index 993de19f98..ccabf4ca07 100644 --- a/source4/lib/registry/patchfile_preg.c +++ b/source4/lib/registry/patchfile_preg.c @@ -21,6 +21,7 @@ #include "includes.h" #include "lib/registry/registry.h" +#include "lib/registry/patchfile.h" #include "system/filesys.h" #include "pstring.h" diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index d74ffd2b4b..0c40773daa 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -1664,7 +1664,7 @@ static WERROR regf_set_value(struct hive_key *key, const char *name, DATA_BLOB value_list; value_list.length = (nk->num_values+1)*4; - value_list.data = (void *)talloc_array(private_data, uint32_t, nk->num_values+1); + value_list.data = talloc_array(private_data, uint32_t, nk->num_values+1); W_ERROR_HAVE_NO_MEMORY(value_list.data); memcpy(value_list.data, values.data, nk->num_values * 4); diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 131d76fff5..cdf688b39e 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -262,8 +262,7 @@ static WERROR cmd_rmval(struct regshell_context *ctx, int argc, char **argv) return WERR_OK; } -static WERROR cmd_exit(struct regshell_context *ctx, - int argc, char **argv) +_NORETURN_ static WERROR cmd_exit(struct regshell_context *ctx, int argc, char **argv) { exit(0); return WERR_OK; @@ -275,8 +274,7 @@ static struct { const char *name; const char *alias; const char *help; - WERROR (*handle)(struct regshell_context *ctx, - int argc, char **argv); + WERROR (*handle)(struct regshell_context *ctx, int argc, char **argv); } regshell_cmds[] = { {"ck", "cd", "Change current key", cmd_ck }, {"info", "i", "Show detailed information of a key", cmd_info }, -- cgit From 959915a8cbea0c598ef1f29ce666329a521ef2f6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Sep 2007 15:35:18 +0000 Subject: r25001: Fix more C++ and other warnings, fix some of the indentation with ts=4 lines that I accidently added earlier. (This used to be commit 0bcb21ed740fcec0f48ad36bbc2deee2948e8fc7) --- source4/lib/registry/patchfile_dotreg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/patchfile_dotreg.c b/source4/lib/registry/patchfile_dotreg.c index 32b70d2144..85cf8ab251 100644 --- a/source4/lib/registry/patchfile_dotreg.c +++ b/source4/lib/registry/patchfile_dotreg.c @@ -79,7 +79,7 @@ static WERROR reg_dotreg_diff_del_value(void *_data, const char *path, const cha static WERROR reg_dotreg_diff_done(void *_data) { - struct dotreg_data *data = _data; + struct dotreg_data *data = (struct dotreg_data *)_data; close(data->fd); talloc_free(data); -- cgit From ffeee68e4b72dd94fee57366bd8d38b8c284c3d4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Sep 2007 12:42:09 +0000 Subject: r25026: Move param/param.h out of includes.h (This used to be commit abe8349f9b4387961ff3665d8c589d61cd2edf31) --- source4/lib/registry/samba.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/samba.c b/source4/lib/registry/samba.c index a5d6f76459..dfb69abb33 100644 --- a/source4/lib/registry/samba.c +++ b/source4/lib/registry/samba.c @@ -18,6 +18,7 @@ #include "includes.h" #include "registry.h" +#include "param/param.h" /** * @file -- cgit From 98b57d5eb61094a9c88e2f7d90d3e21b7e74e9d8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Sep 2007 16:46:30 +0000 Subject: r25035: Fix some more warnings, use service pointer rather than service number in more places. (This used to be commit df9cebcb97e20564359097148665bd519f31bc6f) --- source4/lib/registry/tests/hive.c | 24 ++++++++--------- source4/lib/registry/tests/registry.c | 51 +++++++++++++++++++++++------------ 2 files changed, 46 insertions(+), 29 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index a04bc1168e..a71e31474c 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -31,9 +31,9 @@ NTSTATUS torture_temp_dir(struct torture_context *tctx, const char *prefix, const char **tempdir); static bool test_del_nonexistant_key(struct torture_context *tctx, - const void *test_data) + const void *test_data) { - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; WERROR error = hive_key_del(root, "bla"); torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "invalid return code"); @@ -45,7 +45,7 @@ static bool test_keyinfo_root(struct torture_context *tctx, const void *test_data) { uint32_t num_subkeys, num_values; - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; WERROR error; /* This is a new backend. There should be no subkeys and no @@ -67,7 +67,7 @@ static bool test_keyinfo_nums(struct torture_context *tctx, const void *test_data) { uint32_t num_subkeys, num_values; - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; WERROR error; struct hive_key *subkey; uint32_t data = 42; @@ -100,7 +100,7 @@ static bool test_add_subkey(struct torture_context *tctx, { WERROR error; struct hive_key *subkey; - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; error = hive_key_add_name(mem_ctx, root, "Nested Key", NULL, @@ -114,9 +114,9 @@ static bool test_add_subkey(struct torture_context *tctx, } static bool test_flush_key(struct torture_context *tctx, - const void *test_data) + const void *test_data) { - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; torture_assert_werr_ok(tctx, hive_key_flush(root), "flush key"); @@ -127,7 +127,7 @@ static bool test_del_key(struct torture_context *tctx, const void *test_data) { WERROR error; struct hive_key *subkey; - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; error = hive_key_add_name(mem_ctx, root, "Nested Key", NULL, @@ -148,7 +148,7 @@ static bool test_set_value(struct torture_context *tctx, { WERROR error; struct hive_key *subkey; - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; uint32_t data = 42; @@ -167,7 +167,7 @@ static bool test_get_value(struct torture_context *tctx, const void *test_data) { WERROR error; struct hive_key *subkey; - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; uint32_t data = 42; uint32_t type; @@ -200,7 +200,7 @@ static bool test_del_value(struct torture_context *tctx, const void *test_data) { WERROR error; struct hive_key *subkey; - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; uint32_t data = 42; uint32_t type; @@ -231,7 +231,7 @@ static bool test_list_values(struct torture_context *tctx, { WERROR error; struct hive_key *subkey; - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; uint32_t data = 42; uint32_t type; diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 9ac61b1bc0..9809a6d4c8 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -37,7 +37,8 @@ NTSTATUS torture_temp_dir(struct torture_context *tctx, const char *prefix, static bool test_get_predefined(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root; WERROR error; @@ -66,7 +67,8 @@ static bool test_get_predefined_unknown(struct torture_context *tctx, static bool test_predef_key_by_name(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root; WERROR error; @@ -84,7 +86,8 @@ static bool test_predef_key_by_name(struct torture_context *tctx, static bool test_predef_key_by_name_invalid(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root; WERROR error; @@ -100,7 +103,8 @@ static bool test_predef_key_by_name_invalid(struct torture_context *tctx, static bool test_create_subkey(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root, *newkey; WERROR error; @@ -121,7 +125,8 @@ static bool test_create_subkey(struct torture_context *tctx, static bool test_create_nested_subkey(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root, *newkey1, *newkey2; WERROR error; @@ -148,7 +153,8 @@ static bool test_create_nested_subkey(struct torture_context *tctx, static bool test_key_add_abs_top(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root; WERROR error; @@ -165,7 +171,8 @@ static bool test_key_add_abs(struct torture_context *tctx, const void *_data) { WERROR error; - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root, *result1, *result2; error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT\\bloe", 0, NULL, &result1); @@ -190,7 +197,8 @@ static bool test_key_add_abs(struct torture_context *tctx, static bool test_del_key(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root, *newkey; WERROR error; @@ -238,7 +246,8 @@ static bool create_test_key(struct torture_context *tctx, static bool test_flush_key(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root, *subkey; WERROR error; @@ -256,7 +265,8 @@ static bool test_flush_key(struct torture_context *tctx, const void *_data) static bool test_query_key(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root, *subkey; WERROR error; NTTIME last_changed_time; @@ -280,7 +290,8 @@ static bool test_query_key(struct torture_context *tctx, const void *_data) static bool test_query_key_nums(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root, *subkey1, *subkey2; WERROR error; uint32_t num_subkeys, num_values; @@ -313,7 +324,8 @@ static bool test_query_key_nums(struct torture_context *tctx, const void *_data) */ static bool test_list_subkeys(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; NTTIME last_mod_time; @@ -351,7 +363,8 @@ static bool test_list_subkeys(struct torture_context *tctx, const void *_data) */ static bool test_set_value(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; uint32_t data = 42; @@ -371,7 +384,8 @@ static bool test_set_value(struct torture_context *tctx, const void *_data) */ static bool test_security(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; struct security_descriptor *osd, *nsd; @@ -404,7 +418,8 @@ static bool test_security(struct torture_context *tctx, const void *_data) */ static bool test_get_value(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; DATA_BLOB data; @@ -439,7 +454,8 @@ static bool test_get_value(struct torture_context *tctx, const void *_data) */ static bool test_del_value(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; DATA_BLOB data; @@ -473,7 +489,8 @@ static bool test_del_value(struct torture_context *tctx, const void *_data) */ static bool test_list_values(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; DATA_BLOB data; -- cgit From 7e297ecfa4db2c7ab720a63c7764bc0e20f8058c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 9 Sep 2007 19:34:30 +0000 Subject: r25047: Fix more warnings. (This used to be commit 69de86d2d2e49439760fbc61901eb87fb7fc5d55) --- source4/lib/registry/local.c | 3 ++- source4/lib/registry/patchfile_preg.c | 3 +-- source4/lib/registry/regf.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index 035d556abf..1a45c0a70a 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -126,7 +126,8 @@ static WERROR local_open_key(TALLOC_CTX *mem_ctx, WERROR local_get_predefined_key (const struct registry_context *ctx, uint32_t key_id, struct registry_key **key) { - struct registry_local *rctx = talloc_get_type(ctx, struct registry_local); + struct registry_local *rctx = talloc_get_type(ctx, + struct registry_local); struct mountpoint *mp; for (mp = rctx->mountpoints; mp != NULL; mp = mp->next) { diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c index ccabf4ca07..20bd2fad0d 100644 --- a/source4/lib/registry/patchfile_preg.c +++ b/source4/lib/registry/patchfile_preg.c @@ -211,8 +211,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *call close(fd); return WERR_GENERAL_FAILURE; } - data.length = length; - data.data = talloc_memdup(mem_ctx, buf, length); + data = data_blob_talloc(mem_ctx, buf, length); /* Check if delimiter is in place (whine if it isn't) */ buf_ptr = buf; diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 0c40773daa..17914a8f7c 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -1664,7 +1664,7 @@ static WERROR regf_set_value(struct hive_key *key, const char *name, DATA_BLOB value_list; value_list.length = (nk->num_values+1)*4; - value_list.data = talloc_array(private_data, uint32_t, nk->num_values+1); + value_list.data = (uint8_t *)talloc_array(private_data, uint32_t, nk->num_values+1); W_ERROR_HAVE_NO_MEMORY(value_list.data); memcpy(value_list.data, values.data, nk->num_values * 4); -- cgit From ab309ada8ba2e4ef867f7fdb13012d09cb8d05c9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Sep 2007 07:29:29 +0000 Subject: r25112: make torture_temp_dir() available via tortore/torture.h and return more detailed errors metze (This used to be commit c2b645c8763fd75a0a81983ec44a5990670c4fc4) --- source4/lib/registry/tests/hive.c | 3 --- source4/lib/registry/tests/registry.c | 3 --- 2 files changed, 6 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index a71e31474c..dff6d1e829 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -27,9 +27,6 @@ #include "librpc/gen_ndr/winreg.h" #include "system/filesys.h" -NTSTATUS torture_temp_dir(struct torture_context *tctx, const char *prefix, - const char **tempdir); - static bool test_del_nonexistant_key(struct torture_context *tctx, const void *test_data) { diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 9809a6d4c8..962c7fd2b5 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -28,9 +28,6 @@ #include "libcli/security/security.h" #include "system/filesys.h" -NTSTATUS torture_temp_dir(struct torture_context *tctx, const char *prefix, - const char **tempdir); - /** * Test obtaining a predefined key. */ -- cgit From ffbb7e40604b9cffeb0c226279b929497b03a964 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 16 Sep 2007 19:14:46 +0000 Subject: r25193: Update headers to easy use by external apps. (This used to be commit 20b70fbb7af6b6759c3b8c8aa56e10944b32bfdf) --- source4/lib/registry/hive.h | 1 + source4/lib/registry/interface.c | 8 +++----- source4/lib/registry/local.c | 8 ++++---- source4/lib/registry/registry.h | 1 + source4/lib/registry/util.c | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/hive.h b/source4/lib/registry/hive.h index 36491f149b..8214208870 100644 --- a/source4/lib/registry/hive.h +++ b/source4/lib/registry/hive.h @@ -23,6 +23,7 @@ #include #include "librpc/gen_ndr/security.h" +#include "libcli/util/nt_status.h" /** * This file contains the hive API. This API is generally used for diff --git a/source4/lib/registry/interface.c b/source4/lib/registry/interface.c index 4950e1dacd..98c72c7940 100644 --- a/source4/lib/registry/interface.c +++ b/source4/lib/registry/interface.c @@ -104,11 +104,9 @@ _PUBLIC_ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, * Get value by index */ _PUBLIC_ WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - uint32_t idx, - const char **name, - uint32_t *type, - DATA_BLOB *data) + const struct registry_key *key, + uint32_t idx, const char **name, + uint32_t *type, DATA_BLOB *data) { if (key == NULL) return WERR_INVALID_PARAM; diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index 1a45c0a70a..a52feaaed5 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -49,10 +49,10 @@ struct local_key { }; -struct registry_key *reg_import_hive_key(struct registry_context *ctx, - struct hive_key *hive, - uint32_t predefined_key, - const char **elements) +struct registry_key *reg_import_hive_key(struct registry_context *ctx, + struct hive_key *hive, + uint32_t predefined_key, + const char **elements) { struct local_key *local_key; struct reg_key_path parent_path; diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 1d92a9edab..90dd094eb9 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -26,6 +26,7 @@ struct registry_context; #include #include "librpc/gen_ndr/security.h" #include "lib/registry/hive.h" +#include "libcli/util/nt_status.h" /* Handles for the predefined keys */ #define HKEY_CLASSES_ROOT 0x80000000 diff --git a/source4/lib/registry/util.c b/source4/lib/registry/util.c index 6afd1bc44c..78b578d2e5 100644 --- a/source4/lib/registry/util.c +++ b/source4/lib/registry/util.c @@ -51,7 +51,7 @@ _PUBLIC_ const char *str_regtype(int type) } _PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, - const DATA_BLOB data) + const DATA_BLOB data) { char *ret = NULL; -- cgit From 9b009c900987517359485799be8be4167494b376 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 Sep 2007 21:35:03 +0000 Subject: r25301: Merge my includes.h cleanups. (This used to be commit 37425495f392a2d0122a93aa2c42758eab7dab5a) --- source4/lib/registry/hive.h | 2 +- source4/lib/registry/registry.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/hive.h b/source4/lib/registry/hive.h index 8214208870..5a5356dfd2 100644 --- a/source4/lib/registry/hive.h +++ b/source4/lib/registry/hive.h @@ -23,7 +23,7 @@ #include #include "librpc/gen_ndr/security.h" -#include "libcli/util/nt_status.h" +#include "libcli/util/ntstatus.h" /** * This file contains the hive API. This API is generally used for diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 90dd094eb9..6dec84ad89 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -26,7 +26,7 @@ struct registry_context; #include #include "librpc/gen_ndr/security.h" #include "lib/registry/hive.h" -#include "libcli/util/nt_status.h" +#include "libcli/util/ntstatus.h" /* Handles for the predefined keys */ #define HKEY_CLASSES_ROOT 0x80000000 -- cgit From 37d53832a4623653f706e77985a79d84bd7c6694 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 28 Sep 2007 01:17:46 +0000 Subject: r25398: Parse loadparm context to all lp_*() functions. (This used to be commit 3fcc960839c6e5ca4de2c3c042f12f369ac5f238) --- source4/lib/registry/samba.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/samba.c b/source4/lib/registry/samba.c index dfb69abb33..48eb043306 100644 --- a/source4/lib/registry/samba.c +++ b/source4/lib/registry/samba.c @@ -35,7 +35,7 @@ static WERROR mount_samba_hive(struct registry_context *ctx, struct hive_key *hive; const char *location; - location = talloc_asprintf(ctx, "%s/%s.ldb", lp_private_dir(), name); + location = talloc_asprintf(ctx, "%s/%s.ldb", lp_private_dir(global_loadparm), name); error = reg_open_hive(ctx, location, auth_info, creds, &hive); -- cgit From 2f3551ca7cee59d4d053cceb87abdf1da1b3a1ad Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 1 Oct 2007 18:52:55 +0000 Subject: r25446: Merge some changes I made on the way home from SFO: 2007-09-29 More higher-level passing around of lp_ctx. 2007-09-29 Fix warning. 2007-09-29 Pass loadparm contexts on a higher level. 2007-09-29 Avoid using global loadparm context. (This used to be commit 3468952e771ab31f90b6c374ade01c5550810f42) --- source4/lib/registry/ldb.c | 10 ++++++---- source4/lib/registry/samba.c | 10 +++++----- 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 5ecbfa0407..e9daf31f9b 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -23,6 +23,7 @@ #include "lib/ldb/include/ldb_errors.h" #include "db_wrap.h" #include "librpc/gen_ndr/winreg.h" +#include "param/param.h" static struct hive_operations reg_backend_ldb; @@ -317,9 +318,9 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, } WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - struct hive_key **k) + struct auth_session_info *session_info, + struct cli_credentials *credentials, + struct hive_key **k) { struct ldb_key_data *kd; struct ldb_context *wrap; @@ -327,7 +328,8 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, if (location == NULL) return WERR_INVALID_PARAM; - wrap = ldb_wrap_connect(parent_ctx, location, session_info, credentials, 0, NULL); + wrap = ldb_wrap_connect(parent_ctx, global_loadparm, + location, session_info, credentials, 0, NULL); if (wrap == NULL) { DEBUG(1, (__FILE__": unable to connect\n")); diff --git a/source4/lib/registry/samba.c b/source4/lib/registry/samba.c index 48eb043306..18bbcb8299 100644 --- a/source4/lib/registry/samba.c +++ b/source4/lib/registry/samba.c @@ -25,11 +25,11 @@ * @brief Samba-specific registry functions */ -static WERROR mount_samba_hive(struct registry_context *ctx, - struct auth_session_info *auth_info, - struct cli_credentials *creds, - const char *name, - uint32_t hive_id) +static WERROR mount_samba_hive(struct registry_context *ctx, + struct auth_session_info *auth_info, + struct cli_credentials *creds, + const char *name, + uint32_t hive_id) { WERROR error; struct hive_key *hive; -- cgit From cc8f4eb3cd9b3bc4e3f3d61bfad240147e8a4e5e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 6 Oct 2007 00:17:44 +0000 Subject: r25544: Cleanup some more indents in lib/registry. Guenther (This used to be commit 0d9826dc54057db2cfebcb806e5442c4dcf60daa) --- source4/lib/registry/dir.c | 116 ++--- source4/lib/registry/hive.c | 77 ++-- source4/lib/registry/hive.h | 167 ++++---- source4/lib/registry/interface.c | 148 +++---- source4/lib/registry/ldb.c | 154 ++++--- source4/lib/registry/local.c | 188 +++++---- source4/lib/registry/patchfile.c | 219 +++++----- source4/lib/registry/patchfile.h | 47 ++- source4/lib/registry/patchfile_dotreg.c | 70 ++-- source4/lib/registry/patchfile_preg.c | 86 ++-- source4/lib/registry/regf.c | 722 ++++++++++++++++++-------------- source4/lib/registry/registry.h | 291 ++++++------- source4/lib/registry/rpc.c | 175 ++++---- source4/lib/registry/samba.c | 42 +- source4/lib/registry/util.c | 131 +++--- source4/lib/registry/wine.c | 10 +- 16 files changed, 1437 insertions(+), 1206 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/dir.c b/source4/lib/registry/dir.c index 146c5197fd..532770bcaf 100644 --- a/source4/lib/registry/dir.c +++ b/source4/lib/registry/dir.c @@ -1,18 +1,18 @@ -/* +/* Unix SMB/CIFS implementation. Registry interface - Copyright (C) Jelmer Vernooij 2004-2007. - + Copyright (C) Jelmer Vernooij 2004-2007. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -29,11 +29,11 @@ struct dir_key { static struct hive_operations reg_backend_dir; -static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx, - const struct hive_key *parent, - const char *name, const char *classname, - struct security_descriptor *desc, - struct hive_key **result) +static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx, + const struct hive_key *parent, + const char *name, const char *classname, + struct security_descriptor *desc, + struct hive_key **result) { struct dir_key *dk = talloc_get_type(parent, struct dir_key); char *path; @@ -61,8 +61,8 @@ static WERROR reg_dir_del_key(const struct hive_key *k, const char *name) char *child = talloc_asprintf(NULL, "%s/%s", dk->path, name); WERROR ret; - if (rmdir(child) == 0) - ret = WERR_OK; + if (rmdir(child) == 0) + ret = WERR_OK; else if (errno == ENOENT) ret = WERR_NOT_FOUND; else @@ -73,25 +73,26 @@ static WERROR reg_dir_del_key(const struct hive_key *k, const char *name) return ret; } -static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, - const struct hive_key *parent, - const char *name, struct hive_key **subkey) +static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, + const struct hive_key *parent, + const char *name, struct hive_key **subkey) { DIR *d; char *fullpath; const struct dir_key *p = talloc_get_type(parent, struct dir_key); struct dir_key *ret; - + if (name == NULL) { DEBUG(0, ("NULL pointer passed as directory name!")); return WERR_INVALID_PARAM; } - + fullpath = talloc_asprintf(mem_ctx, "%s/%s", p->path, name); - + d = opendir(fullpath); if (d == NULL) { - DEBUG(3,("Unable to open '%s': %s\n", fullpath, strerror(errno))); + DEBUG(3,("Unable to open '%s': %s\n", fullpath, + strerror(errno))); return WERR_BADFILE; } closedir(d); @@ -102,11 +103,11 @@ static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, return WERR_OK; } -static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, - const struct hive_key *k, uint32_t idx, - const char **name, - const char **classname, - NTTIME *last_mod_time) +static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, + const struct hive_key *k, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time) { struct dirent *e; const struct dir_key *dk = talloc_get_type(k, struct dir_key); @@ -115,14 +116,14 @@ static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, d = opendir(dk->path); - if (d == NULL) + if (d == NULL) return WERR_INVALID_PARAM; - + while((e = readdir(d))) { if(!ISDOT(e->d_name) && !ISDOTDOT(e->d_name)) { struct stat stbuf; char *thispath; - + /* Check if file is a directory */ asprintf(&thispath, "%s/%s", dk->path, e->d_name); stat(thispath, &stbuf); @@ -153,12 +154,12 @@ static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, return WERR_NO_MORE_ITEMS; } -WERROR reg_open_directory(TALLOC_CTX *parent_ctx, - const char *location, struct hive_key **key) +WERROR reg_open_directory(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key) { struct dir_key *dk; - if (location == NULL) + if (location == NULL) return WERR_INVALID_PARAM; dk = talloc(parent_ctx, struct dir_key); @@ -168,8 +169,8 @@ WERROR reg_open_directory(TALLOC_CTX *parent_ctx, return WERR_OK; } -WERROR reg_create_directory(TALLOC_CTX *parent_ctx, - const char *location, struct hive_key **key) +WERROR reg_create_directory(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key) { if (mkdir(location, 0700) != 0) { *key = NULL; @@ -179,11 +180,11 @@ WERROR reg_create_directory(TALLOC_CTX *parent_ctx, return reg_open_directory(parent_ctx, location, key); } -static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key, - const char **classname, - uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *lastmod) +static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *lastmod) { DIR *d; const struct dir_key *dk = talloc_get_type(key, struct dir_key); @@ -196,7 +197,7 @@ static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key, *classname = NULL; d = opendir(dk->path); - if (d == NULL) + if (d == NULL) return WERR_INVALID_PARAM; if (num_subkeys != NULL) @@ -207,10 +208,12 @@ static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key, while((e = readdir(d))) { if(!ISDOT(e->d_name) && !ISDOTDOT(e->d_name)) { - char *path = talloc_asprintf(ctx, "%s/%s", dk->path, e->d_name); + char *path = talloc_asprintf(ctx, "%s/%s", + dk->path, e->d_name); if (stat(path, &st) < 0) { - DEBUG(0, ("Error statting %s: %s\n", path, strerror(errno))); + DEBUG(0, ("Error statting %s: %s\n", path, + strerror(errno))); continue; } @@ -231,8 +234,8 @@ static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key, return WERR_OK; } -static WERROR reg_dir_set_value (struct hive_key *key, const char *name, - uint32_t type, const DATA_BLOB data) +static WERROR reg_dir_set_value(struct hive_key *key, const char *name, + uint32_t type, const DATA_BLOB data) { const struct dir_key *dk = talloc_get_type(key, struct dir_key); char *path = talloc_asprintf(dk, "%s/%s", dk->path, name); @@ -245,9 +248,9 @@ static WERROR reg_dir_set_value (struct hive_key *key, const char *name, return WERR_OK; } -static WERROR reg_dir_get_value (TALLOC_CTX *mem_ctx, - struct hive_key *key, const char *name, - uint32_t *type, DATA_BLOB *data) +static WERROR reg_dir_get_value(TALLOC_CTX *mem_ctx, + struct hive_key *key, const char *name, + uint32_t *type, DATA_BLOB *data) { const struct dir_key *dk = talloc_get_type(key, struct dir_key); char *path = talloc_asprintf(mem_ctx, "%s/%s", dk->path, name); @@ -256,7 +259,7 @@ static WERROR reg_dir_get_value (TALLOC_CTX *mem_ctx, contents = file_load(path, &size, mem_ctx); talloc_free(path); - if (contents == NULL) + if (contents == NULL) return WERR_NOT_FOUND; if (type != NULL) @@ -267,11 +270,11 @@ static WERROR reg_dir_get_value (TALLOC_CTX *mem_ctx, return WERR_OK; } - -static WERROR reg_dir_enum_value (TALLOC_CTX *mem_ctx, - const struct hive_key *key, int idx, - const char **name, - uint32_t *type, DATA_BLOB *data) + +static WERROR reg_dir_enum_value(TALLOC_CTX *mem_ctx, + const struct hive_key *key, int idx, + const char **name, + uint32_t *type, DATA_BLOB *data) { const struct dir_key *dk = talloc_get_type(key, struct dir_key); DIR *d; @@ -280,19 +283,22 @@ static WERROR reg_dir_enum_value (TALLOC_CTX *mem_ctx, d = opendir(dk->path); if (d == NULL) { - DEBUG(3,("Unable to open '%s': %s\n", dk->path, strerror(errno))); + DEBUG(3,("Unable to open '%s': %s\n", dk->path, + strerror(errno))); return WERR_BADFILE; } i = 0; while((e = readdir(d))) { - if (ISDOT(e->d_name) || ISDOTDOT(e->d_name)) + if (ISDOT(e->d_name) || ISDOTDOT(e->d_name)) continue; if (i == idx) { if (name != NULL) *name = talloc_strdup(mem_ctx, e->d_name); - W_ERROR_NOT_OK_RETURN(reg_dir_get_value(mem_ctx, key, *name, type, data)); + W_ERROR_NOT_OK_RETURN(reg_dir_get_value(mem_ctx, key, + *name, type, + data)); return WERR_OK; } @@ -315,7 +321,7 @@ static WERROR reg_dir_del_value (struct hive_key *key, const char *name) return WERR_GENERAL_FAILURE; } talloc_free(path); - + return WERR_OK; } diff --git a/source4/lib/registry/hive.c b/source4/lib/registry/hive.c index 97ce883e66..16534aac9c 100644 --- a/source4/lib/registry/hive.c +++ b/source4/lib/registry/hive.c @@ -1,19 +1,19 @@ -/* +/* Unix SMB/CIFS implementation. Registry hive interface - Copyright (C) Jelmer Vernooij 2003-2007. - + Copyright (C) Jelmer Vernooij 2003-2007. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -24,10 +24,10 @@ #include "system/filesys.h" /** Open a registry file/host/etc */ -_PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - struct hive_key **root) +_PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + struct hive_key **root) { int fd, num; char peek[20]; @@ -54,28 +54,33 @@ _PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, return reg_open_regf_file(parent_ctx, location, root); } else if (!strncmp(peek, "TDB file", 8)) { close(fd); - return reg_open_ldb_file(parent_ctx, location, session_info, credentials, root); + return reg_open_ldb_file(parent_ctx, location, session_info, + credentials, root); } return WERR_BADFILE; } -_PUBLIC_ WERROR hive_key_get_info(TALLOC_CTX *mem_ctx, const struct hive_key *key, - const char **classname, uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_change_time) +_PUBLIC_ WERROR hive_key_get_info(TALLOC_CTX *mem_ctx, + const struct hive_key *key, + const char **classname, uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time) { - return key->ops->get_key_info(mem_ctx, key, classname, num_subkeys, - num_values, last_change_time); + return key->ops->get_key_info(mem_ctx, key, classname, num_subkeys, + num_values, last_change_time); } -_PUBLIC_ WERROR hive_key_add_name(TALLOC_CTX *ctx, const struct hive_key *parent_key, - const char *name, const char *classname, struct security_descriptor *desc, - struct hive_key **key) +_PUBLIC_ WERROR hive_key_add_name(TALLOC_CTX *ctx, + const struct hive_key *parent_key, + const char *name, const char *classname, + struct security_descriptor *desc, + struct hive_key **key) { SMB_ASSERT(strchr(name, '\\') == NULL); - return parent_key->ops->add_key(ctx, parent_key, name, classname, desc, key); + return parent_key->ops->add_key(ctx, parent_key, name, classname, + desc, key); } _PUBLIC_ WERROR hive_key_del(const struct hive_key *key, const char *name) @@ -84,20 +89,21 @@ _PUBLIC_ WERROR hive_key_del(const struct hive_key *key, const char *name) } _PUBLIC_ WERROR hive_get_key_by_name(TALLOC_CTX *mem_ctx, - const struct hive_key *key, const char *name, - struct hive_key **subkey) + const struct hive_key *key, + const char *name, + struct hive_key **subkey) { return key->ops->get_key_by_name(mem_ctx, key, name, subkey); } WERROR hive_enum_key(TALLOC_CTX *mem_ctx, - const struct hive_key *key, uint32_t idx, - const char **name, - const char **classname, - NTTIME *last_mod_time) + const struct hive_key *key, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time) { - return key->ops->enum_key(mem_ctx, key, idx, name, classname, - last_mod_time); + return key->ops->enum_key(mem_ctx, key, idx, name, classname, + last_mod_time); } WERROR hive_set_value(struct hive_key *key, const char *name, uint32_t type, @@ -109,9 +115,9 @@ WERROR hive_set_value(struct hive_key *key, const char *name, uint32_t type, return key->ops->set_value(key, name, type, data); } -WERROR hive_get_value (TALLOC_CTX *mem_ctx, - struct hive_key *key, const char *name, - uint32_t *type, DATA_BLOB *data) +WERROR hive_get_value(TALLOC_CTX *mem_ctx, + struct hive_key *key, const char *name, + uint32_t *type, DATA_BLOB *data) { if (key->ops->get_value_by_name == NULL) return WERR_NOT_SUPPORTED; @@ -119,9 +125,10 @@ WERROR hive_get_value (TALLOC_CTX *mem_ctx, return key->ops->get_value_by_name(mem_ctx, key, name, type, data); } -WERROR hive_get_value_by_index (TALLOC_CTX *mem_ctx, - struct hive_key *key, uint32_t idx, const char **name, - uint32_t *type, DATA_BLOB *data) +WERROR hive_get_value_by_index(TALLOC_CTX *mem_ctx, + struct hive_key *key, uint32_t idx, + const char **name, + uint32_t *type, DATA_BLOB *data) { if (key->ops->enum_value == NULL) return WERR_NOT_SUPPORTED; @@ -130,7 +137,7 @@ WERROR hive_get_value_by_index (TALLOC_CTX *mem_ctx, } -WERROR hive_del_value (struct hive_key *key, const char *name) +WERROR hive_del_value(struct hive_key *key, const char *name) { if (key->ops->delete_value == NULL) return WERR_NOT_SUPPORTED; diff --git a/source4/lib/registry/hive.h b/source4/lib/registry/hive.h index 5a5356dfd2..2f783dd15d 100644 --- a/source4/lib/registry/hive.h +++ b/source4/lib/registry/hive.h @@ -1,18 +1,18 @@ -/* +/* Unix SMB/CIFS implementation. Registry hive interface Copyright (C) Jelmer Vernooij 2003-2007. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -26,13 +26,13 @@ #include "libcli/util/ntstatus.h" /** - * This file contains the hive API. This API is generally used for - * reading a specific file that contains just one hive. + * This file contains the hive API. This API is generally used for + * reading a specific file that contains just one hive. * * Good examples are .DAT (NTUSER.DAT) files. * - * This API does not have any notification support (that - * should be provided by the registry implementation), nor + * This API does not have any notification support (that + * should be provided by the registry implementation), nor * does it understand what predefined keys are. */ @@ -41,31 +41,32 @@ struct hive_key { }; struct hive_operations { - const char *name; + const char *name; /** * Open a specific subkey */ WERROR (*enum_key) (TALLOC_CTX *mem_ctx, - const struct hive_key *key, uint32_t idx, - const char **name, - const char **classname, - NTTIME *last_mod_time); + const struct hive_key *key, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time); /** * Open a subkey by name */ WERROR (*get_key_by_name) (TALLOC_CTX *mem_ctx, - const struct hive_key *key, const char *name, - struct hive_key **subkey); - + const struct hive_key *key, const char *name, + struct hive_key **subkey); + /** * Add a new key. */ WERROR (*add_key) (TALLOC_CTX *ctx, - const struct hive_key *parent_key, const char *name, - const char *classname, struct security_descriptor *desc, - struct hive_key **key); + const struct hive_key *parent_key, const char *name, + const char *classname, + struct security_descriptor *desc, + struct hive_key **key); /** * Remove an existing key. */ @@ -80,22 +81,22 @@ struct hive_operations { * Retrieve a registry value with a specific index. */ WERROR (*enum_value) (TALLOC_CTX *mem_ctx, - const struct hive_key *key, int idx, - const char **name, uint32_t *type, - DATA_BLOB *data); + const struct hive_key *key, int idx, + const char **name, uint32_t *type, + DATA_BLOB *data); /** * Retrieve a registry value with the specified name */ - WERROR (*get_value_by_name) (TALLOC_CTX *mem_ctx, - struct hive_key *key, const char *name, - uint32_t *type, DATA_BLOB *data); - + WERROR (*get_value_by_name) (TALLOC_CTX *mem_ctx, + struct hive_key *key, const char *name, + uint32_t *type, DATA_BLOB *data); + /** * Set a value on the specified registry key. */ - WERROR (*set_value) (struct hive_key *key, const char *name, - uint32_t type, const DATA_BLOB data); + WERROR (*set_value) (struct hive_key *key, const char *name, + uint32_t type, const DATA_BLOB data); /** * Remove a value. @@ -107,91 +108,93 @@ struct hive_operations { /** * Change the security descriptor on a registry key. * - * This should return WERR_NOT_SUPPORTED if the underlying - * format does not have a mechanism for storing + * This should return WERR_NOT_SUPPORTED if the underlying + * format does not have a mechanism for storing * security descriptors. */ - WERROR (*set_sec_desc) (struct hive_key *key, - const struct security_descriptor *desc); + WERROR (*set_sec_desc) (struct hive_key *key, + const struct security_descriptor *desc); /** * Retrieve the security descriptor on a registry key. * - * This should return WERR_NOT_SUPPORTED if the underlying - * format does not have a mechanism for storing + * This should return WERR_NOT_SUPPORTED if the underlying + * format does not have a mechanism for storing * security descriptors. */ WERROR (*get_sec_desc) (TALLOC_CTX *ctx, - const struct hive_key *key, - struct security_descriptor **desc); - + const struct hive_key *key, + struct security_descriptor **desc); + /** * Retrieve general information about a key. */ WERROR (*get_key_info) (TALLOC_CTX *mem_ctx, - const struct hive_key *key, - const char **classname, - uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_change_time); + const struct hive_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time); }; struct cli_credentials; struct auth_session_info; -WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - struct hive_key **root); +WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + struct hive_key **root); WERROR hive_key_get_info(TALLOC_CTX *mem_ctx, const struct hive_key *key, - const char **classname, uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_change_time); + const char **classname, uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time); WERROR hive_key_add_name(TALLOC_CTX *ctx, const struct hive_key *parent_key, - const char *name, const char *classname, struct security_descriptor *desc, - struct hive_key **key); + const char *name, const char *classname, + struct security_descriptor *desc, + struct hive_key **key); WERROR hive_key_del(const struct hive_key *key, const char *name); WERROR hive_get_key_by_name(TALLOC_CTX *mem_ctx, - const struct hive_key *key, const char *name, - struct hive_key **subkey); + const struct hive_key *key, const char *name, + struct hive_key **subkey); WERROR hive_enum_key(TALLOC_CTX *mem_ctx, - const struct hive_key *key, uint32_t idx, - const char **name, - const char **classname, - NTTIME *last_mod_time); + const struct hive_key *key, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time); -WERROR hive_set_value (struct hive_key *key, const char *name, - uint32_t type, const DATA_BLOB data); +WERROR hive_set_value(struct hive_key *key, const char *name, + uint32_t type, const DATA_BLOB data); -WERROR hive_get_value (TALLOC_CTX *mem_ctx, - struct hive_key *key, const char *name, - uint32_t *type, DATA_BLOB *data); -WERROR hive_get_value_by_index (TALLOC_CTX *mem_ctx, - struct hive_key *key, uint32_t idx, const char **name, - uint32_t *type, DATA_BLOB *data); +WERROR hive_get_value(TALLOC_CTX *mem_ctx, + struct hive_key *key, const char *name, + uint32_t *type, DATA_BLOB *data); +WERROR hive_get_value_by_index(TALLOC_CTX *mem_ctx, + struct hive_key *key, uint32_t idx, + const char **name, + uint32_t *type, DATA_BLOB *data); -WERROR hive_del_value (struct hive_key *key, const char *name); +WERROR hive_del_value(struct hive_key *key, const char *name); WERROR hive_key_flush(struct hive_key *key); /* Individual backends */ -WERROR reg_open_directory(TALLOC_CTX *parent_ctx, - const char *location, struct hive_key **key); -WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, - const char *location, struct hive_key **key); -WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - struct hive_key **k); - - -WERROR reg_create_directory(TALLOC_CTX *parent_ctx, - const char *location, struct hive_key **key); -WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, - const char *location, - int major_version, - struct hive_key **key); +WERROR reg_open_directory(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key); +WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key); +WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + struct hive_key **k); + + +WERROR reg_create_directory(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key); +WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, + const char *location, + int major_version, + struct hive_key **key); #endif /* __REGISTRY_HIVE_H__ */ diff --git a/source4/lib/registry/interface.c b/source4/lib/registry/interface.c index 98c72c7940..8f60a55ae9 100644 --- a/source4/lib/registry/interface.c +++ b/source4/lib/registry/interface.c @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. Transparent registry backend handling Copyright (C) Jelmer Vernooij 2003-2007. @@ -47,7 +47,7 @@ _PUBLIC_ const char *reg_get_predef_name(uint32_t hkey) { int i; for (i = 0; reg_predefined_keys[i].name; i++) { - if (reg_predefined_keys[i].handle == hkey) + if (reg_predefined_keys[i].handle == hkey) return reg_predefined_keys[i].name; } @@ -55,40 +55,42 @@ _PUBLIC_ const char *reg_get_predef_name(uint32_t hkey) } /** Get predefined key by name. */ -_PUBLIC_ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, - const char *name, - struct registry_key **key) +_PUBLIC_ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, + const char *name, + struct registry_key **key) { int i; - + for (i = 0; reg_predefined_keys[i].name; i++) { - if (!strcasecmp(reg_predefined_keys[i].name, name)) - return reg_get_predefined_key(ctx, reg_predefined_keys[i].handle, - key); + if (!strcasecmp(reg_predefined_keys[i].name, name)) + return reg_get_predefined_key(ctx, + reg_predefined_keys[i].handle, + key); } DEBUG(1, ("No predefined key with name '%s'\n", name)); - + return WERR_BADFILE; } /** Get predefined key by id. */ -_PUBLIC_ WERROR reg_get_predefined_key(const struct registry_context *ctx, - uint32_t hkey, struct registry_key **key) +_PUBLIC_ WERROR reg_get_predefined_key(const struct registry_context *ctx, + uint32_t hkey, struct registry_key **key) { return ctx->ops->get_predefined_key(ctx, hkey, key); } /** - * Open a key + * Open a key * First tries to use the open_key function from the backend - * then falls back to get_subkey_by_name and later get_subkey_by_index + * then falls back to get_subkey_by_name and later get_subkey_by_index */ -_PUBLIC_ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, - const char *name, struct registry_key **result) +_PUBLIC_ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, + const char *name, struct registry_key **result) { if (parent == NULL) { - DEBUG(0, ("Invalid parent key specified for open of '%s'\n", name)); + DEBUG(0, ("Invalid parent key specified for open of '%s'\n", + name)); return WERR_INVALID_PARAM; } @@ -103,69 +105,71 @@ _PUBLIC_ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, /** * Get value by index */ -_PUBLIC_ WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, - const struct registry_key *key, +_PUBLIC_ WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, + const struct registry_key *key, uint32_t idx, const char **name, uint32_t *type, DATA_BLOB *data) { - if (key == NULL) + if (key == NULL) return WERR_INVALID_PARAM; if (key->context->ops->enum_value == NULL) return WERR_NOT_SUPPORTED; - return key->context->ops->enum_value(mem_ctx, key, idx, name, type, - data); + return key->context->ops->enum_value(mem_ctx, key, idx, name, + type, data); } -/** +/** * Get the number of subkeys. */ -_PUBLIC_ WERROR reg_key_get_info(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - const char **classname, - uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_change_time) +_PUBLIC_ WERROR reg_key_get_info(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time) { - if (key == NULL) + if (key == NULL) return WERR_INVALID_PARAM; - + if (key->context->ops->get_key_info == NULL) return WERR_NOT_SUPPORTED; return key->context->ops->get_key_info(mem_ctx, - key, classname, num_subkeys, - num_values, last_change_time); + key, classname, num_subkeys, + num_values, last_change_time); } /** * Get subkey by index. */ -_PUBLIC_ WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, - const struct registry_key *key, int idx, const char **name, - const char **keyclass, NTTIME *last_changed_time) +_PUBLIC_ WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + int idx, const char **name, + const char **keyclass, + NTTIME *last_changed_time) { - if (key == NULL) + if (key == NULL) return WERR_INVALID_PARAM; if (key->context->ops->enum_key == NULL) return WERR_NOT_SUPPORTED; return key->context->ops->enum_key(mem_ctx, key, idx, name, - keyclass, last_changed_time); + keyclass, last_changed_time); } /** * Get value by name. */ -_PUBLIC_ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - const char *name, - uint32_t *type, - DATA_BLOB *data) +_PUBLIC_ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char *name, + uint32_t *type, + DATA_BLOB *data) { - if (key == NULL) + if (key == NULL) return WERR_INVALID_PARAM; if (key->context->ops->get_value == NULL) @@ -179,49 +183,49 @@ _PUBLIC_ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, */ _PUBLIC_ WERROR reg_key_del(struct registry_key *parent, const char *name) { - if (parent == NULL) + if (parent == NULL) return WERR_INVALID_PARAM; - + if (parent->context->ops->delete_key == NULL) return WERR_NOT_SUPPORTED; - + return parent->context->ops->delete_key(parent, name); } /** * Add a key. */ -_PUBLIC_ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, - struct registry_key *parent, - const char *name, const char *key_class, - struct security_descriptor *desc, - struct registry_key **newkey) +_PUBLIC_ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, + struct registry_key *parent, + const char *name, const char *key_class, + struct security_descriptor *desc, + struct registry_key **newkey) { - if (parent == NULL) + if (parent == NULL) return WERR_INVALID_PARAM; - + if (parent->context->ops->create_key == NULL) { - DEBUG(1, ("Backend '%s' doesn't support method add_key\n", + DEBUG(1, ("Backend '%s' doesn't support method add_key\n", parent->context->ops->name)); return WERR_NOT_SUPPORTED; } - return parent->context->ops->create_key(mem_ctx, parent, name, - key_class, desc, newkey); + return parent->context->ops->create_key(mem_ctx, parent, name, + key_class, desc, newkey); } /** * Set a value. */ -_PUBLIC_ WERROR reg_val_set(struct registry_key *key, const char *value, - uint32_t type, const DATA_BLOB data) +_PUBLIC_ WERROR reg_val_set(struct registry_key *key, const char *value, + uint32_t type, const DATA_BLOB data) { if (key == NULL) return WERR_INVALID_PARAM; /* A 'real' set function has preference */ if (key->context->ops->set_value == NULL) { - DEBUG(1, ("Backend '%s' doesn't support method set_value\n", + DEBUG(1, ("Backend '%s' doesn't support method set_value\n", key->context->ops->name)); return WERR_NOT_SUPPORTED; } @@ -232,15 +236,15 @@ _PUBLIC_ WERROR reg_val_set(struct registry_key *key, const char *value, /** * Get the security descriptor on a key. */ -_PUBLIC_ WERROR reg_get_sec_desc(TALLOC_CTX *ctx, - const struct registry_key *key, - struct security_descriptor **secdesc) +_PUBLIC_ WERROR reg_get_sec_desc(TALLOC_CTX *ctx, + const struct registry_key *key, + struct security_descriptor **secdesc) { if (key == NULL) return WERR_INVALID_PARAM; /* A 'real' set function has preference */ - if (key->context->ops->get_security == NULL) + if (key->context->ops->get_security == NULL) return WERR_NOT_SUPPORTED; return key->context->ops->get_security(ctx, key, secdesc); @@ -267,32 +271,32 @@ _PUBLIC_ WERROR reg_key_flush(struct registry_key *key) { if (key == NULL) return WERR_INVALID_PARAM; - + if (key->context->ops->flush_key == NULL) return WERR_NOT_SUPPORTED; return key->context->ops->flush_key(key); } -_PUBLIC_ WERROR reg_get_security(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - struct security_descriptor **security) +_PUBLIC_ WERROR reg_get_security(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + struct security_descriptor **security) { if (key == NULL) return WERR_INVALID_PARAM; - + if (key->context->ops->get_security == NULL) return WERR_NOT_SUPPORTED; return key->context->ops->get_security(mem_ctx, key, security); } -_PUBLIC_ WERROR reg_set_security(struct registry_key *key, - struct security_descriptor *security) +_PUBLIC_ WERROR reg_set_security(struct registry_key *key, + struct security_descriptor *security) { if (key == NULL) return WERR_INVALID_PARAM; - + if (key->context->ops->set_security == NULL) return WERR_NOT_SUPPORTED; diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index e9daf31f9b..4a6ef65bc4 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -1,18 +1,18 @@ -/* +/* Unix SMB/CIFS implementation. Registry interface Copyright (C) Jelmer Vernooij 2004-2007. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -27,7 +27,7 @@ static struct hive_operations reg_backend_ldb; -struct ldb_key_data +struct ldb_key_data { struct hive_key key; struct ldb_context *ldb; @@ -36,12 +36,15 @@ struct ldb_key_data int subkey_count, value_count; }; -static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char **name, - uint32_t *type, DATA_BLOB *data) +static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, + const char **name, uint32_t *type, + DATA_BLOB *data) { const struct ldb_val *val; if (name != NULL) - *name = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(msg, "value", NULL)); + *name = talloc_strdup(mem_ctx, + ldb_msg_find_attr_as_string(msg, "value", + NULL)); if (type != NULL) *type = ldb_msg_find_attr_as_uint(msg, "type", 0); @@ -51,8 +54,9 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, c { case REG_SZ: case REG_EXPAND_SZ: - data->length = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, - val->data, val->length, (void **)&data->data); + data->length = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, + val->data, val->length, + (void **)&data->data); break; case REG_DWORD: { @@ -67,9 +71,10 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, c } } -static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, - TALLOC_CTX *mem_ctx, const char *name, - uint32_t type, DATA_BLOB data) +static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, + TALLOC_CTX *mem_ctx, + const char *name, + uint32_t type, DATA_BLOB data) { struct ldb_val val; struct ldb_message *msg = talloc_zero(mem_ctx, struct ldb_message); @@ -80,13 +85,17 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, switch (type) { case REG_SZ: case REG_EXPAND_SZ: - val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8, - (void *)data.data, data.length, (void **)&val.data); + val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8, + (void *)data.data, + data.length, + (void **)&val.data); ldb_msg_add_value(msg, "data", &val, NULL); break; case REG_DWORD: - ldb_msg_add_string(msg, "data", talloc_asprintf(mem_ctx, "0x%x", IVAL(data.data, 0))); + ldb_msg_add_string(msg, "data", + talloc_asprintf(mem_ctx, "0x%x", + IVAL(data.data, 0))); break; default: ldb_msg_add_value(msg, "data", &data, NULL); @@ -94,7 +103,7 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, type_s = talloc_asprintf(mem_ctx, "%u", type); - ldb_msg_add_string(msg, "type", type_s); + ldb_msg_add_string(msg, "type", type_s); return msg; } @@ -103,20 +112,20 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, static int reg_close_ldb_key(struct ldb_key_data *key) { if (key->subkeys != NULL) { - talloc_free(key->subkeys); + talloc_free(key->subkeys); key->subkeys = NULL; } if (key->values != NULL) { - talloc_free(key->values); + talloc_free(key->values); key->values = NULL; } return 0; } -static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, - const struct hive_key *from, - const char *path, const char *add) +static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, + const struct hive_key *from, + const char *path, const char *add) { TALLOC_CTX *local_ctx; struct ldb_dn *ret; @@ -173,7 +182,8 @@ static WERROR cache_subkeys(struct ldb_key_data *kd) ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &res); if (ret != LDB_SUCCESS) { - DEBUG(0, ("Error getting subkeys for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); + DEBUG(0, ("Error getting subkeys for '%s': %s\n", + ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); return WERR_FOOBAR; } @@ -190,10 +200,12 @@ static WERROR cache_values(struct ldb_key_data *kd) struct ldb_result *res; int ret; - ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(value=*)", NULL, &res); + ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, + "(value=*)", NULL, &res); if (ret != LDB_SUCCESS) { - DEBUG(0, ("Error getting values for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); + DEBUG(0, ("Error getting values for '%s': %s\n", + ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); return WERR_FOOBAR; } kd->value_count = res->count; @@ -203,11 +215,11 @@ static WERROR cache_values(struct ldb_key_data *kd) } -static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, - const struct hive_key *k, uint32_t idx, - const char **name, - const char **classname, - NTTIME *last_mod_time) +static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, + const struct hive_key *k, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time) { struct ldb_message_element *el; struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data); @@ -215,21 +227,21 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, /* Do a search if necessary */ if (kd->subkeys == NULL) { W_ERROR_NOT_OK_RETURN(cache_subkeys(kd)); - } + } - if (idx >= kd->subkey_count) + if (idx >= kd->subkey_count) return WERR_NO_MORE_ITEMS; el = ldb_msg_find_element(kd->subkeys[idx], "key"); SMB_ASSERT(el != NULL); SMB_ASSERT(el->num_values != 0); - + if (name != NULL) *name = talloc_strdup(mem_ctx, (char *)el->values[0].data); if (classname != NULL) *classname = NULL; /* TODO: Store properly */ - + if (last_mod_time != NULL) *last_mod_time = 0; /* TODO: we need to add this to the ldb backend properly */ @@ -237,8 +249,9 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, return WERR_OK; } -static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct hive_key *k, int idx, - const char **name, uint32_t *data_type, DATA_BLOB *data) +static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct hive_key *k, + int idx, const char **name, + uint32_t *data_type, DATA_BLOB *data) { struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data); @@ -247,16 +260,18 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct hive_key *k, W_ERROR_NOT_OK_RETURN(cache_values(kd)); } - if(idx >= kd->value_count) return WERR_NO_MORE_ITEMS; + if (idx >= kd->value_count) + return WERR_NO_MORE_ITEMS; - reg_ldb_unpack_value(mem_ctx, kd->values[idx], - name, data_type, data); + reg_ldb_unpack_value(mem_ctx, kd->values[idx], + name, data_type, data); return WERR_OK; } -static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, - const char *name, uint32_t *data_type, DATA_BLOB *data) +static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, + const char *name, uint32_t *data_type, + DATA_BLOB *data) { struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data); struct ldb_context *c = kd->ldb; @@ -269,7 +284,8 @@ static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, talloc_free(query); if (ret != LDB_SUCCESS) { - DEBUG(0, ("Error getting values for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); + DEBUG(0, ("Error getting values for '%s': %s\n", + ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); return WERR_FOOBAR; } @@ -281,8 +297,8 @@ static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, return WERR_OK; } -static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, - const char *name, struct hive_key **key) +static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, + const char *name, struct hive_key **key) { struct ldb_result *res; struct ldb_dn *ldap_path; @@ -296,11 +312,12 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL, &res); if (ret != LDB_SUCCESS) { - DEBUG(3, ("Error opening key '%s': %s\n", - ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); + DEBUG(3, ("Error opening key '%s': %s\n", + ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); return WERR_FOOBAR; } else if (res->count == 0) { - DEBUG(3, ("Key '%s' not found\n", ldb_dn_get_linearized(ldap_path))); + DEBUG(3, ("Key '%s' not found\n", + ldb_dn_get_linearized(ldap_path))); talloc_free(res); return WERR_NOT_FOUND; } @@ -308,7 +325,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, newkd = talloc_zero(mem_ctx, struct ldb_key_data); newkd->key.ops = ®_backend_ldb; newkd->ldb = talloc_reference(newkd, kd->ldb); - newkd->dn = ldb_dn_copy(mem_ctx, res->msgs[0]->dn); + newkd->dn = ldb_dn_copy(mem_ctx, res->msgs[0]->dn); *key = (struct hive_key *)newkd; @@ -317,7 +334,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, return WERR_OK; } -WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, +WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, struct hive_key **k) @@ -325,10 +342,10 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, struct ldb_key_data *kd; struct ldb_context *wrap; - if (location == NULL) + if (location == NULL) return WERR_INVALID_PARAM; - wrap = ldb_wrap_connect(parent_ctx, global_loadparm, + wrap = ldb_wrap_connect(parent_ctx, global_loadparm, location, session_info, credentials, 0, NULL); if (wrap == NULL) { @@ -349,10 +366,10 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, return WERR_OK; } -static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, const struct hive_key *parent, - const char *name, const char *classname, - struct security_descriptor *sd, - struct hive_key **newkey) +static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent, + const char *name, const char *classname, + struct security_descriptor *sd, + struct hive_key **newkey) { const struct ldb_key_data *parentkd = (const struct ldb_key_data *)parent; struct ldb_message *msg; @@ -365,13 +382,14 @@ static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, const struct hive_key *parent, ldb_msg_add_string(msg, "key", talloc_strdup(mem_ctx, name)); if (classname != NULL) - ldb_msg_add_string(msg, "classname", talloc_strdup(mem_ctx, classname)); + ldb_msg_add_string(msg, "classname", + talloc_strdup(mem_ctx, classname)); ret = ldb_add(parentkd->ldb, msg); if (ret < 0) { DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parentkd->ldb))); return WERR_FOOBAR; - } + } DEBUG(2, ("key added: %s\n", ldb_dn_get_linearized(msg->dn))); @@ -385,7 +403,7 @@ static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, const struct hive_key *parent, return WERR_OK; } -static WERROR ldb_del_key (const struct hive_key *key, const char *child) +static WERROR ldb_del_key(const struct hive_key *key, const char *child) { int ret; struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data); @@ -431,9 +449,9 @@ static WERROR ldb_del_value (struct hive_key *key, const char *child) return WERR_OK; } -static WERROR ldb_set_value(struct hive_key *parent, - const char *name, uint32_t type, - const DATA_BLOB data) +static WERROR ldb_set_value(struct hive_key *parent, + const char *name, uint32_t type, + const DATA_BLOB data) { struct ldb_message *msg; struct ldb_key_data *kd = talloc_get_type(parent, struct ldb_key_data); @@ -454,17 +472,17 @@ static WERROR ldb_set_value(struct hive_key *parent, return WERR_FOOBAR; } } - + talloc_free(mem_ctx); return WERR_OK; } -static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, - const struct hive_key *key, - const char **classname, - uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_change_time) +static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, + const struct hive_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time) { struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data); diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index a52feaaed5..b54f0cf30a 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. Transparent registry backend handling Copyright (C) Jelmer Vernooij 2003-2007. @@ -38,7 +38,7 @@ struct registry_local { struct mountpoint *prev, *next; } *mountpoints; - struct auth_session_info *session_info; + struct auth_session_info *session_info; struct cli_credentials *credentials; }; @@ -49,9 +49,9 @@ struct local_key { }; -struct registry_key *reg_import_hive_key(struct registry_context *ctx, - struct hive_key *hive, - uint32_t predefined_key, +struct registry_key *reg_import_hive_key(struct registry_context *ctx, + struct hive_key *hive, + uint32_t predefined_key, const char **elements) { struct local_key *local_key; @@ -70,25 +70,26 @@ struct registry_key *reg_import_hive_key(struct registry_context *ctx, static WERROR local_open_key(TALLOC_CTX *mem_ctx, - struct registry_key *parent, - const char *path, - struct registry_key **result) + struct registry_key *parent, + const char *path, + struct registry_key **result) { char *orig = talloc_strdup(mem_ctx, path), - *curbegin = orig, + *curbegin = orig, *curend = strchr(orig, '\\'); - struct local_key *local_parent = talloc_get_type(parent, struct local_key); + struct local_key *local_parent = talloc_get_type(parent, + struct local_key); struct hive_key *curkey = local_parent->hive_key; WERROR error; const char **elements = NULL; int el; if (local_parent->path.elements != NULL) { - elements = talloc_array(mem_ctx, const char *, - str_list_length(local_parent->path.elements) + 1); + elements = talloc_array(mem_ctx, const char *, + str_list_length(local_parent->path.elements) + 1); for (el = 0; local_parent->path.elements[el] != NULL; el++) { - elements[el] = talloc_reference(elements, - local_parent->path.elements[el]); + elements[el] = talloc_reference(elements, + local_parent->path.elements[el]); } elements[el] = NULL; } else { @@ -103,67 +104,69 @@ static WERROR local_open_key(TALLOC_CTX *mem_ctx, elements[el] = talloc_strdup(elements, curbegin); el++; elements[el] = NULL; - error = hive_get_key_by_name(mem_ctx, curkey, curbegin, &curkey); + error = hive_get_key_by_name(mem_ctx, curkey, + curbegin, &curkey); if (!W_ERROR_IS_OK(error)) { - DEBUG(2, ("Opening key %s failed: %s\n", curbegin, win_errstr(error))); + DEBUG(2, ("Opening key %s failed: %s\n", curbegin, + win_errstr(error))); talloc_free(orig); return error; } - if (curend == NULL) + if (curend == NULL) break; curbegin = curend + 1; curend = strchr(curbegin, '\\'); } talloc_free(orig); - *result = reg_import_hive_key(local_parent->global.context, curkey, - local_parent->path.predefined_key, - talloc_steal(curkey, elements)); - + *result = reg_import_hive_key(local_parent->global.context, curkey, + local_parent->path.predefined_key, + talloc_steal(curkey, elements)); + return WERR_OK; } -WERROR local_get_predefined_key (const struct registry_context *ctx, - uint32_t key_id, struct registry_key **key) -{ - struct registry_local *rctx = talloc_get_type(ctx, +WERROR local_get_predefined_key(const struct registry_context *ctx, + uint32_t key_id, struct registry_key **key) +{ + struct registry_local *rctx = talloc_get_type(ctx, struct registry_local); struct mountpoint *mp; for (mp = rctx->mountpoints; mp != NULL; mp = mp->next) { - if (mp->path.predefined_key == key_id && + if (mp->path.predefined_key == key_id && mp->path.elements == NULL) break; } if (mp == NULL) return WERR_NOT_FOUND; - - *key = reg_import_hive_key(ctx, mp->key, - mp->path.predefined_key, + + *key = reg_import_hive_key(ctx, mp->key, + mp->path.predefined_key, mp->path.elements); return WERR_OK; } static WERROR local_enum_key(TALLOC_CTX *mem_ctx, - const struct registry_key *key, uint32_t idx, - const char **name, - const char **keyclass, - NTTIME *last_changed_time) + const struct registry_key *key, uint32_t idx, + const char **name, + const char **keyclass, + NTTIME *last_changed_time) { const struct local_key *local = (const struct local_key *)key; - return hive_enum_key(mem_ctx, local->hive_key, idx, name, keyclass, - last_changed_time); + return hive_enum_key(mem_ctx, local->hive_key, idx, name, keyclass, + last_changed_time); } -static WERROR local_create_key (TALLOC_CTX *mem_ctx, - struct registry_key *parent_key, - const char *name, - const char *key_class, - struct security_descriptor *security, - struct registry_key **key) +static WERROR local_create_key(TALLOC_CTX *mem_ctx, + struct registry_key *parent_key, + const char *name, + const char *key_class, + struct security_descriptor *security, + struct registry_key **key) { const struct local_key *local_parent; struct hive_key *hivekey; @@ -176,21 +179,22 @@ static WERROR local_create_key (TALLOC_CTX *mem_ctx, last_part = name; local_parent = (const struct local_key *)parent_key; } else { - W_ERROR_NOT_OK_RETURN(reg_open_key(mem_ctx, parent_key, - talloc_strndup(mem_ctx, name, last_part-name), - &local_parent)); + W_ERROR_NOT_OK_RETURN(reg_open_key(mem_ctx, parent_key, + talloc_strndup(mem_ctx, name, last_part-name), + &local_parent)); last_part++; } - W_ERROR_NOT_OK_RETURN(hive_key_add_name(mem_ctx, local_parent->hive_key, - last_part, key_class, security, &hivekey)); + W_ERROR_NOT_OK_RETURN(hive_key_add_name(mem_ctx, local_parent->hive_key, + last_part, key_class, security, + &hivekey)); if (local_parent->path.elements != NULL) { - elements = talloc_array(hivekey, const char *, - str_list_length(local_parent->path.elements)+2); + elements = talloc_array(hivekey, const char *, + str_list_length(local_parent->path.elements)+2); for (i = 0; local_parent->path.elements[i] != NULL; i++) { - elements[i] = talloc_reference(elements, - local_parent->path.elements[i]); + elements[i] = talloc_reference(elements, + local_parent->path.elements[i]); } } else { elements = talloc_array(hivekey, const char *, 2); @@ -200,75 +204,75 @@ static WERROR local_create_key (TALLOC_CTX *mem_ctx, elements[i] = talloc_strdup(elements, name); elements[i+1] = NULL; - *key = reg_import_hive_key(local_parent->global.context, hivekey, - local_parent->path.predefined_key, - elements); + *key = reg_import_hive_key(local_parent->global.context, hivekey, + local_parent->path.predefined_key, + elements); return WERR_OK; } -static WERROR local_set_value (struct registry_key *key, const char *name, - uint32_t type, const DATA_BLOB data) +static WERROR local_set_value(struct registry_key *key, const char *name, + uint32_t type, const DATA_BLOB data) { struct local_key *local = (struct local_key *)key; return hive_set_value(local->hive_key, name, type, data); } -static WERROR local_get_value (TALLOC_CTX *mem_ctx, - const struct registry_key *key, - const char *name, uint32_t *type, DATA_BLOB *data) +static WERROR local_get_value(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char *name, uint32_t *type, DATA_BLOB *data) { const struct local_key *local = (const struct local_key *)key; return hive_get_value(mem_ctx, local->hive_key, name, type, data); } -static WERROR local_enum_value (TALLOC_CTX *mem_ctx, - const struct registry_key *key, uint32_t idx, - const char **name, - uint32_t *type, - DATA_BLOB *data) +static WERROR local_enum_value(TALLOC_CTX *mem_ctx, + const struct registry_key *key, uint32_t idx, + const char **name, + uint32_t *type, + DATA_BLOB *data) { const struct local_key *local = (const struct local_key *)key; - return hive_get_value_by_index(mem_ctx, local->hive_key, idx, - name, type, data); + return hive_get_value_by_index(mem_ctx, local->hive_key, idx, + name, type, data); } -static WERROR local_delete_key (struct registry_key *key, const char *name) +static WERROR local_delete_key(struct registry_key *key, const char *name) { const struct local_key *local = (const struct local_key *)key; return hive_key_del(local->hive_key, name); } -static WERROR local_delete_value (struct registry_key *key, const char *name) +static WERROR local_delete_value(struct registry_key *key, const char *name) { const struct local_key *local = (const struct local_key *)key; return hive_del_value(local->hive_key, name); } -static WERROR local_flush_key (struct registry_key *key) +static WERROR local_flush_key(struct registry_key *key) { const struct local_key *local = (const struct local_key *)key; return hive_key_flush(local->hive_key); } -static WERROR local_get_key_info (TALLOC_CTX *mem_ctx, - const struct registry_key *key, - const char **classname, - uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_change_time) +static WERROR local_get_key_info(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time) { const struct local_key *local = (const struct local_key *)key; - return hive_key_get_info(mem_ctx, local->hive_key, - classname, num_subkeys, num_values, - last_change_time); + return hive_key_get_info(mem_ctx, local->hive_key, + classname, num_subkeys, num_values, + last_change_time); } const static struct registry_operations local_ops = { @@ -286,11 +290,12 @@ const static struct registry_operations local_ops = { .get_key_info = local_get_key_info, }; -WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials) +WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials) { - struct registry_local *ret = talloc_zero(mem_ctx, struct registry_local); + struct registry_local *ret = talloc_zero(mem_ctx, + struct registry_local); W_ERROR_HAVE_NO_MEMORY(ret); @@ -299,16 +304,17 @@ WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx, ret->credentials = credentials; *ctx = (struct registry_context *)ret; - + return WERR_OK; } -WERROR reg_mount_hive(struct registry_context *rctx, - struct hive_key *hive_key, - uint32_t key_id, - const char **elements) +WERROR reg_mount_hive(struct registry_context *rctx, + struct hive_key *hive_key, + uint32_t key_id, + const char **elements) { - struct registry_local *reg_local = talloc_get_type(rctx, struct registry_local); + struct registry_local *reg_local = talloc_get_type(rctx, + struct registry_local); struct mountpoint *mp = talloc(rctx, struct mountpoint); int i = 0; @@ -316,11 +322,11 @@ WERROR reg_mount_hive(struct registry_context *rctx, mp->prev = mp->next = NULL; mp->key = hive_key; if (elements != NULL) { - mp->path.elements = talloc_array(mp, const char *, - str_list_length(elements)); + mp->path.elements = talloc_array(mp, const char *, + str_list_length(elements)); for (i = 0; elements[i] != NULL; i++) { - mp->path.elements[i] = talloc_reference(mp->path.elements, - elements[i]); + mp->path.elements[i] = talloc_reference(mp->path.elements, + elements[i]); } mp->path.elements[i] = NULL; } else { diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index 99887c67bf..e5d9a26618 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -1,7 +1,7 @@ -/* +/* Unix SMB/CIFS implementation. Reading registry patch files - + Copyright (C) Jelmer Vernooij 2004-2007 Copyright (C) Wilco Baan Hofman 2006 @@ -9,12 +9,12 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -25,18 +25,22 @@ #include "system/filesys.h" -_PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *callbacks, void *callback_data); +_PUBLIC_ WERROR reg_preg_diff_load(int fd, + const struct reg_diff_callbacks *callbacks, + void *callback_data); -_PUBLIC_ WERROR reg_dotreg_diff_load(int fd, const struct reg_diff_callbacks *callbacks, void *callback_data); +_PUBLIC_ WERROR reg_dotreg_diff_load(int fd, + const struct reg_diff_callbacks *callbacks, + void *callback_data); /* * Generate difference between two keys */ -WERROR reg_generate_diff_key(struct registry_key *oldkey, - struct registry_key *newkey, - const char *path, - const struct reg_diff_callbacks *callbacks, - void *callback_data) +WERROR reg_generate_diff_key(struct registry_key *oldkey, + struct registry_key *newkey, + const char *path, + const struct reg_diff_callbacks *callbacks, + void *callback_data) { int i; struct registry_key *t1, *t2; @@ -48,11 +52,12 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, new_num_subkeys, new_num_values; if (oldkey != NULL) { - error = reg_key_get_info(mem_ctx, oldkey, NULL, &old_num_subkeys, &old_num_values, - NULL); + error = reg_key_get_info(mem_ctx, oldkey, NULL, + &old_num_subkeys, &old_num_values, + NULL); if (!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error occured while getting key info: %s\n", - win_errstr(error))); + DEBUG(0, ("Error occured while getting key info: %s\n", + win_errstr(error))); return error; } } else { @@ -62,11 +67,12 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, /* Subkeys that were deleted */ for (i = 0; i < old_num_subkeys; i++) { - error1 = reg_key_get_subkey_by_index(mem_ctx, oldkey, i, &keyname1, - NULL, NULL); + error1 = reg_key_get_subkey_by_index(mem_ctx, oldkey, i, + &keyname1, + NULL, NULL); if (!W_ERROR_IS_OK(error1)) { - DEBUG(0, ("Error occured while getting subkey by index: %s\n", - win_errstr(error2))); + DEBUG(0, ("Error occured while getting subkey by index: %s\n", + win_errstr(error2))); continue; } @@ -81,8 +87,8 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, } if (!W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - DEBUG(0, ("Error occured while getting subkey by name: %s\n", - win_errstr(error2))); + DEBUG(0, ("Error occured while getting subkey by name: %s\n", + win_errstr(error2))); talloc_free(mem_ctx); return error2; } @@ -90,15 +96,16 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, /* newkey didn't have such a subkey, add del diff */ tmppath = talloc_asprintf(mem_ctx, "%s\\%s", path, keyname1); callbacks->del_key(callback_data, tmppath); - talloc_free(tmppath); + talloc_free(tmppath); } if (newkey != NULL) { - error = reg_key_get_info(mem_ctx, newkey, NULL, &new_num_subkeys, &new_num_values, - NULL); + error = reg_key_get_info(mem_ctx, newkey, NULL, + &new_num_subkeys, &new_num_values, + NULL); if (!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error occured while getting key info: %s\n", - win_errstr(error))); + DEBUG(0, ("Error occured while getting key info: %s\n", + win_errstr(error))); return error; } } else { @@ -108,28 +115,29 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, /* Subkeys that were added */ for(i = 0; i < new_num_subkeys; i++) { - error1 = reg_key_get_subkey_by_index(mem_ctx, newkey, i, &keyname1, - NULL, NULL); + error1 = reg_key_get_subkey_by_index(mem_ctx, newkey, + i, &keyname1, + NULL, NULL); if (!W_ERROR_IS_OK(error1)) { - DEBUG(0, ("Error occured while getting subkey by index: %s\n", - win_errstr(error1))); + DEBUG(0, ("Error occured while getting subkey by index: %s\n", + win_errstr(error1))); talloc_free(mem_ctx); return error1; } if (oldkey != NULL) { error2 = reg_open_key(mem_ctx, oldkey, keyname1, &t1); - + if (W_ERROR_IS_OK(error2)) continue; } else { t1 = NULL; error2 = WERR_DEST_NOT_FOUND; } - + if (!W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - DEBUG(0, ("Error occured while getting subkey by name: %s\n", - win_errstr(error2))); + DEBUG(0, ("Error occured while getting subkey by name: %s\n", + win_errstr(error2))); talloc_free(mem_ctx); return error2; } @@ -141,7 +149,8 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, W_ERROR_NOT_OK_RETURN( reg_open_key(mem_ctx, newkey, keyname1, &t2)); - reg_generate_diff_key(t1, t2, tmppath, callbacks, callback_data); + reg_generate_diff_key(t1, t2, tmppath, + callbacks, callback_data); talloc_free(tmppath); } @@ -151,56 +160,59 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, uint32_t type1, type2; DATA_BLOB contents1, contents2; - error1 = reg_key_get_value_by_index(mem_ctx, newkey, i, - &name, &type1, &contents1); + error1 = reg_key_get_value_by_index(mem_ctx, newkey, i, + &name, &type1, &contents1); if (!W_ERROR_IS_OK(error1)) { - DEBUG(0, ("Unable to get key by index: %s\n", - win_errstr(error1))); + DEBUG(0, ("Unable to get key by index: %s\n", + win_errstr(error1))); talloc_free(mem_ctx); return error1; } if (oldkey != NULL) { - error2 = reg_key_get_value_by_name(mem_ctx, oldkey, name, - &type2, &contents2); - } else + error2 = reg_key_get_value_by_name(mem_ctx, oldkey, + name, &type2, + &contents2); + } else error2 = WERR_DEST_NOT_FOUND; - - if(!W_ERROR_IS_OK(error2) && + + if(!W_ERROR_IS_OK(error2) && !W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - DEBUG(0, ("Error occured while getting value by name: %s\n", - win_errstr(error2))); + DEBUG(0, ("Error occured while getting value by name: %s\n", + win_errstr(error2))); talloc_free(mem_ctx); return error2; } - if (W_ERROR_IS_OK(error2) && data_blob_cmp(&contents1, &contents2) == 0) + if (W_ERROR_IS_OK(error2) && + data_blob_cmp(&contents1, &contents2) == 0) continue; - callbacks->set_value(callback_data, path, name, type1, contents1); + callbacks->set_value(callback_data, path, name, + type1, contents1); } /* Values that were deleted */ for (i = 0; i < old_num_values; i++) { const char *name; - error1 = reg_key_get_value_by_index(mem_ctx, oldkey, i, &name, - NULL, NULL); + error1 = reg_key_get_value_by_index(mem_ctx, oldkey, i, &name, + NULL, NULL); if (!W_ERROR_IS_OK(error1)) { - DEBUG(0, ("Error ocurred getting value by index: %s\n", - win_errstr(error1))); + DEBUG(0, ("Error ocurred getting value by index: %s\n", + win_errstr(error1))); talloc_free(mem_ctx); return error1; } - error2 = reg_key_get_value_by_name(mem_ctx, newkey, name, NULL, - NULL); + error2 = reg_key_get_value_by_name(mem_ctx, newkey, name, NULL, + NULL); if (W_ERROR_IS_OK(error2)) continue; if (!W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - DEBUG(0, ("Error occured while getting value by name: %s\n", - win_errstr(error2))); + DEBUG(0, ("Error occured while getting value by name: %s\n", + win_errstr(error2))); return error2; } @@ -212,10 +224,10 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, } /** - * Generate diff between two registry contexts + * Generate diff between two registry contexts */ -_PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1, - struct registry_context *ctx2, +_PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1, + struct registry_context *ctx2, const struct reg_diff_callbacks *callbacks, void *callback_data) { @@ -225,21 +237,27 @@ _PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1, for(i = HKEY_FIRST; i <= HKEY_LAST; i++) { struct registry_key *r1 = NULL, *r2 = NULL; error = reg_get_predefined_key(ctx1, i, &r1); - if (!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_NOT_FOUND)) { - DEBUG(0, ("Unable to open hive %s for backend 1\n", reg_get_predef_name(i))); + if (!W_ERROR_IS_OK(error) && + !W_ERROR_EQUAL(error, WERR_NOT_FOUND)) { + DEBUG(0, ("Unable to open hive %s for backend 1\n", + reg_get_predef_name(i))); } - + error = reg_get_predefined_key(ctx2, i, &r2); - if (!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_NOT_FOUND)) { - DEBUG(0, ("Unable to open hive %s for backend 2\n", reg_get_predef_name(i))); + if (!W_ERROR_IS_OK(error) && + !W_ERROR_EQUAL(error, WERR_NOT_FOUND)) { + DEBUG(0, ("Unable to open hive %s for backend 2\n", + reg_get_predef_name(i))); } if (r1 == NULL && r2 == NULL) continue; - error = reg_generate_diff_key(r1, r2, reg_get_predef_name(i), callbacks, callback_data); + error = reg_generate_diff_key(r1, r2, reg_get_predef_name(i), + callbacks, callback_data); if (!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Unable to determine diff: %s\n", win_errstr(error))); + DEBUG(0, ("Unable to determine diff: %s\n", + win_errstr(error))); return error; } } @@ -252,21 +270,23 @@ _PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1, /** * Load diff file */ -_PUBLIC_ WERROR reg_diff_load(const char *filename, - const struct reg_diff_callbacks *callbacks, +_PUBLIC_ WERROR reg_diff_load(const char *filename, + const struct reg_diff_callbacks *callbacks, void *callback_data) { int fd; char hdr[4]; - + fd = open(filename, O_RDONLY, 0); if (fd == -1) { - DEBUG(0, ("Error opening registry patch file `%s'\n", filename)); + DEBUG(0, ("Error opening registry patch file `%s'\n", + filename)); return WERR_GENERAL_FAILURE; } if (read(fd, &hdr, 4) != 4) { - DEBUG(0, ("Error reading registry patch file `%s'\n", filename)); + DEBUG(0, ("Error reading registry patch file `%s'\n", + filename)); return WERR_GENERAL_FAILURE; } @@ -279,8 +299,8 @@ _PUBLIC_ WERROR reg_diff_load(const char *filename, } else if (strncmp(hdr, "regf", 4) == 0) { /* Must be a REGF NTConfig.pol file */ return reg_regf_diff_load(diff, fd); - } else -#endif + } else +#endif if (strncmp(hdr, "PReg", 4) == 0) { /* Must be a GPO Registry.pol file */ return reg_preg_diff_load(fd, callbacks, callback_data); @@ -293,7 +313,7 @@ _PUBLIC_ WERROR reg_diff_load(const char *filename, /** * The reg_diff_apply functions */ -static WERROR reg_diff_apply_add_key(void *_ctx, const char *key_name) +static WERROR reg_diff_apply_add_key(void *_ctx, const char *key_name) { struct registry_context *ctx = (struct registry_context *)_ctx; struct registry_key *tmp; @@ -301,14 +321,16 @@ static WERROR reg_diff_apply_add_key(void *_ctx, const char *key_name) error = reg_key_add_abs(ctx, ctx, key_name, 0, NULL, &tmp); - if (!W_ERROR_EQUAL(error, WERR_ALREADY_EXISTS) && !W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error adding new key '%s': %s\n", key_name, win_errstr(error))); + if (!W_ERROR_EQUAL(error, WERR_ALREADY_EXISTS) && + !W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error adding new key '%s': %s\n", + key_name, win_errstr(error))); return error; } return WERR_OK; } -static WERROR reg_diff_apply_del_key(void *_ctx, const char *key_name) +static WERROR reg_diff_apply_del_key(void *_ctx, const char *key_name) { struct registry_context *ctx = (struct registry_context *)_ctx; WERROR error; @@ -319,16 +341,18 @@ static WERROR reg_diff_apply_del_key(void *_ctx, const char *key_name) DEBUG(0, ("Unable to delete key '%s'\n", key_name)); return error; } - + return WERR_OK; } -static WERROR reg_diff_apply_set_value(void *_ctx, const char *path, const char *value_name, uint32_t value_type, DATA_BLOB value) +static WERROR reg_diff_apply_set_value(void *_ctx, const char *path, + const char *value_name, + uint32_t value_type, DATA_BLOB value) { struct registry_context *ctx = (struct registry_context *)_ctx; struct registry_key *tmp; WERROR error; - + /* Open key */ error = reg_open_key_abs(ctx, ctx, path, &tmp); @@ -338,22 +362,23 @@ static WERROR reg_diff_apply_set_value(void *_ctx, const char *path, const char } /* Set value */ - error = reg_val_set(tmp, value_name, + error = reg_val_set(tmp, value_name, value_type, value); if (!W_ERROR_IS_OK(error)) { DEBUG(0, ("Error setting value '%s'\n", value_name)); return error; - } - + } + return WERR_OK; } -static WERROR reg_diff_apply_del_value (void *_ctx, const char *key_name, const char *value_name) +static WERROR reg_diff_apply_del_value(void *_ctx, const char *key_name, + const char *value_name) { struct registry_context *ctx = (struct registry_context *)_ctx; struct registry_key *tmp; WERROR error; - + /* Open key */ error = reg_open_key_abs(ctx, ctx, key_name, &tmp); @@ -367,7 +392,7 @@ static WERROR reg_diff_apply_del_value (void *_ctx, const char *key_name, const DEBUG(0, ("Error deleting value '%s'\n", value_name)); return error; } - + return WERR_OK; } @@ -387,26 +412,28 @@ static WERROR reg_diff_apply_del_all_values(void *_ctx, const char *key_name) return error; } - W_ERROR_NOT_OK_RETURN(reg_key_get_info(ctx, key, - NULL, - NULL, - &num_values, - NULL)); + W_ERROR_NOT_OK_RETURN(reg_key_get_info(ctx, key, + NULL, + NULL, + &num_values, + NULL)); for (i = 0; i < num_values; i++) { const char *name; - W_ERROR_NOT_OK_RETURN(reg_key_get_value_by_index(ctx, key, i, &name, - NULL, NULL)); + W_ERROR_NOT_OK_RETURN(reg_key_get_value_by_index(ctx, key, i, + &name, + NULL, NULL)); W_ERROR_NOT_OK_RETURN(reg_del_value(key, name)); } return WERR_OK; } -/** - * Apply diff to a registry context +/** + * Apply diff to a registry context */ -_PUBLIC_ WERROR reg_diff_apply (const char *filename, struct registry_context *ctx) +_PUBLIC_ WERROR reg_diff_apply(const char *filename, + struct registry_context *ctx) { struct reg_diff_callbacks callbacks; diff --git a/source4/lib/registry/patchfile.h b/source4/lib/registry/patchfile.h index 1c0b195a8c..4c0599b2f3 100644 --- a/source4/lib/registry/patchfile.h +++ b/source4/lib/registry/patchfile.h @@ -1,52 +1,55 @@ -/* +/* Unix SMB/CIFS implementation. Patchfile interface Copyright (C) Jelmer Vernooij 2006 Copyright (C) Wilco Baan Hofman 2006 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _PATCHFILE_H -#define _PATCHFILE_H +#define _PATCHFILE_H #include "lib/registry/registry.h" struct reg_diff_callbacks { WERROR (*add_key) (void *callback_data, const char *key_name); - WERROR (*set_value) (void *callback_data, const char *key_name, - const char *value_name, uint32_t value_type, DATA_BLOB value); - WERROR (*del_value) (void *callback_data, const char *key_name, const char *value_name); + WERROR (*set_value) (void *callback_data, const char *key_name, + const char *value_name, uint32_t value_type, + DATA_BLOB value); + WERROR (*del_value) (void *callback_data, const char *key_name, + const char *value_name); WERROR (*del_key) (void *callback_data, const char *key_name); WERROR (*del_all_values) (void *callback_data, const char *key_name); WERROR (*done) (void *callback_data); }; -WERROR reg_diff_apply (const char *filename, - struct registry_context *ctx); - -WERROR reg_generate_diff(struct registry_context *ctx1, - struct registry_context *ctx2, - const struct reg_diff_callbacks *callbacks, - void *callback_data); -WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, - struct reg_diff_callbacks **callbacks, void **callback_data); -WERROR reg_generate_diff_key(struct registry_key *oldkey, - struct registry_key *newkey, - const char *path, - const struct reg_diff_callbacks *callbacks, - void *callback_data); +WERROR reg_diff_apply (const char *filename, + struct registry_context *ctx); + +WERROR reg_generate_diff(struct registry_context *ctx1, + struct registry_context *ctx2, + const struct reg_diff_callbacks *callbacks, + void *callback_data); +WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, + struct reg_diff_callbacks **callbacks, + void **callback_data); +WERROR reg_generate_diff_key(struct registry_key *oldkey, + struct registry_key *newkey, + const char *path, + const struct reg_diff_callbacks *callbacks, + void *callback_data); #endif /* _PATCHFILE_H */ diff --git a/source4/lib/registry/patchfile_dotreg.c b/source4/lib/registry/patchfile_dotreg.c index 85cf8ab251..ebcafc92af 100644 --- a/source4/lib/registry/patchfile_dotreg.c +++ b/source4/lib/registry/patchfile_dotreg.c @@ -1,7 +1,7 @@ -/* +/* Unix SMB/CIFS implementation. Reading .REG files - + Copyright (C) Jelmer Vernooij 2004-2007 Copyright (C) Wilco Baan Hofman 2006 @@ -9,12 +9,12 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -43,7 +43,7 @@ static WERROR reg_dotreg_diff_add_key(void *_data, const char *key_name) struct dotreg_data *data = (struct dotreg_data *)_data; fdprintf(data->fd, "\n[%s]\n", key_name); - + return WERR_OK; } @@ -52,23 +52,25 @@ static WERROR reg_dotreg_diff_del_key(void *_data, const char *key_name) struct dotreg_data *data = (struct dotreg_data *)_data; fdprintf(data->fd, "\n[-%s]\n", key_name); - + return WERR_OK; } -static WERROR reg_dotreg_diff_set_value(void *_data, const char *path, - const char *value_name, uint32_t value_type, DATA_BLOB value) +static WERROR reg_dotreg_diff_set_value(void *_data, const char *path, + const char *value_name, + uint32_t value_type, DATA_BLOB value) { struct dotreg_data *data = (struct dotreg_data *)_data; fdprintf(data->fd, "\"%s\"=%s:%s\n", - value_name, str_regtype(value_type), + value_name, str_regtype(value_type), reg_val_data_string(NULL, value_type, value)); - + return WERR_OK; } -static WERROR reg_dotreg_diff_del_value(void *_data, const char *path, const char *value_name) +static WERROR reg_dotreg_diff_del_value(void *_data, const char *path, + const char *value_name) { struct dotreg_data *data = (struct dotreg_data *)_data; @@ -87,7 +89,8 @@ static WERROR reg_dotreg_diff_done(void *_data) return WERR_OK; } -static WERROR reg_dotreg_diff_del_all_values (void *callback_data, const char *key_name) +static WERROR reg_dotreg_diff_del_all_values(void *callback_data, + const char *key_name) { return WERR_NOT_SUPPORTED; } @@ -95,8 +98,9 @@ static WERROR reg_dotreg_diff_del_all_values (void *callback_data, const char *k /** * Save registry diff */ -_PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, - struct reg_diff_callbacks **callbacks, void **callback_data) +_PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, + struct reg_diff_callbacks **callbacks, + void **callback_data) { struct dotreg_data *data; @@ -125,13 +129,14 @@ _PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, (*callbacks)->done = reg_dotreg_diff_done; return WERR_OK; -} +} /** * Load diff file */ -_PUBLIC_ WERROR reg_dotreg_diff_load(int fd, - const struct reg_diff_callbacks *callbacks, void *callback_data) +_PUBLIC_ WERROR reg_dotreg_diff_load(int fd, + const struct reg_diff_callbacks *callbacks, + void *callback_data) { char *line, *p, *q; char *curkey = NULL; @@ -152,8 +157,8 @@ _PUBLIC_ WERROR reg_dotreg_diff_load(int fd, /* Ignore comments and empty lines */ if (strlen(line) == 0 || line[0] == ';') { talloc_free(line); - - if (curkey) { + + if (curkey) { talloc_free(curkey); } curkey = NULL; @@ -171,9 +176,11 @@ _PUBLIC_ WERROR reg_dotreg_diff_load(int fd, if (line[1] == '-') { curkey = talloc_strndup(line, line+2, strlen(line)-3); - error = callbacks->del_key(callback_data, curkey); + error = callbacks->del_key(callback_data, + curkey); if (!W_ERROR_IS_OK(error)) { - DEBUG(0,("Error deleting key %s\n", curkey)); + DEBUG(0,("Error deleting key %s\n", + curkey)); talloc_free(mem_ctx); return error; } @@ -213,9 +220,11 @@ _PUBLIC_ WERROR reg_dotreg_diff_load(int fd, /* Delete value */ if (strcmp(p, "-") == 0) { - error = callbacks->del_value(callback_data, curkey, line); + error = callbacks->del_value(callback_data, + curkey, line); if (!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error deleting value %s in key %s\n", line, curkey)); + DEBUG(0, ("Error deleting value %s in key %s\n", + line, curkey)); talloc_free(mem_ctx); return error; } @@ -223,18 +232,21 @@ _PUBLIC_ WERROR reg_dotreg_diff_load(int fd, talloc_free(line); continue; } - + q = strchr_m(p, ':'); if (q) { - *q = '\0'; + *q = '\0'; q++; } - reg_string_to_val(line, q?p:"REG_SZ", q?q:p, &value_type, &value); - - error = callbacks->set_value(callback_data, curkey, line, value_type, value); + reg_string_to_val(line, q?p:"REG_SZ", q?q:p, + &value_type, &value); + + error = callbacks->set_value(callback_data, curkey, line, + value_type, value); if (!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error setting value for %s in %s\n", line, curkey)); + DEBUG(0, ("Error setting value for %s in %s\n", + line, curkey)); talloc_free(mem_ctx); return error; } diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c index 20bd2fad0d..90a4f2529a 100644 --- a/source4/lib/registry/patchfile_preg.c +++ b/source4/lib/registry/patchfile_preg.c @@ -1,19 +1,19 @@ -/* +/* Unix SMB/CIFS implementation. Reading Registry.pol PReg registry files - + Copyright (C) Wilco Baan Hofman 2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -53,13 +53,16 @@ static WERROR reg_preg_diff_del_key(void *_data, const char *key_name) return WERR_OK; } -static WERROR reg_preg_diff_set_value(void *_data, const char *key_name, const char *value_name, uint32_t value_type, DATA_BLOB value_data) +static WERROR reg_preg_diff_set_value(void *_data, const char *key_name, + const char *value_name, + uint32_t value_type, DATA_BLOB value_data) { struct preg_data *data = (struct preg_data *)_data; return WERR_OK; } -static WERROR reg_preg_diff_del_value(void *_data, const char *key_name, const char *value_name) +static WERROR reg_preg_diff_del_value(void *_data, const char *key_name, + const char *value_name) { struct preg_data *data = (struct preg_data *)_data; return WERR_OK; @@ -83,14 +86,16 @@ static WERROR reg_preg_diff_done(void *_data) /** * Save registry diff */ -_PUBLIC_ WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename, struct reg_diff_callbacks **callbacks, void **callback_data) +_PUBLIC_ WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename, + struct reg_diff_callbacks **callbacks, + void **callback_data) { struct preg_data *data; struct { char hdr[4]; uint32_t version; } preg_header; - + data = talloc_zero(ctx, struct preg_data); *callback_data = data; @@ -106,23 +111,25 @@ _PUBLIC_ WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename, struct } snprintf(preg_header.hdr, 4, "PReg"); SIVAL(&preg_header, 4, 1); - write(data->fd, (uint8_t *)&preg_header,8); + write(data->fd, (uint8_t *)&preg_header,8); *callbacks = talloc(ctx, struct reg_diff_callbacks); - + (*callbacks)->add_key = reg_preg_diff_add_key; (*callbacks)->del_key = reg_preg_diff_del_key; (*callbacks)->set_value = reg_preg_diff_set_value; (*callbacks)->del_value = reg_preg_diff_del_value; (*callbacks)->del_all_values = reg_preg_diff_del_all_values; (*callbacks)->done = reg_preg_diff_done; - + return WERR_OK; } /** * Load diff file */ -_PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *callbacks, void *callback_data) +_PUBLIC_ WERROR reg_preg_diff_load(int fd, + const struct reg_diff_callbacks *callbacks, + void *callback_data) { struct { char hdr[4]; @@ -132,7 +139,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *call char *buf_ptr = buf; TALLOC_CTX *mem_ctx = talloc_init("reg_preg_diff_load"); - + /* Read first 8 bytes (the header) */ if (read(fd, &preg_header, 8) != 8) { DEBUG(0, ("Could not read PReg file: %s\n", @@ -147,14 +154,14 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *call } if (preg_header.version > 1) { DEBUG(0, ("Warning: file format version is higher than expected.\n")); - } + } /* Read the entries */ while(1) { char *key, *value_name; uint32_t value_type, length; DATA_BLOB data; - + if (!W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr))) { break; } @@ -163,17 +170,19 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *call close(fd); return WERR_GENERAL_FAILURE; } - + /* Get the path */ buf_ptr = buf; - while (W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr != ';' && buf_ptr-buf < sizeof(buf)) { + while (W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && + *buf_ptr != ';' && buf_ptr-buf < sizeof(buf)) { buf_ptr++; } key = talloc_asprintf(mem_ctx, "\\%s", buf); - + /* Get the name */ buf_ptr = buf; - while (W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr != ';' && buf_ptr-buf < sizeof(buf)) { + while (W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && + *buf_ptr != ';' && buf_ptr-buf < sizeof(buf)) { buf_ptr++; } value_name = talloc_strdup(mem_ctx, buf); @@ -186,7 +195,8 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *call } /* Read past delimiter */ buf_ptr = buf; - if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr == ';') && buf_ptr-buf < sizeof(buf)) { + if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && + *buf_ptr == ';') && buf_ptr-buf < sizeof(buf)) { DEBUG(0, ("Error in PReg file.\n")); close(fd); return WERR_GENERAL_FAILURE; @@ -199,39 +209,43 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *call } /* Read past delimiter */ buf_ptr = buf; - if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr == ';') && buf_ptr-buf < sizeof(buf)) { + if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && + *buf_ptr == ';') && buf_ptr-buf < sizeof(buf)) { DEBUG(0, ("Error in PReg file.\n")); close(fd); return WERR_GENERAL_FAILURE; - } + } /* Get the data */ buf_ptr = buf; - if (length < sizeof(buf) && read(fd, buf_ptr, length) != length) { + if (length < sizeof(buf) && + read(fd, buf_ptr, length) != length) { DEBUG(0, ("Error while reading PReg\n")); close(fd); return WERR_GENERAL_FAILURE; } data = data_blob_talloc(mem_ctx, buf, length); - + /* Check if delimiter is in place (whine if it isn't) */ buf_ptr = buf; - if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr == ']') && buf_ptr-buf < sizeof(buf)) { - DEBUG(0, ("Warning: Missing ']' in PReg file, expected ']', got '%c' 0x%x.\n",*buf_ptr, *buf_ptr)); + if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && + *buf_ptr == ']') && buf_ptr-buf < sizeof(buf)) { + DEBUG(0, ("Warning: Missing ']' in PReg file, expected ']', got '%c' 0x%x.\n", + *buf_ptr, *buf_ptr)); } if (strcasecmp(value_name, "**DelVals") == 0) { callbacks->del_all_values(callback_data, key); } else if (strncasecmp(value_name, "**Del.",6) == 0) { char *p = value_name+6; - + callbacks->del_value(callback_data, key, p); } else if (strcasecmp(value_name, "**DeleteValues") == 0) { char *p, *q; p = (char *) data.data; - + while ((q = strchr_m(p, ';'))) { - *q = '\0'; + *q = '\0'; q++; callbacks->del_value(callback_data, key, p); @@ -243,28 +257,30 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *call char *p, *q, *full_key; p = (char *) data.data; - + while ((q = strchr_m(p, ';'))) { *q = '\0'; q++; - - full_key = talloc_asprintf(mem_ctx, "%s\\%s", key, p); + + full_key = talloc_asprintf(mem_ctx, "%s\\%s", + key, p); callbacks->del_key(callback_data, full_key); talloc_free(full_key); - p = q; + p = q; } full_key = talloc_asprintf(mem_ctx, "%s\\%s", key, p); callbacks->del_key(callback_data, full_key); talloc_free(full_key); } else { callbacks->add_key(callback_data, key); - callbacks->set_value(callback_data, key, value_name, value_type, data); + callbacks->set_value(callback_data, key, value_name, + value_type, data); } talloc_free(key); talloc_free(value_name); talloc_free(data.data); } - close(fd); + close(fd); return WERR_OK; } diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 17914a8f7c..2dd27ca33d 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -8,15 +8,15 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ - + #include "includes.h" #include "lib/registry/hive.h" #include "system/filesys.h" @@ -28,7 +28,7 @@ static struct hive_operations reg_backend_regf; /** - * There are several places on the web where the REGF format is explained; + * There are several places on the web where the REGF format is explained; * * TODO: Links */ @@ -53,18 +53,18 @@ static WERROR regf_save_hbin(struct regf_data *data); struct regf_key_data { struct hive_key key; - struct regf_data *hive; + struct regf_data *hive; uint32_t offset; struct nk_block *nk; }; -static struct hbin_block *hbin_by_offset(const struct regf_data *data, - uint32_t offset, uint32_t *rel_offset) +static struct hbin_block *hbin_by_offset(const struct regf_data *data, + uint32_t offset, uint32_t *rel_offset) { int i; for (i = 0; data->hbins[i]; i++) { - if (offset >= data->hbins[i]->offset_from_first && + if (offset >= data->hbins[i]->offset_from_first && offset < data->hbins[i]->offset_from_first+ data->hbins[i]->offset_to_next) { if (rel_offset != NULL) @@ -84,7 +84,7 @@ static uint32_t regf_hdr_checksum(const uint8_t *buffer) { uint32_t checksum = 0, x; int i; - + for (i = 0; i < 0x01FB; i+= 4) { x = IVAL(buffer, i); checksum ^= x; @@ -122,14 +122,14 @@ static DATA_BLOB hbin_get(const struct regf_data *data, uint32_t offset) ret.length = (ret.length ^ 0xffffffff) + 1; ret.length -= 4; /* 4 bytes for the length... */ - ret.data = hbin->data + + ret.data = hbin->data + (offset - hbin->offset_from_first - 0x20) + 4; - + return ret; } -static bool hbin_get_tdr (struct regf_data *regf, uint32_t offset, - TALLOC_CTX *ctx, tdr_pull_fn_t pull_fn, void *p) +static bool hbin_get_tdr(struct regf_data *regf, uint32_t offset, + TALLOC_CTX *ctx, tdr_pull_fn_t pull_fn, void *p) { struct tdr_pull pull; @@ -140,9 +140,10 @@ static bool hbin_get_tdr (struct regf_data *regf, uint32_t offset, DEBUG(1, ("Unable to get data at 0x%04x\n", offset)); return false; } - + if (NT_STATUS_IS_ERR(pull_fn(&pull, ctx, p))) { - DEBUG(1, ("Error parsing record at 0x%04x using tdr\n", offset)); + DEBUG(1, ("Error parsing record at 0x%04x using tdr\n", + offset)); return false; } @@ -150,8 +151,8 @@ static bool hbin_get_tdr (struct regf_data *regf, uint32_t offset, } /* Allocate some new data */ -static DATA_BLOB hbin_alloc(struct regf_data *data, uint32_t size, - uint32_t *offset) +static DATA_BLOB hbin_alloc(struct regf_data *data, uint32_t size, + uint32_t *offset) { DATA_BLOB ret; uint32_t rel_offset = -1; /* Relative offset ! */ @@ -190,13 +191,15 @@ static DATA_BLOB hbin_alloc(struct regf_data *data, uint32_t size, my_size = -my_size; } else if (my_size == size) { /* exact match */ rel_offset = j; - DEBUG(4, ("Found free block of exact size %d in middle of HBIN\n", size)); + DEBUG(4, ("Found free block of exact size %d in middle of HBIN\n", + size)); break; } else if (my_size > size) { /* data will remain */ rel_offset = j; /* Split this block and mark the next block as free */ - SIVAL(hbin->data, rel_offset+size, my_size-size); - DEBUG(4, ("Found free block of size %d (needing %d) in middle of HBIN\n", my_size, size)); + SIVAL(hbin->data, rel_offset+size, my_size-size); + DEBUG(4, ("Found free block of size %d (needing %d) in middle of HBIN\n", + my_size, size)); break; } } @@ -204,12 +207,14 @@ static DATA_BLOB hbin_alloc(struct regf_data *data, uint32_t size, if (rel_offset != -1) break; } - - /* No space available in previous hbins, + + /* No space available in previous hbins, * allocate new one */ - if (data->hbins[i] == NULL) { - DEBUG(4, ("No space available in other HBINs for block of size %d, allocating new HBIN\n", size)); - data->hbins = talloc_realloc(data, data->hbins, struct hbin_block *, i+2); + if (data->hbins[i] == NULL) { + DEBUG(4, ("No space available in other HBINs for block of size %d, allocating new HBIN\n", + size)); + data->hbins = talloc_realloc(data, data->hbins, + struct hbin_block *, i+2); hbin = talloc(data->hbins, struct hbin_block); SMB_ASSERT(hbin != NULL); @@ -255,11 +260,12 @@ static uint32_t hbin_store (struct regf_data *data, DATA_BLOB blob) return ret; } -static uint32_t hbin_store_tdr (struct regf_data *data, tdr_push_fn_t push_fn, void *p) +static uint32_t hbin_store_tdr(struct regf_data *data, + tdr_push_fn_t push_fn, void *p) { struct tdr_push *push = talloc_zero(data, struct tdr_push); uint32_t ret; - + if (NT_STATUS_IS_ERR(push_fn(push, p))) { DEBUG(0, ("Error during push\n")); return -1; @@ -278,26 +284,27 @@ static void hbin_free (struct regf_data *data, uint32_t offset) { int32_t size; uint32_t rel_offset; - int32_t next_size; + int32_t next_size; struct hbin_block *hbin; SMB_ASSERT (offset > 0); - + hbin = hbin_by_offset(data, offset, &rel_offset); if (hbin == NULL) return; - + /* Get original size */ size = IVALS(hbin->data, rel_offset); if (size > 0) { - DEBUG(1, ("Trying to free already freed block at 0x%04x\n", offset)); + DEBUG(1, ("Trying to free already freed block at 0x%04x\n", + offset)); return; } /* Mark as unused */ size = -size; - + /* If the next block is free, merge into big free block */ if (rel_offset + size < hbin->offset_to_next) { next_size = IVALS(hbin->data, rel_offset+size); @@ -312,13 +319,14 @@ static void hbin_free (struct regf_data *data, uint32_t offset) /** * Store a data blob data was already stored, but has changed in size - * Will try to save it at the current location if possible, otherwise + * Will try to save it at the current location if possible, otherwise * does a free + store */ -static uint32_t hbin_store_resize(struct regf_data *data, - uint32_t orig_offset, DATA_BLOB blob) +static uint32_t hbin_store_resize(struct regf_data *data, + uint32_t orig_offset, DATA_BLOB blob) { uint32_t rel_offset; - struct hbin_block *hbin = hbin_by_offset(data, orig_offset, &rel_offset); + struct hbin_block *hbin = hbin_by_offset(data, orig_offset, + &rel_offset); int32_t my_size; int32_t orig_size; int32_t needed_size; @@ -343,7 +351,8 @@ static uint32_t hbin_store_resize(struct regf_data *data, * and free/merge it */ if (orig_size - needed_size > 0x4) { SIVALS(hbin->data, rel_offset, -needed_size); - SIVALS(hbin->data, rel_offset + needed_size, needed_size-orig_size); + SIVALS(hbin->data, rel_offset + needed_size, + needed_size-orig_size); hbin_free(data, orig_offset + needed_size); } return orig_offset; @@ -357,7 +366,7 @@ static uint32_t hbin_store_resize(struct regf_data *data, break; my_size = IVALS(hbin->data, i); - + if (my_size == 0x0) { DEBUG(0, ("Invalid zero-length block! File is corrupt.\n")); break; @@ -367,7 +376,8 @@ static uint32_t hbin_store_resize(struct regf_data *data, if (possible_size >= blob.length) { SIVAL(hbin->data, rel_offset, -possible_size); - memcpy(hbin->data + rel_offset + 0x4, blob.data, blob.length); + memcpy(hbin->data + rel_offset + 0x4, + blob.data, blob.length); return orig_offset; } } @@ -376,12 +386,13 @@ static uint32_t hbin_store_resize(struct regf_data *data, return hbin_store(data, blob); } -static uint32_t hbin_store_tdr_resize (struct regf_data *regf, tdr_push_fn_t push_fn, - uint32_t orig_offset, void *p) +static uint32_t hbin_store_tdr_resize(struct regf_data *regf, + tdr_push_fn_t push_fn, + uint32_t orig_offset, void *p) { struct tdr_push *push = talloc_zero(regf, struct tdr_push); uint32_t ret; - + if (NT_STATUS_IS_ERR(push_fn(push, p))) { DEBUG(0, ("Error during push\n")); return -1; @@ -394,13 +405,13 @@ static uint32_t hbin_store_tdr_resize (struct regf_data *regf, tdr_push_fn_t pus return ret; } -static uint32_t regf_create_lh_hash(const char *name) +static uint32_t regf_create_lh_hash(const char *name) { char *hash_name; uint32_t ret = 0; uint16_t i; - hash_name = strupper_talloc(NULL, name); + hash_name = strupper_talloc(NULL, name); for (i = 0; *(hash_name + i) != 0; i++) { ret *= 37; ret += *(hash_name + i); @@ -409,14 +420,14 @@ static uint32_t regf_create_lh_hash(const char *name) return ret; } -static WERROR regf_get_info (TALLOC_CTX *mem_ctx, - const struct hive_key *key, - const char **classname, - uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_mod_time) +static WERROR regf_get_info(TALLOC_CTX *mem_ctx, + const struct hive_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_mod_time) { - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)key; if (num_subkeys != NULL) @@ -427,22 +438,23 @@ static WERROR regf_get_info (TALLOC_CTX *mem_ctx, if (classname != NULL) { if (private_data->nk->clsname_offset != -1) { - DATA_BLOB data = hbin_get(private_data->hive, - private_data->nk->clsname_offset); - *classname = talloc_strndup(mem_ctx, - (char*)data.data, private_data->nk->clsname_length); - } else + DATA_BLOB data = hbin_get(private_data->hive, + private_data->nk->clsname_offset); + *classname = talloc_strndup(mem_ctx, + (char*)data.data, + private_data->nk->clsname_length); + } else *classname = NULL; } /* TODO: Last mod time */ - + return WERR_OK; } -static struct regf_key_data *regf_get_key(TALLOC_CTX *ctx, - struct regf_data *regf, - uint32_t offset) +static struct regf_key_data *regf_get_key(TALLOC_CTX *ctx, + struct regf_data *regf, + uint32_t offset) { struct nk_block *nk; struct regf_key_data *ret; @@ -457,7 +469,8 @@ static struct regf_key_data *regf_get_key(TALLOC_CTX *ctx, ret->nk = nk; - if (!hbin_get_tdr(regf, offset, nk, (tdr_pull_fn_t)tdr_pull_nk_block, nk)) { + if (!hbin_get_tdr(regf, offset, nk, + (tdr_pull_fn_t)tdr_pull_nk_block, nk)) { DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset)); return NULL; } @@ -472,11 +485,11 @@ static struct regf_key_data *regf_get_key(TALLOC_CTX *ctx, } -static WERROR regf_get_value(TALLOC_CTX *ctx, const struct hive_key *key, - int idx, const char **name, - uint32_t *data_type, DATA_BLOB *data) +static WERROR regf_get_value(TALLOC_CTX *ctx, const struct hive_key *key, + int idx, const char **name, + uint32_t *data_type, DATA_BLOB *data) { - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)key; struct vk_block *vk; struct regf_data *regf = private_data->hive; @@ -500,8 +513,9 @@ static WERROR regf_get_value(TALLOC_CTX *ctx, const struct hive_key *key, vk = talloc(NULL, struct vk_block); W_ERROR_HAVE_NO_MEMORY(vk); - - if (!hbin_get_tdr(regf, vk_offset, vk, (tdr_pull_fn_t)tdr_pull_vk_block, vk)) { + + if (!hbin_get_tdr(regf, vk_offset, vk, + (tdr_pull_fn_t)tdr_pull_vk_block, vk)) { DEBUG(0, ("Unable to get VK block at %d\n", vk_offset)); talloc_free(vk); return WERR_GENERAL_FAILURE; @@ -514,7 +528,7 @@ static WERROR regf_get_value(TALLOC_CTX *ctx, const struct hive_key *key, if (data_type != NULL) *data_type = vk->data_type; - if (vk->data_length & 0x80000000) { + if (vk->data_length & 0x80000000) { vk->data_length &=~0x80000000; data->data = (uint8_t *)&vk->data_offset; data->length = vk->data_length; @@ -527,13 +541,13 @@ static WERROR regf_get_value(TALLOC_CTX *ctx, const struct hive_key *key, } talloc_free(vk); - + return WERR_OK; } -static WERROR regf_get_value_by_name (TALLOC_CTX *mem_ctx, - struct hive_key *key, const char *name, - uint32_t *type, DATA_BLOB *data) +static WERROR regf_get_value_by_name(TALLOC_CTX *mem_ctx, + struct hive_key *key, const char *name, + uint32_t *type, DATA_BLOB *data) { int i; const char *vname; @@ -541,24 +555,25 @@ static WERROR regf_get_value_by_name (TALLOC_CTX *mem_ctx, /* FIXME: Do binary search? Is this list sorted at all? */ - for (i = 0; W_ERROR_IS_OK(error = regf_get_value(mem_ctx, key, i, - &vname, type, data)); i++) { + for (i = 0; W_ERROR_IS_OK(error = regf_get_value(mem_ctx, key, i, + &vname, type, data)); + i++) { if (!strcmp(vname, name)) return WERR_OK; - } + } if (W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) return WERR_NOT_FOUND; return error; } - -static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, - const struct hive_key *key, - uint32_t idx, const char **name, - const char **classname, - NTTIME *last_mod_time) + +static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx, + const struct hive_key *key, + uint32_t idx, const char **name, + const char **classname, + NTTIME *last_mod_time) { DATA_BLOB data; struct regf_key_data *ret; @@ -594,7 +609,7 @@ static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, return WERR_GENERAL_FAILURE; } key_off = li.nk_offset[idx]; - + } else if (!strncmp((char *)data.data, "lf", 2)) { struct lf_block lf; struct tdr_pull pull; @@ -618,17 +633,17 @@ static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, } else if (!strncmp((char *)data.data, "lh", 2)) { struct lh_block lh; struct tdr_pull pull; - + DEBUG(10, ("Subkeys in LH list\n")); ZERO_STRUCT(pull); pull.data = data; - + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { DEBUG(0, ("Error parsing LH list\n")); return WERR_GENERAL_FAILURE; } SMB_ASSERT(!strncmp(lh.header, "lh", 2)); - + if (lh.key_count != nk->num_subkeys) { DEBUG(0, ("Subkey counts don't match\n")); return WERR_GENERAL_FAILURE; @@ -639,41 +654,43 @@ static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, struct tdr_pull pull; uint16_t i; uint16_t sublist_count = 0; - + DEBUG(10, ("Subkeys in RI list\n")); ZERO_STRUCT(pull); pull.data = data; - + if (NT_STATUS_IS_ERR(tdr_pull_ri_block(&pull, nk, &ri))) { DEBUG(0, ("Error parsing RI list\n")); return WERR_GENERAL_FAILURE; } SMB_ASSERT(!strncmp(ri.header, "ri", 2)); - + for (i = 0; i < ri.key_count; i++) { DATA_BLOB list_data; - + /* Get sublist data blob */ list_data = hbin_get(private_data->hive, ri.offset[i]); if (!list_data.data) { DEBUG(0, ("Error getting RI list.")); return WERR_GENERAL_FAILURE; } - + ZERO_STRUCT(pull); pull.data = list_data; - + if (!strncmp((char *)list_data.data, "li", 2)) { struct li_block li; DEBUG(10, ("Subkeys in RI->LI list\n")); - if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { + if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, + nk, + &li))) { DEBUG(0, ("Error parsing LI list from RI\n")); return WERR_GENERAL_FAILURE; } SMB_ASSERT(!strncmp(li.header, "li", 2)); - + /* Advance to next sublist if necessary */ if (idx >= sublist_count + li.key_count) { sublist_count += li.key_count; @@ -684,10 +701,12 @@ static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, break; } else if (!strncmp((char *)list_data.data, "lh", 2)) { struct lh_block lh; - + DEBUG(10, ("Subkeys in RI->LH list\n")); - if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, + nk, + &lh))) { DEBUG(0, ("Error parsing LH list from RI\n")); return WERR_GENERAL_FAILURE; } @@ -706,15 +725,15 @@ static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, return WERR_GENERAL_FAILURE; } - + } - + if (idx > sublist_count) { return WERR_NO_MORE_ITEMS; } } else { - DEBUG(0, ("Unknown type for subkey list (0x%04x): %c%c\n", + DEBUG(0, ("Unknown type for subkey list (0x%04x): %c%c\n", nk->subkeys_offset, data.data[0], data.data[1])); return WERR_GENERAL_FAILURE; } @@ -723,11 +742,12 @@ static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, if (classname != NULL) { if (ret->nk->clsname_offset != -1) { - DATA_BLOB db = hbin_get(ret->hive, - ret->nk->clsname_offset); - *classname = talloc_strndup(ctx, - (char*)db.data, ret->nk->clsname_length); - } else + DATA_BLOB db = hbin_get(ret->hive, + ret->nk->clsname_offset); + *classname = talloc_strndup(ctx, + (char*)db.data, + ret->nk->clsname_length); + } else *classname = NULL; } @@ -742,16 +762,17 @@ static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, return WERR_OK; } -static WERROR regf_match_subkey_by_name(TALLOC_CTX *ctx, - const struct hive_key *key, uint32_t offset, - const char *name, uint32_t *ret) +static WERROR regf_match_subkey_by_name(TALLOC_CTX *ctx, + const struct hive_key *key, + uint32_t offset, + const char *name, uint32_t *ret) { DATA_BLOB subkey_data; struct nk_block subkey; struct tdr_pull pull; - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)key; - + subkey_data = hbin_get(private_data->hive, offset); if (!subkey_data.data) { DEBUG(0, ("Unable to retrieve subkey HBIN\n")); @@ -760,7 +781,7 @@ static WERROR regf_match_subkey_by_name(TALLOC_CTX *ctx, ZERO_STRUCT(pull); pull.data = subkey_data; - + if (NT_STATUS_IS_ERR(tdr_pull_nk_block(&pull, ctx, &subkey))) { DEBUG(0, ("Error parsing NK structure.\n")); return WERR_GENERAL_FAILURE; @@ -778,14 +799,14 @@ static WERROR regf_match_subkey_by_name(TALLOC_CTX *ctx, } return WERR_OK; } - -static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, - const struct hive_key *key, - const char *name, - struct hive_key **ret) + +static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, + const struct hive_key *key, + const char *name, + struct hive_key **ret) { DATA_BLOB data; - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)key; struct nk_block *nk = private_data->nk; uint32_t key_off = 0; @@ -804,7 +825,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, DEBUG(10, ("Subkeys in LI list\n")); ZERO_STRUCT(pull); pull.data = data; - + if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { DEBUG(0, ("Error parsing LI list\n")); return WERR_GENERAL_FAILURE; @@ -815,9 +836,12 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, DEBUG(0, ("Subkey counts don't match\n")); return WERR_GENERAL_FAILURE; } - + for (i = 0; i < li.key_count; i++) { - W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, li.nk_offset[i], name, &key_off)); + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, + li.nk_offset[i], + name, + &key_off)); if (key_off != 0) break; } @@ -831,7 +855,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, DEBUG(10, ("Subkeys in LF list\n")); ZERO_STRUCT(pull); pull.data = data; - + if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, nk, &lf))) { DEBUG(0, ("Error parsing LF list\n")); return WERR_GENERAL_FAILURE; @@ -842,12 +866,16 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, DEBUG(0, ("Subkey counts don't match\n")); return WERR_GENERAL_FAILURE; } - + for (i = 0; i < lf.key_count; i++) { if (strncmp(lf.hr[i].hash, name, 4)) { continue; } - W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, lf.hr[i].nk_offset, name, &key_off)); + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, + key, + lf.hr[i].nk_offset, + name, + &key_off)); if (key_off != 0) break; } @@ -862,7 +890,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, DEBUG(10, ("Subkeys in LH list\n")); ZERO_STRUCT(pull); pull.data = data; - + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { DEBUG(0, ("Error parsing LH list\n")); return WERR_GENERAL_FAILURE; @@ -873,16 +901,20 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, DEBUG(0, ("Subkey counts don't match\n")); return WERR_GENERAL_FAILURE; } - + hash = regf_create_lh_hash(name); for (i = 0; i < lh.key_count; i++) { if (lh.hr[i].base37 != hash) { continue; } - W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, lh.hr[i].nk_offset, name, &key_off)); + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, + key, + lh.hr[i].nk_offset, + name, + &key_off)); if (key_off != 0) break; - } + } if (key_off == 0) return WERR_NOT_FOUND; } else if (!strncmp((char *)data.data, "ri", 2)) { @@ -893,46 +925,52 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, DEBUG(10, ("Subkeys in RI list\n")); ZERO_STRUCT(pull); pull.data = data; - + if (NT_STATUS_IS_ERR(tdr_pull_ri_block(&pull, nk, &ri))) { DEBUG(0, ("Error parsing RI list\n")); return WERR_GENERAL_FAILURE; } SMB_ASSERT(!strncmp(ri.header, "ri", 2)); - + for (i = 0; i < ri.key_count; i++) { DATA_BLOB list_data; - + /* Get sublist data blob */ list_data = hbin_get(private_data->hive, ri.offset[i]); if (list_data.data == NULL) { DEBUG(0, ("Error getting RI list.")); return WERR_GENERAL_FAILURE; } - + ZERO_STRUCT(pull); pull.data = list_data; - + if (!strncmp((char *)list_data.data, "li", 2)) { struct li_block li; - - if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { + + if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, + nk, + &li))) { DEBUG(0, ("Error parsing LI list from RI\n")); return WERR_GENERAL_FAILURE; } SMB_ASSERT(!strncmp(li.header, "li", 2)); - + for (j = 0; j < li.key_count; j++) { - W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, - li.nk_offset[j], name, &key_off)); + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, + li.nk_offset[j], + name, + &key_off)); if (key_off) break; } } else if (!strncmp((char *)list_data.data, "lh", 2)) { struct lh_block lh; uint32_t hash; - - if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { + + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, + nk, + &lh))) { DEBUG(0, ("Error parsing LH list from RI\n")); return WERR_GENERAL_FAILURE; } @@ -943,8 +981,10 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, if (lh.hr[j].base37 != hash) { continue; } - W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, - lh.hr[j].nk_offset, name, &key_off)); + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, + lh.hr[j].nk_offset, + name, + &key_off)); if (key_off) break; } @@ -959,14 +999,15 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, return WERR_GENERAL_FAILURE; } - *ret = (struct hive_key *)regf_get_key (ctx, private_data->hive, key_off); + *ret = (struct hive_key *)regf_get_key(ctx, private_data->hive, + key_off); return WERR_OK; } -static WERROR regf_set_sec_desc (struct hive_key *key, - const struct security_descriptor *sec_desc) +static WERROR regf_set_sec_desc(struct hive_key *key, + const struct security_descriptor *sec_desc) { - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)key; struct sk_block cur_sk, sk, new_sk; struct regf_data *regf = private_data->hive; @@ -976,47 +1017,51 @@ static WERROR regf_set_sec_desc (struct hive_key *key, bool update_cur_sk = false; /* Get the root nk */ - hbin_get_tdr(regf, regf->header->data_offset, regf, - (tdr_pull_fn_t) tdr_pull_nk_block, &root); + hbin_get_tdr(regf, regf->header->data_offset, regf, + (tdr_pull_fn_t) tdr_pull_nk_block, &root); /* Push the security descriptor to a blob */ - if (NT_STATUS_IS_ERR(ndr_push_struct_blob(&data, regf, sec_desc, - (ndr_push_flags_fn_t)ndr_push_security_descriptor))) { + if (NT_STATUS_IS_ERR(ndr_push_struct_blob(&data, regf, sec_desc, + (ndr_push_flags_fn_t)ndr_push_security_descriptor))) { DEBUG(0, ("Unable to push security descriptor\n")); return WERR_GENERAL_FAILURE; } - /* Get the current security descriptor for the key */ - if (!hbin_get_tdr(regf, private_data->nk->sk_offset, regf, - (tdr_pull_fn_t) tdr_pull_sk_block, &cur_sk)) { + /* Get the current security descriptor for the key */ + if (!hbin_get_tdr(regf, private_data->nk->sk_offset, regf, + (tdr_pull_fn_t) tdr_pull_sk_block, &cur_sk)) { DEBUG(0, ("Unable to find security descriptor for current key\n")); return WERR_BADFILE; } /* If there's no change, change nothing. */ - if (memcmp(data.data, cur_sk.sec_desc, MIN(data.length, cur_sk.rec_size)) == 0) { + if (memcmp(data.data, cur_sk.sec_desc, + MIN(data.length, cur_sk.rec_size)) == 0) { return WERR_OK; } - /* Delete the current sk if only this key is using it */ + /* Delete the current sk if only this key is using it */ if (cur_sk.ref_cnt == 1) { - /* Get the previous security descriptor for the key */ - if (!hbin_get_tdr(regf, cur_sk.prev_offset, regf, - (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + /* Get the previous security descriptor for the key */ + if (!hbin_get_tdr(regf, cur_sk.prev_offset, regf, + (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find prev security descriptor for current key\n")); return WERR_BADFILE; } /* Change and store the previous security descriptor */ sk.next_offset = cur_sk.next_offset; - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, cur_sk.prev_offset, &sk); - - /* Get the next security descriptor for the key */ - if (!hbin_get_tdr(regf, cur_sk.next_offset, regf, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, + cur_sk.prev_offset, &sk); + + /* Get the next security descriptor for the key */ + if (!hbin_get_tdr(regf, cur_sk.next_offset, regf, + (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find next security descriptor for current key\n")); return WERR_BADFILE; } /* Change and store the next security descriptor */ sk.prev_offset = cur_sk.prev_offset; - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, cur_sk.next_offset, &sk); + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, + cur_sk.next_offset, &sk); hbin_free(regf, private_data->nk->sk_offset); } else { @@ -1029,20 +1074,26 @@ static WERROR regf_set_sec_desc (struct hive_key *key, do { cur_sk_offset = sk_offset; - if (!hbin_get_tdr(regf, sk_offset, regf, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + if (!hbin_get_tdr(regf, sk_offset, regf, + (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find security descriptor\n")); return WERR_BADFILE; } if (memcmp(data.data, sk.sec_desc, MIN(data.length, sk.rec_size)) == 0) { private_data->nk->sk_offset = sk_offset; sk.ref_cnt++; - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, sk_offset, &sk); - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, private_data->offset, private_data->nk); + hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_sk_block, + sk_offset, &sk); + hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_nk_block, + private_data->offset, + private_data->nk); return WERR_OK; } sk_offset = sk.next_offset; } while (sk_offset != root.sk_offset); - + ZERO_STRUCT(new_sk); new_sk.header = "sk"; new_sk.prev_offset = cur_sk_offset; @@ -1050,8 +1101,10 @@ static WERROR regf_set_sec_desc (struct hive_key *key, new_sk.ref_cnt = 1; new_sk.rec_size = data.length; new_sk.sec_desc = data.data; - - sk_offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_sk_block, &new_sk); + + sk_offset = hbin_store_tdr(regf, + (tdr_push_fn_t) tdr_push_sk_block, + &new_sk); if (sk_offset == -1) { DEBUG(0, ("Error storing sk block\n")); return WERR_GENERAL_FAILURE; @@ -1059,47 +1112,58 @@ static WERROR regf_set_sec_desc (struct hive_key *key, private_data->nk->sk_offset = sk_offset; if (update_cur_sk) { - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, private_data->nk->sk_offset, &cur_sk); + hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_sk_block, + private_data->nk->sk_offset, &cur_sk); } - /* Get the previous security descriptor for the key */ - if (!hbin_get_tdr(regf, new_sk.prev_offset, regf, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + /* Get the previous security descriptor for the key */ + if (!hbin_get_tdr(regf, new_sk.prev_offset, regf, + (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find security descriptor for previous key\n")); return WERR_BADFILE; } /* Change and store the previous security descriptor */ sk.next_offset = sk_offset; - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, cur_sk.prev_offset, &sk); - - /* Get the next security descriptor for the key (always root, as we append) */ - if (!hbin_get_tdr(regf, new_sk.next_offset, regf, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_sk_block, + cur_sk.prev_offset, &sk); + + /* Get the next security descriptor for the key (always root, as we append) */ + if (!hbin_get_tdr(regf, new_sk.next_offset, regf, + (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find security descriptor for current key\n")); return WERR_BADFILE; } /* Change and store the next security descriptor (always root, as we append) */ sk.prev_offset = sk_offset; - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, root.sk_offset, &sk); + hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_sk_block, + root.sk_offset, &sk); /* Store the nk. */ - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, private_data->offset, private_data->nk); + hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_sk_block, + private_data->offset, private_data->nk); return WERR_OK; } -static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, const struct hive_key *key, - struct security_descriptor **sd) +static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, const struct hive_key *key, + struct security_descriptor **sd) { - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)key; struct sk_block sk; struct regf_data *regf = private_data->hive; DATA_BLOB data; - if (!hbin_get_tdr(regf, private_data->nk->sk_offset, ctx, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + if (!hbin_get_tdr(regf, private_data->nk->sk_offset, ctx, + (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find security descriptor\n")); return WERR_GENERAL_FAILURE; } - + if (strcmp(sk.header, "sk") != 0) { DEBUG(0, ("Expected 'sk', got '%s'\n", sk.header)); return WERR_GENERAL_FAILURE; @@ -1110,7 +1174,8 @@ static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, const struct hive_key *key, data.data = sk.sec_desc; data.length = sk.rec_size; - if (NT_STATUS_IS_ERR(ndr_pull_struct_blob(&data, ctx, *sd, (ndr_pull_flags_fn_t)ndr_pull_security_descriptor))) { + if (NT_STATUS_IS_ERR(ndr_pull_struct_blob(&data, ctx, *sd, + (ndr_pull_flags_fn_t)ndr_pull_security_descriptor))) { DEBUG(0, ("Error parsing security descriptor\n")); return WERR_GENERAL_FAILURE; } @@ -1118,45 +1183,51 @@ static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, const struct hive_key *key, return WERR_OK; } -static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, - const char *name, uint32_t key_offset, uint32_t *ret) +static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, + const char *name, + uint32_t key_offset, uint32_t *ret) { DATA_BLOB data; /* Create a new key if necessary */ - if (list_offset == -1) { + if (list_offset == -1) { if (regf->header->version.major != 1) { DEBUG(0, ("Can't store keys in unknown registry format\n")); return WERR_NOT_SUPPORTED; } - if (regf->header->version.minor < 3) { + if (regf->header->version.minor < 3) { /* Store LI */ struct li_block li; ZERO_STRUCT(li); li.header = "li"; - li.key_count = 1; + li.key_count = 1; li.nk_offset = talloc_array(regf, uint32_t, 1); W_ERROR_HAVE_NO_MEMORY(li.nk_offset); li.nk_offset[0] = key_offset; - *ret = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_li_block, &li); + *ret = hbin_store_tdr(regf, + (tdr_push_fn_t) tdr_push_li_block, + &li); talloc_free(li.nk_offset); - } else if (regf->header->version.minor == 3 || regf->header->version.minor == 4) { + } else if (regf->header->version.minor == 3 || + regf->header->version.minor == 4) { /* Store LF */ struct lf_block lf; ZERO_STRUCT(lf); lf.header = "lf"; lf.key_count = 1; - + lf.hr = talloc_array(regf, struct hash_record, 1); W_ERROR_HAVE_NO_MEMORY(lf.hr); lf.hr[0].nk_offset = key_offset; lf.hr[0].hash = talloc_strndup(lf.hr, name, 4); W_ERROR_HAVE_NO_MEMORY(lf.hr[0].hash); - *ret = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_lf_block, &lf); + *ret = hbin_store_tdr(regf, + (tdr_push_fn_t) tdr_push_lf_block, + &lf); talloc_free(lf.hr); } else if (regf->header->version.minor == 5) { @@ -1165,19 +1236,21 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, ZERO_STRUCT(lh); lh.header = "lh"; lh.key_count = 1; - + lh.hr = talloc_array(regf, struct lh_hash, 1); W_ERROR_HAVE_NO_MEMORY(lh.hr); lh.hr[0].nk_offset = key_offset; lh.hr[0].base37 = regf_create_lh_hash(name); - *ret = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_lh_block, &lh); + *ret = hbin_store_tdr(regf, + (tdr_push_fn_t) tdr_push_lh_block, + &lh); talloc_free(lh.hr); } return WERR_OK; - } - + } + data = hbin_get(regf, list_offset); if (!data.data) { DEBUG(0, ("Unable to find subkey list\n")); @@ -1187,7 +1260,7 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, if (!strncmp((char *)data.data, "li", 2)) { struct tdr_pull pull; struct li_block li; - + ZERO_STRUCT(pull); pull.data = data; @@ -1201,13 +1274,16 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, DEBUG(0, ("LI header corrupt\n")); return WERR_BADFILE; } - - li.nk_offset = talloc_realloc(regf, li.nk_offset, uint32_t, li.key_count+1); + + li.nk_offset = talloc_realloc(regf, li.nk_offset, + uint32_t, li.key_count+1); W_ERROR_HAVE_NO_MEMORY(li.nk_offset); li.nk_offset[li.key_count] = key_offset; li.key_count++; - *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t)tdr_push_li_block, list_offset, &li); - + *ret = hbin_store_tdr_resize(regf, + (tdr_push_fn_t)tdr_push_li_block, + list_offset, &li); + talloc_free(li.nk_offset); } else if (!strncmp((char *)data.data, "lf", 2)) { struct tdr_pull pull; @@ -1221,14 +1297,17 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, return WERR_BADFILE; } SMB_ASSERT(!strncmp(lf.header, "lf", 2)); - - lf.hr = talloc_realloc(regf, lf.hr, struct hash_record, lf.key_count+1); + + lf.hr = talloc_realloc(regf, lf.hr, struct hash_record, + lf.key_count+1); W_ERROR_HAVE_NO_MEMORY(lf.hr); lf.hr[lf.key_count].nk_offset = key_offset; lf.hr[lf.key_count].hash = talloc_strndup(lf.hr, name, 4); W_ERROR_HAVE_NO_MEMORY(lf.hr[lf.key_count].hash); lf.key_count++; - *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t)tdr_push_lf_block, list_offset, &lf); + *ret = hbin_store_tdr_resize(regf, + (tdr_push_fn_t)tdr_push_lf_block, + list_offset, &lf); talloc_free(lf.hr); } else if (!strncmp((char *)data.data, "lh", 2)) { @@ -1243,13 +1322,16 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, return WERR_BADFILE; } SMB_ASSERT(!strncmp(lh.header, "lh", 2)); - - lh.hr = talloc_realloc(regf, lh.hr, struct lh_hash, lh.key_count+1); + + lh.hr = talloc_realloc(regf, lh.hr, struct lh_hash, + lh.key_count+1); W_ERROR_HAVE_NO_MEMORY(lh.hr); lh.hr[lh.key_count].nk_offset = key_offset; lh.hr[lh.key_count].base37 = regf_create_lh_hash(name); lh.key_count++; - *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t)tdr_push_lh_block, list_offset, &lh); + *ret = hbin_store_tdr_resize(regf, + (tdr_push_fn_t)tdr_push_lh_block, + list_offset, &lh); talloc_free(lh.hr); } else if (!strncmp((char *)data.data, "ri", 2)) { @@ -1260,12 +1342,12 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, DEBUG(0, ("Cannot add to unknown subkey list\n")); return WERR_BADFILE; } - + return WERR_OK; } -static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, - uint32_t key_offset, uint32_t *ret) +static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, + uint32_t key_offset, uint32_t *ret) { DATA_BLOB data; @@ -1280,17 +1362,17 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, struct tdr_pull pull; uint16_t i; bool found_offset = false; - + DEBUG(10, ("Subkeys in LI list\n")); - + ZERO_STRUCT(pull); - pull.data = data; - + pull.data = data; + if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, regf, &li))) { DEBUG(0, ("Error parsing LI list\n")); return WERR_BADFILE; } - + SMB_ASSERT(!strncmp(li.header, "li", 2)); for (i = 0; i < li.key_count; i++) { @@ -1315,23 +1397,25 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, } /* Store li block */ - *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_li_block, list_offset, &li); + *ret = hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_li_block, + list_offset, &li); } else if (strncmp((char *)data.data, "lf", 2) == 0) { struct lf_block lf; struct tdr_pull pull; uint16_t i; bool found_offset = false; - + DEBUG(10, ("Subkeys in LF list\n")); - + ZERO_STRUCT(pull); - pull.data = data; - + pull.data = data; + if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, regf, &lf))) { DEBUG(0, ("Error parsing LF list\n")); return WERR_BADFILE; } - + SMB_ASSERT(!strncmp(lf.header, "lf", 2)); for (i = 0; i < lf.key_count; i++) { @@ -1349,7 +1433,7 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, return WERR_NOT_FOUND; } lf.key_count--; - + /* If the there are no entries left, free the subkey list */ if (lf.key_count == 0) { hbin_free(regf, list_offset); @@ -1358,23 +1442,25 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, } /* Store lf block */ - *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_lf_block, list_offset, &lf); + *ret = hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_lf_block, + list_offset, &lf); } else if (strncmp((char *)data.data, "lh", 2) == 0) { struct lh_block lh; struct tdr_pull pull; uint16_t i; bool found_offset = false; - + DEBUG(10, ("Subkeys in LH list\n")); - + ZERO_STRUCT(pull); - pull.data = data; - + pull.data = data; + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, regf, &lh))) { DEBUG(0, ("Error parsing LF list\n")); return WERR_BADFILE; } - + SMB_ASSERT(!strncmp(lh.header, "lh", 2)); for (i = 0; i < lh.key_count; i++) { @@ -1392,7 +1478,7 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, return WERR_NOT_FOUND; } lh.key_count--; - + /* If the there are no entries left, free the subkey list */ if (lh.key_count == 0) { hbin_free(regf, list_offset); @@ -1401,7 +1487,9 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, } /* Store lh block */ - *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_lh_block, list_offset, &lh); + *ret = hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_lh_block, + list_offset, &lh); } else if (strncmp((char *)data.data, "ri", 2) == 0) { /* FIXME */ DEBUG(0, ("Sorry, deletion from ri block is not supported yet.\n")); @@ -1415,7 +1503,7 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, static WERROR regf_del_value (struct hive_key *key, const char *name) { - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)key; struct regf_data *regf = private_data->hive; struct nk_block *nk = private_data->nk; @@ -1436,11 +1524,13 @@ static WERROR regf_del_value (struct hive_key *key, const char *name) ((uint32_t *)values.data)[i-1] = ((uint32_t *) values.data)[i]; } else { vk_offset = IVAL(values.data, i * 4); - if (!hbin_get_tdr(regf, vk_offset, private_data, - (tdr_pull_fn_t)tdr_pull_vk_block, &vk)) { - DEBUG(0, ("Unable to get VK block at %d\n", vk_offset)); + if (!hbin_get_tdr(regf, vk_offset, private_data, + (tdr_pull_fn_t)tdr_pull_vk_block, + &vk)) { + DEBUG(0, ("Unable to get VK block at %d\n", + vk_offset)); return WERR_BADFILE; - } + } if (strcmp(vk.data_name, name) == 0) { hbin_free(regf, vk_offset); found_offset = true; @@ -1458,10 +1548,13 @@ static WERROR regf_del_value (struct hive_key *key, const char *name) if (nk->num_values == 0) { hbin_free(regf, nk->values_offset); nk->values_offset = -1; - } else { - nk->values_offset = hbin_store_resize(regf, nk->values_offset, values); + } else { + nk->values_offset = hbin_store_resize(regf, + nk->values_offset, + values); } - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, private_data->offset, nk); + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, + private_data->offset, nk); return regf_save_hbin(private_data->hive); } @@ -1469,14 +1562,14 @@ static WERROR regf_del_value (struct hive_key *key, const char *name) static WERROR regf_del_key(const struct hive_key *parent, const char *name) { - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)parent; struct regf_key_data *key; struct nk_block *parent_nk; WERROR error; SMB_ASSERT(private_data); - + parent_nk = private_data->nk; if (parent_nk->subkeys_offset == -1) { @@ -1485,21 +1578,21 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name) } /* Find the key */ - if (!W_ERROR_IS_OK(regf_get_subkey_by_name(parent_nk, parent, name, - (struct hive_key **)&key))) { + if (!W_ERROR_IS_OK(regf_get_subkey_by_name(parent_nk, parent, name, + (struct hive_key **)&key))) { DEBUG(2, ("Key '%s' not found\n", name)); return WERR_NOT_FOUND; } - - if (key->nk->subkeys_offset != -1 || + + if (key->nk->subkeys_offset != -1 || key->nk->values_offset != -1) { DEBUG(0, ("Key '%s' is not empty.\n", name)); return WERR_FILE_EXISTS; } - + /* Delete it from the subkey list. */ - error = regf_sl_del_entry(private_data->hive, parent_nk->subkeys_offset, - key->offset, &parent_nk->subkeys_offset); + error = regf_sl_del_entry(private_data->hive, parent_nk->subkeys_offset, + key->offset, &parent_nk->subkeys_offset); if (!W_ERROR_IS_OK(error)) { DEBUG(0, ("Can't store new subkey list for parent key. Won't delete.\n")); return error; @@ -1507,9 +1600,9 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name) /* Re-store parent key */ parent_nk->num_subkeys--; - hbin_store_tdr_resize(private_data->hive, - (tdr_push_fn_t) tdr_push_nk_block, - private_data->offset, parent_nk); + hbin_store_tdr_resize(private_data->hive, + (tdr_push_fn_t) tdr_push_nk_block, + private_data->offset, parent_nk); if (key->nk->clsname_offset != -1) { hbin_free(private_data->hive, key->nk->clsname_offset); @@ -1519,12 +1612,12 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name) return regf_save_hbin(private_data->hive); } -static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent, - const char *name, const char *classname, - struct security_descriptor *sec_desc, - struct hive_key **ret) +static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent, + const char *name, const char *classname, + struct security_descriptor *sec_desc, + struct hive_key **ret) { - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)parent; struct nk_block *parent_nk = private_data->nk, nk; struct nk_block *root; @@ -1547,32 +1640,33 @@ static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent, nk.clsname_offset = -1; /* FIXME: fill in */ nk.clsname_length = 0; nk.key_name = name; - + /* Get the security descriptor of the root key */ root = talloc_zero(ctx, struct nk_block); W_ERROR_HAVE_NO_MEMORY(root); - if (!hbin_get_tdr(regf, regf->header->data_offset, root, - (tdr_pull_fn_t)tdr_pull_nk_block, root)) { + if (!hbin_get_tdr(regf, regf->header->data_offset, root, + (tdr_pull_fn_t)tdr_pull_nk_block, root)) { DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset)); return WERR_GENERAL_FAILURE; } nk.sk_offset = root->sk_offset; talloc_free(root); - + /* Store the new nk key */ offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_nk_block, &nk); - - error = regf_sl_add_entry(regf, parent_nk->subkeys_offset, name, offset, &parent_nk->subkeys_offset); + + error = regf_sl_add_entry(regf, parent_nk->subkeys_offset, name, offset, + &parent_nk->subkeys_offset); if (!W_ERROR_IS_OK(error)) { hbin_free(regf, offset); return error; } - + parent_nk->num_subkeys++; /* Since the subkey offset of the parent can change, store it again */ - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, nk.parent_offset, parent_nk); *ret = (struct hive_key *)regf_get_key(ctx, regf, offset); @@ -1580,10 +1674,10 @@ static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent, return regf_save_hbin(private_data->hive); } -static WERROR regf_set_value(struct hive_key *key, const char *name, - uint32_t type, const DATA_BLOB data) +static WERROR regf_set_value(struct hive_key *key, const char *name, + uint32_t type, const DATA_BLOB data) { - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)key; struct regf_data *regf = private_data->hive; struct nk_block *nk = private_data->nk; @@ -1600,9 +1694,11 @@ static WERROR regf_set_value(struct hive_key *key, const char *name, for (i = 0; i < nk->num_values; i++) { tmp_vk_offset = IVAL(values.data, i * 4); - if (!hbin_get_tdr(regf, tmp_vk_offset, private_data, - (tdr_pull_fn_t)tdr_pull_vk_block, &vk)) { - DEBUG(0, ("Unable to get VK block at %d\n", tmp_vk_offset)); + if (!hbin_get_tdr(regf, tmp_vk_offset, private_data, + (tdr_pull_fn_t)tdr_pull_vk_block, + &vk)) { + DEBUG(0, ("Unable to get VK block at %d\n", + tmp_vk_offset)); return WERR_GENERAL_FAILURE; } if (strcmp(vk.data_name, name) == 0) { @@ -1612,7 +1708,7 @@ static WERROR regf_set_value(struct hive_key *key, const char *name, } /* Free data, if any */ if (!(vk.data_length & 0x80000000)) { - hbin_free(regf, vk.data_offset); + hbin_free(regf, vk.data_offset); } } if (old_vk_offset == -1) { @@ -1638,15 +1734,21 @@ static WERROR regf_set_value(struct hive_key *key, const char *name, } if (old_vk_offset == -1) { /* Store new vk */ - vk_offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_vk_block, &vk); + vk_offset = hbin_store_tdr(regf, + (tdr_push_fn_t) tdr_push_vk_block, + &vk); } else { /* Store vk at offset */ - vk_offset = hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_vk_block, old_vk_offset ,&vk); + vk_offset = hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_vk_block, + old_vk_offset ,&vk); } /* Re-allocate the value list */ if (nk->values_offset == -1) { - nk->values_offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_uint32, &vk_offset); + nk->values_offset = hbin_store_tdr(regf, + (tdr_push_fn_t) tdr_push_uint32, + &vk_offset); nk->num_values = 1; } else { @@ -1664,17 +1766,23 @@ static WERROR regf_set_value(struct hive_key *key, const char *name, DATA_BLOB value_list; value_list.length = (nk->num_values+1)*4; - value_list.data = (uint8_t *)talloc_array(private_data, uint32_t, nk->num_values+1); + value_list.data = (uint8_t *)talloc_array(private_data, + uint32_t, + nk->num_values+1); W_ERROR_HAVE_NO_MEMORY(value_list.data); memcpy(value_list.data, values.data, nk->num_values * 4); SIVAL(value_list.data, nk->num_values * 4, vk_offset); nk->num_values++; - nk->values_offset = hbin_store_resize(regf, nk->values_offset, value_list); + nk->values_offset = hbin_store_resize(regf, + nk->values_offset, + value_list); } - + } - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, private_data->offset, nk); + hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_nk_block, + private_data->offset, nk); return regf_save_hbin(private_data->hive); } @@ -1698,8 +1806,9 @@ static WERROR regf_save_hbin(struct regf_data *regf) regf->header->chksum = regf_hdr_checksum(push->data.data); talloc_free(push); - if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, - (tdr_push_fn_t)tdr_push_regf_hdr, regf->header))) { + if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, + (tdr_push_fn_t)tdr_push_regf_hdr, + regf->header))) { DEBUG(0, ("Error writing registry file header\n")); return WERR_GENERAL_FAILURE; } @@ -1707,13 +1816,13 @@ static WERROR regf_save_hbin(struct regf_data *regf) if (lseek(regf->fd, 0x1000, SEEK_SET) == -1) { DEBUG(0, ("Error lseeking to 0x1000 in regf file\n")); return WERR_GENERAL_FAILURE; - } + } for (i = 0; regf->hbins[i]; i++) { - if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, - (tdr_push_fn_t)tdr_push_hbin_block, - regf->hbins[i]))) { - DEBUG(0, ("Error writing HBIN block\n")); + if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, + (tdr_push_fn_t)tdr_push_hbin_block, + regf->hbins[i]))) { + DEBUG(0, ("Error writing HBIN block\n")); return WERR_GENERAL_FAILURE; } } @@ -1721,8 +1830,8 @@ static WERROR regf_save_hbin(struct regf_data *regf) return WERR_OK; } -WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location, - int minor_version, struct hive_key **key) +WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location, + int minor_version, struct hive_key **key) { struct regf_data *regf; struct regf_hdr *regf_hdr; @@ -1754,7 +1863,8 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location, regf_hdr->version.major = 1; regf_hdr->version.minor = minor_version; regf_hdr->last_block = 0x1000; /* Block size */ - regf_hdr->description = talloc_strdup(regf_hdr, "registry created by Samba 4"); + regf_hdr->description = talloc_strdup(regf_hdr, + "registry created by Samba 4"); W_ERROR_HAVE_NO_MEMORY(regf_hdr->description); regf_hdr->chksum = 0; @@ -1785,14 +1895,16 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location, nk.clsname_offset = -1; /* FIXME: fill in */ nk.clsname_length = 0; nk.key_name = ""; - + nk.sk_offset = -1; /* FIXME: fill in */ - + /* Store the new nk key */ - regf->header->data_offset = hbin_store_tdr(regf, - (tdr_push_fn_t)tdr_push_nk_block, &nk); - - *key = (struct hive_key *)regf_get_key(parent_ctx, regf, regf->header->data_offset); + regf->header->data_offset = hbin_store_tdr(regf, + (tdr_push_fn_t)tdr_push_nk_block, + &nk); + + *key = (struct hive_key *)regf_get_key(parent_ctx, regf, + regf->header->data_offset); /* We can drop our own reference now that *key will have created one */ talloc_free(regf); @@ -1805,8 +1917,8 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location, return WERR_OK; } -WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, - const char *location, struct hive_key **key) +WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key) { struct regf_data *regf; struct regf_hdr *regf_hdr; @@ -1850,7 +1962,7 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, if (strcmp(regf_hdr->REGF_ID, "regf") != 0) { DEBUG(0, ("Unrecognized NT registry header id: %s, %s\n", - regf_hdr->REGF_ID, location)); + regf_hdr->REGF_ID, location)); talloc_free(regf); return WERR_GENERAL_FAILURE; } @@ -1858,8 +1970,8 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, /* Validate the header ... */ if (regf_hdr_checksum(pull.data.data) != regf_hdr->chksum) { DEBUG(0, ("Registry file checksum error: %s: %d,%d\n", - location, regf_hdr->chksum, - regf_hdr_checksum(pull.data.data))); + location, regf_hdr->chksum, + regf_hdr_checksum(pull.data.data))); talloc_free(regf); return WERR_GENERAL_FAILURE; } @@ -1873,8 +1985,10 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, regf->hbins[0] = NULL; - while (pull.offset < pull.data.length && pull.offset <= regf->header->last_block) { - struct hbin_block *hbin = talloc(regf->hbins, struct hbin_block); + while (pull.offset < pull.data.length && + pull.offset <= regf->header->last_block) { + struct hbin_block *hbin = talloc(regf->hbins, + struct hbin_block); W_ERROR_HAVE_NO_MEMORY(hbin); @@ -1885,21 +1999,23 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, } if (strcmp(hbin->HBIN_ID, "hbin") != 0) { - DEBUG(0, ("[%d] Expected 'hbin', got '%s'\n", i, hbin->HBIN_ID)); + DEBUG(0, ("[%d] Expected 'hbin', got '%s'\n", + i, hbin->HBIN_ID)); talloc_free(regf); return WERR_FOOBAR; } regf->hbins[i] = hbin; i++; - regf->hbins = talloc_realloc(regf, regf->hbins, struct hbin_block *, i+2); + regf->hbins = talloc_realloc(regf, regf->hbins, + struct hbin_block *, i+2); regf->hbins[i] = NULL; - } + } DEBUG(1, ("%d HBIN blocks read\n", i)); - *key = (struct hive_key *)regf_get_key(parent_ctx, regf, - regf->header->data_offset); + *key = (struct hive_key *)regf_get_key(parent_ctx, regf, + regf->header->data_offset); /* We can drop our own reference now that *key will have created one */ talloc_free(regf); diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 6dec84ad89..c1159dde2e 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -1,25 +1,25 @@ -/* +/* Unix SMB/CIFS implementation. Registry interface Copyright (C) Gerald Carter 2002. Copyright (C) Jelmer Vernooij 2003-2007. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _REGISTRY_H /* _REGISTRY_H */ -#define _REGISTRY_H +#define _REGISTRY_H struct registry_context; @@ -29,15 +29,15 @@ struct registry_context; #include "libcli/util/ntstatus.h" /* Handles for the predefined keys */ -#define HKEY_CLASSES_ROOT 0x80000000 -#define HKEY_CURRENT_USER 0x80000001 -#define HKEY_LOCAL_MACHINE 0x80000002 -#define HKEY_USERS 0x80000003 -#define HKEY_PERFORMANCE_DATA 0x80000004 -#define HKEY_CURRENT_CONFIG 0x80000005 -#define HKEY_DYN_DATA 0x80000006 -#define HKEY_PERFORMANCE_TEXT 0x80000050 -#define HKEY_PERFORMANCE_NLSTEXT 0x80000060 +#define HKEY_CLASSES_ROOT 0x80000000 +#define HKEY_CURRENT_USER 0x80000001 +#define HKEY_LOCAL_MACHINE 0x80000002 +#define HKEY_USERS 0x80000003 +#define HKEY_PERFORMANCE_DATA 0x80000004 +#define HKEY_CURRENT_CONFIG 0x80000005 +#define HKEY_DYN_DATA 0x80000006 +#define HKEY_PERFORMANCE_TEXT 0x80000050 +#define HKEY_PERFORMANCE_NLSTEXT 0x80000060 #define HKEY_FIRST HKEY_CLASSES_ROOT #define HKEY_LAST HKEY_PERFORMANCE_NLSTEXT @@ -61,18 +61,18 @@ extern const struct reg_predefined_key reg_predefined_keys[]; struct reg_key_operations; /* structure to store the registry handles */ -struct registry_key +struct registry_key { struct registry_context *context; }; #include "lib/registry/patchfile.h" -struct registry_value +struct registry_value { - const char *name; - unsigned int data_type; - DATA_BLOB data; + const char *name; + unsigned int data_type; + DATA_BLOB data; }; /* FIXME */ @@ -86,77 +86,77 @@ struct registry_operations { const char *name; WERROR (*get_key_info) (TALLOC_CTX *mem_ctx, - const struct registry_key *key, - const char **classname, - uint32_t *numsubkeys, - uint32_t *numvalues, - NTTIME *last_change_time); + const struct registry_key *key, + const char **classname, + uint32_t *numsubkeys, + uint32_t *numvalues, + NTTIME *last_change_time); WERROR (*flush_key) (struct registry_key *key); - WERROR (*get_predefined_key) (const struct registry_context *ctx, - uint32_t key_id, - struct registry_key **key); + WERROR (*get_predefined_key) (const struct registry_context *ctx, + uint32_t key_id, + struct registry_key **key); WERROR (*open_key) (TALLOC_CTX *mem_ctx, - struct registry_key *parent, - const char *path, - struct registry_key **key); + struct registry_key *parent, + const char *path, + struct registry_key **key); - WERROR (*create_key) (TALLOC_CTX *mem_ctx, - struct registry_key *parent, - const char *name, - const char *key_class, - struct security_descriptor *security, - struct registry_key **key); + WERROR (*create_key) (TALLOC_CTX *mem_ctx, + struct registry_key *parent, + const char *name, + const char *key_class, + struct security_descriptor *security, + struct registry_key **key); WERROR (*delete_key) (struct registry_key *key, const char *name); WERROR (*delete_value) (struct registry_key *key, const char *name); WERROR (*enum_key) (TALLOC_CTX *mem_ctx, - const struct registry_key *key, uint32_t idx, - const char **name, - const char **keyclass, - NTTIME *last_changed_time); + const struct registry_key *key, uint32_t idx, + const char **name, + const char **keyclass, + NTTIME *last_changed_time); WERROR (*enum_value) (TALLOC_CTX *mem_ctx, - const struct registry_key *key, uint32_t idx, - const char **name, - uint32_t *type, - DATA_BLOB *data); + const struct registry_key *key, uint32_t idx, + const char **name, + uint32_t *type, + DATA_BLOB *data); WERROR (*get_security) (TALLOC_CTX *mem_ctx, - const struct registry_key *key, - struct security_descriptor **security); + const struct registry_key *key, + struct security_descriptor **security); WERROR (*set_security) (struct registry_key *key, - const struct security_descriptor *security); + const struct security_descriptor *security); WERROR (*load_key) (struct registry_key *key, - const char *key_name, - const char *path); + const char *key_name, + const char *path); WERROR (*unload_key) (struct registry_key *key, const char *name); WERROR (*notify_value_change) (struct registry_key *key, - reg_value_notification_function fn); + reg_value_notification_function fn); WERROR (*get_value) (TALLOC_CTX *mem_ctx, - const struct registry_key *key, - const char *name, - uint32_t *type, - DATA_BLOB *data); + const struct registry_key *key, + const char *name, + uint32_t *type, + DATA_BLOB *data); WERROR (*set_value) (struct registry_key *key, - const char *name, - uint32_t type, - const DATA_BLOB data); -}; + const char *name, + uint32_t type, + const DATA_BLOB data); +}; /** * Handle to a full registry - * contains zero or more hives + * contains zero or more hives */ struct registry_context { const struct registry_operations *ops; @@ -168,113 +168,118 @@ struct event_context; /** * Open the locally defined registry. */ -WERROR reg_open_local (TALLOC_CTX *mem_ctx, - struct registry_context **ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials); +WERROR reg_open_local(TALLOC_CTX *mem_ctx, + struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials); -WERROR reg_open_samba (TALLOC_CTX *mem_ctx, - struct registry_context **ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials); +WERROR reg_open_samba(TALLOC_CTX *mem_ctx, + struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials); /** * Open the registry on a remote machine. */ -WERROR reg_open_remote(struct registry_context **ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - const char *location, struct event_context *ev); +WERROR reg_open_remote(struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + const char *location, struct event_context *ev); WERROR reg_open_wine(struct registry_context **ctx, const char *path); const char *reg_get_predef_name(uint32_t hkey); -WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, - const char *name, - struct registry_key **key); -WERROR reg_get_predefined_key(const struct registry_context *ctx, - uint32_t hkey, - struct registry_key **key); - -WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, - const char *name, struct registry_key **result); - -WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, - const struct registry_key *key, uint32_t idx, - const char **name, - uint32_t *type, - DATA_BLOB *data); +WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, + const char *name, + struct registry_key **key); +WERROR reg_get_predefined_key(const struct registry_context *ctx, + uint32_t hkey, + struct registry_key **key); + +WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, + const char *name, struct registry_key **result); + +WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, + const struct registry_key *key, uint32_t idx, + const char **name, + uint32_t *type, + DATA_BLOB *data); WERROR reg_key_get_info(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - const char **class_name, - uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_change_time); -WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - int idx, - const char **name, - const char **classname, - NTTIME *last_mod_time); -WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - const char *name, - struct registry_key **subkey); -WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - const char *name, - uint32_t *type, - DATA_BLOB *data); + const struct registry_key *key, + const char **class_name, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time); +WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + int idx, + const char **name, + const char **classname, + NTTIME *last_mod_time); +WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char *name, + struct registry_key **subkey); +WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char *name, + uint32_t *type, + DATA_BLOB *data); WERROR reg_key_del(struct registry_key *parent, const char *name); -WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, - struct registry_key *parent, const char *name, - const char *classname, - struct security_descriptor *desc, - struct registry_key **newkey); -WERROR reg_val_set(struct registry_key *key, const char *value, - uint32_t type, DATA_BLOB data); -WERROR reg_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, struct security_descriptor **secdesc); +WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, + struct registry_key *parent, const char *name, + const char *classname, + struct security_descriptor *desc, + struct registry_key **newkey); +WERROR reg_val_set(struct registry_key *key, const char *value, + uint32_t type, DATA_BLOB data); +WERROR reg_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, + struct security_descriptor **secdesc); WERROR reg_del_value(struct registry_key *key, const char *valname); WERROR reg_key_flush(struct registry_key *key); -WERROR reg_create_key (TALLOC_CTX *mem_ctx, - struct registry_key *parent, - - const char *name, - const char *key_class, - struct security_descriptor *security, - struct registry_key **key); +WERROR reg_create_key(TALLOC_CTX *mem_ctx, + struct registry_key *parent, + const char *name, + const char *key_class, + struct security_descriptor *security, + struct registry_key **key); /* Utility functions */ const char *str_regtype(int type); -char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, - const DATA_BLOB data); +char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, + const DATA_BLOB data); char *reg_val_description(TALLOC_CTX *mem_ctx, const char *name, - uint32_t type, const DATA_BLOB data); -bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data); -WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result); + uint32_t type, const DATA_BLOB data); +bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, + const char *data_str, uint32_t *type, DATA_BLOB *data); +WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, + const char *name, struct registry_key **result); WERROR reg_key_del_abs(struct registry_context *ctx, const char *path); -WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx, const char *path, uint32_t access_mask, struct security_descriptor *sec_desc, struct registry_key **result); -WERROR reg_load_key(struct registry_context *ctx, struct registry_key *key, - const char *name, const char *filename); - -WERROR reg_mount_hive(struct registry_context *rctx, - struct hive_key *hive_key, - uint32_t key_id, - const char **elements); +WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx, + const char *path, uint32_t access_mask, + struct security_descriptor *sec_desc, + struct registry_key **result); +WERROR reg_load_key(struct registry_context *ctx, struct registry_key *key, + const char *name, const char *filename); + +WERROR reg_mount_hive(struct registry_context *rctx, + struct hive_key *hive_key, + uint32_t key_id, + const char **elements); struct registry_key *reg_import_hive_key(struct registry_context *ctx, - struct hive_key *hive, - uint32_t predef_key, - const char **elements); -WERROR reg_get_security(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - struct security_descriptor **security); - -WERROR reg_set_security(struct registry_key *key, - struct security_descriptor *security); + struct hive_key *hive, + uint32_t predef_key, + const char **elements); +WERROR reg_get_security(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + struct security_descriptor **security); + +WERROR reg_set_security(struct registry_key *key, + struct security_descriptor *security); #endif /* _REGISTRY_H */ diff --git a/source4/lib/registry/rpc.c b/source4/lib/registry/rpc.c index e4157fe424..c694223909 100644 --- a/source4/lib/registry/rpc.c +++ b/source4/lib/registry/rpc.c @@ -7,15 +7,15 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ - + #include "includes.h" #include "registry.h" #include "librpc/gen_ndr/ndr_winreg_c.h" @@ -76,7 +76,8 @@ openhive(HKCC) static struct { uint32_t hkey; - WERROR (*open) (struct dcerpc_pipe *p, TALLOC_CTX *, struct policy_handle *h); + WERROR (*open) (struct dcerpc_pipe *p, TALLOC_CTX *, + struct policy_handle *h); } known_hives[] = { { HKEY_LOCAL_MACHINE, open_HKLM }, { HKEY_CURRENT_USER, open_HKCU }, @@ -90,20 +91,20 @@ static struct { static WERROR rpc_query_key(const struct registry_key *k); -static WERROR rpc_get_predefined_key(const struct registry_context *ctx, - uint32_t hkey_type, - struct registry_key **k) +static WERROR rpc_get_predefined_key(const struct registry_context *ctx, + uint32_t hkey_type, + struct registry_key **k) { int n; - struct rpc_registry_context *rctx = talloc_get_type(ctx, - struct rpc_registry_context); + struct rpc_registry_context *rctx = talloc_get_type(ctx, + struct rpc_registry_context); struct rpc_key *mykeydata; for(n = 0; known_hives[n].hkey; n++) { - if(known_hives[n].hkey == hkey_type) + if(known_hives[n].hkey == hkey_type) break; } - + if (known_hives[n].open == NULL) { DEBUG(1, ("No such hive %d\n", hkey_type)); return WERR_NO_MORE_ITEMS; @@ -119,7 +120,7 @@ static WERROR rpc_get_predefined_key(const struct registry_context *ctx, #if 0 static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) { - struct winreg_OpenKey r; + struct winreg_OpenKey r; struct rpc_key_data *mykeydata; k->backend_data = mykeydata = talloc(mem_ctx, struct rpc_key_data); @@ -129,46 +130,47 @@ static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) /* Then, open the handle using the hive */ memset(&r, 0, sizeof(struct winreg_OpenKey)); - r.in.handle = &(((struct rpc_key_data *)k->hive->root->backend_data)->pol); - init_winreg_String(&r.in.keyname, k->path); - r.in.unknown = 0x00000000; - r.in.access_mask = 0x02000000; - r.out.handle = &mykeydata->pol; + r.in.handle = &(((struct rpc_key_data *)k->hive->root->backend_data)->pol); + init_winreg_String(&r.in.keyname, k->path); + r.in.unknown = 0x00000000; + r.in.access_mask = 0x02000000; + r.out.handle = &mykeydata->pol; - dcerpc_winreg_OpenKey((struct dcerpc_pipe *)k->hive->backend_data, mem_ctx, &r); + dcerpc_winreg_OpenKey((struct dcerpc_pipe *)k->hive->backend_data, + mem_ctx, &r); return r.out.result; } #endif -static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, - const char *name, struct registry_key **key) +static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, + const char *name, struct registry_key **key) { struct rpc_key *mykeydata = talloc_get_type(h, struct rpc_key), - *newkeydata; - struct winreg_OpenKey r; + *newkeydata; + struct winreg_OpenKey r; mykeydata = talloc(mem_ctx, struct rpc_key); /* Then, open the handle using the hive */ memset(&r, 0, sizeof(struct winreg_OpenKey)); - r.in.parent_handle = &mykeydata->pol; - init_winreg_String(&r.in.keyname, name); - r.in.unknown = 0x00000000; - r.in.access_mask = 0x02000000; - r.out.handle = &newkeydata->pol; + r.in.parent_handle = &mykeydata->pol; + init_winreg_String(&r.in.keyname, name); + r.in.unknown = 0x00000000; + r.in.access_mask = 0x02000000; + r.out.handle = &newkeydata->pol; - dcerpc_winreg_OpenKey(mykeydata->pipe, mem_ctx, &r); + dcerpc_winreg_OpenKey(mykeydata->pipe, mem_ctx, &r); return r.out.result; } -static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, - const struct registry_key *parent, - uint32_t n, - const char **value_name, - uint32_t *type, - DATA_BLOB *data) +static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, + const struct registry_key *parent, + uint32_t n, + const char **value_name, + uint32_t *type, + DATA_BLOB *data) { struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key); WERROR error; @@ -177,14 +179,14 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, NTSTATUS status; struct winreg_StringBuf name; uint8_t u8; - + if (mykeydata->num_values == -1) { error = rpc_query_key(parent); if(!W_ERROR_IS_OK(error)) return error; } len1 = mykeydata->max_valdatalen; - + name.length = 0; name.size = mykeydata->max_valnamelen * 2; name.name = ""; @@ -197,29 +199,29 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, r.in.length = &zero; r.in.size = &len1; r.out.name = &name; - + status = dcerpc_winreg_EnumValue(mykeydata->pipe, mem_ctx, &r); if(NT_STATUS_IS_ERR(status)) { DEBUG(0, ("Error in EnumValue: %s\n", nt_errstr(status))); return WERR_GENERAL_FAILURE; } - - if(NT_STATUS_IS_OK(status) && + + if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result) && r.out.length) { *value_name = talloc_strdup(mem_ctx, r.out.name->name); *data = data_blob_talloc(mem_ctx, r.out.value, *r.out.length); return WERR_OK; } - + return r.out.result; } -static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, - const struct registry_key *parent, - uint32_t n, - const char **name, - const char **keyclass, - NTTIME *last_changed_time) +static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, + const struct registry_key *parent, + uint32_t n, + const char **name, + const char **keyclass, + NTTIME *last_changed_time) { struct winreg_EnumKey r; struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key); @@ -242,7 +244,7 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, r.out.name = &namebuf; status = dcerpc_winreg_EnumKey(mykeydata->pipe, mem_ctx, &r); - if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { + if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { *name = talloc_strdup(mem_ctx, r.out.name->name); *keyclass = talloc_strdup(mem_ctx, r.out.keyclass->name); *last_changed_time = *r.out.last_changed_time; @@ -251,11 +253,11 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, return r.out.result; } -static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, - struct registry_key *parent, const char *name, - const char *key_class, - struct security_descriptor *sec, - struct registry_key **key) +static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, + struct registry_key *parent, const char *name, + const char *key_class, + struct security_descriptor *sec, + struct registry_key **key) { NTSTATUS status; struct winreg_CreateKey r; @@ -273,11 +275,11 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, status = dcerpc_winreg_CreateKey(parentkd->pipe, mem_ctx, &r); - if (!NT_STATUS_IS_OK(status)) { + if (!NT_STATUS_IS_OK(status)) { talloc_free(rpck); - DEBUG(1, ("CreateKey failed - %s\n", nt_errstr(status))); - return ntstatus_to_werror(status); - } + DEBUG(1, ("CreateKey failed - %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); + } if (W_ERROR_IS_OK(r.out.result)) { rpck->pipe = talloc_reference(rpck, parentkd->pipe); @@ -289,29 +291,29 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, static WERROR rpc_query_key(const struct registry_key *k) { - NTSTATUS status; - struct winreg_QueryInfoKey r; - struct rpc_key *mykeydata = talloc_get_type(k, struct rpc_key); + NTSTATUS status; + struct winreg_QueryInfoKey r; + struct rpc_key *mykeydata = talloc_get_type(k, struct rpc_key); TALLOC_CTX *mem_ctx = talloc_init("query_key"); r.in.classname = talloc(mem_ctx, struct winreg_String); - init_winreg_String(r.in.classname, NULL); - r.in.handle = &mykeydata->pol; - - status = dcerpc_winreg_QueryInfoKey(mykeydata->pipe, mem_ctx, &r); + init_winreg_String(r.in.classname, NULL); + r.in.handle = &mykeydata->pol; + + status = dcerpc_winreg_QueryInfoKey(mykeydata->pipe, mem_ctx, &r); talloc_free(mem_ctx); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("QueryInfoKey failed - %s\n", nt_errstr(status))); - return ntstatus_to_werror(status); - } - - if (W_ERROR_IS_OK(r.out.result)) { + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("QueryInfoKey failed - %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); + } + + if (W_ERROR_IS_OK(r.out.result)) { mykeydata->num_subkeys = *r.out.num_subkeys; mykeydata->num_values = *r.out.num_values; mykeydata->max_valnamelen = *r.out.max_valnamelen; mykeydata->max_valdatalen = *r.out.max_valbufsize; - } + } return r.out.result; } @@ -322,11 +324,11 @@ static WERROR rpc_del_key(struct registry_key *parent, const char *name) struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key); struct winreg_DeleteKey r; TALLOC_CTX *mem_ctx = talloc_init("del_key"); - - r.in.handle = &mykeydata->pol; - init_winreg_String(&r.in.key, name); - - status = dcerpc_winreg_DeleteKey(mykeydata->pipe, mem_ctx, &r); + + r.in.handle = &mykeydata->pol; + init_winreg_String(&r.in.key, name); + + status = dcerpc_winreg_DeleteKey(mykeydata->pipe, mem_ctx, &r); talloc_free(mem_ctx); @@ -334,19 +336,19 @@ static WERROR rpc_del_key(struct registry_key *parent, const char *name) } static WERROR rpc_get_info(TALLOC_CTX *mem_ctx, const struct registry_key *key, - const char **classname, + const char **classname, uint32_t *numsubkeys, uint32_t *numvalue, NTTIME *last_changed_time) { struct rpc_key *mykeydata = talloc_get_type(key, struct rpc_key); WERROR error; - - if(mykeydata->num_values == -1) { + + if (mykeydata->num_values == -1) { error = rpc_query_key(key); if(!W_ERROR_IS_OK(error)) return error; } - + /* FIXME: *classname = talloc_strdup(mem_ctx, mykeydata->classname); */ /* FIXME: *last_changed_time = mykeydata->last_changed_time */ @@ -370,10 +372,10 @@ static struct registry_operations reg_backend_rpc = { .get_predefined_key = rpc_get_predefined_key, }; -_PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - const char *location, struct event_context *ev) +_PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + const char *location, struct event_context *ev) { NTSTATUS status; struct dcerpc_pipe *p; @@ -388,14 +390,15 @@ _PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, location = talloc_strdup(ctx, "ncalrpc:"); } - status = dcerpc_pipe_connect(*ctx /* TALLOC_CTX */, - &p, location, + status = dcerpc_pipe_connect(*ctx /* TALLOC_CTX */, + &p, location, &ndr_table_winreg, credentials, ev); rctx->pipe = p; if(NT_STATUS_IS_ERR(status)) { - DEBUG(1, ("Unable to open '%s': %s\n", location, nt_errstr(status))); + DEBUG(1, ("Unable to open '%s': %s\n", location, + nt_errstr(status))); talloc_free(*ctx); *ctx = NULL; return ntstatus_to_werror(status); diff --git a/source4/lib/registry/samba.c b/source4/lib/registry/samba.c index 18bbcb8299..2397432f0b 100644 --- a/source4/lib/registry/samba.c +++ b/source4/lib/registry/samba.c @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. Copyright (C) Jelmer Vernooij 2004-2007. @@ -25,23 +25,25 @@ * @brief Samba-specific registry functions */ -static WERROR mount_samba_hive(struct registry_context *ctx, +static WERROR mount_samba_hive(struct registry_context *ctx, struct auth_session_info *auth_info, struct cli_credentials *creds, - const char *name, + const char *name, uint32_t hive_id) { WERROR error; struct hive_key *hive; const char *location; - location = talloc_asprintf(ctx, "%s/%s.ldb", lp_private_dir(global_loadparm), name); - + location = talloc_asprintf(ctx, "%s/%s.ldb", + lp_private_dir(global_loadparm), + name); error = reg_open_hive(ctx, location, auth_info, creds, &hive); if (W_ERROR_EQUAL(error, WERR_NOT_FOUND)) - error = reg_open_ldb_file(ctx, location, auth_info, creds, &hive); + error = reg_open_ldb_file(ctx, location, auth_info, + creds, &hive); if (!W_ERROR_IS_OK(error)) return error; @@ -50,10 +52,10 @@ static WERROR mount_samba_hive(struct registry_context *ctx, } -_PUBLIC_ WERROR reg_open_samba (TALLOC_CTX *mem_ctx, - struct registry_context **ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials) +_PUBLIC_ WERROR reg_open_samba(TALLOC_CTX *mem_ctx, + struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials) { WERROR result; @@ -62,19 +64,19 @@ _PUBLIC_ WERROR reg_open_samba (TALLOC_CTX *mem_ctx, return result; } - mount_samba_hive(*ctx, session_info, credentials, - "hklm", HKEY_LOCAL_MACHINE); + mount_samba_hive(*ctx, session_info, credentials, + "hklm", HKEY_LOCAL_MACHINE); - mount_samba_hive(*ctx, session_info, credentials, - "hkcr", HKEY_CLASSES_ROOT); + mount_samba_hive(*ctx, session_info, credentials, + "hkcr", HKEY_CLASSES_ROOT); - /* FIXME: Should be mounted from NTUSER.DAT in the home directory of the + /* FIXME: Should be mounted from NTUSER.DAT in the home directory of the * current user */ - mount_samba_hive(*ctx, session_info, credentials, - "hkcu", HKEY_CURRENT_USER); + mount_samba_hive(*ctx, session_info, credentials, + "hkcu", HKEY_CURRENT_USER); - mount_samba_hive(*ctx, session_info, credentials, - "hku", HKEY_USERS); + mount_samba_hive(*ctx, session_info, credentials, + "hku", HKEY_USERS); /* FIXME: Different hive backend for HKEY_CLASSES_ROOT: merged view of HKEY_LOCAL_MACHINE\Software\Classes * and HKEY_CURRENT_USER\Software\Classes */ @@ -86,6 +88,6 @@ _PUBLIC_ WERROR reg_open_samba (TALLOC_CTX *mem_ctx, /* FIXME: HKEY_LOCAL_MACHINE\Hardware is autogenerated */ /* FIXME: HKEY_LOCAL_MACHINE\Security\SAM is an alias for HKEY_LOCAL_MACHINE\SAM */ - + return WERR_OK; } diff --git a/source4/lib/registry/util.c b/source4/lib/registry/util.c index 78b578d2e5..ca3e3dd619 100644 --- a/source4/lib/registry/util.c +++ b/source4/lib/registry/util.c @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. Transparent registry backend handling Copyright (C) Jelmer Vernooij 2003-2007. @@ -43,60 +43,59 @@ _PUBLIC_ const char *str_regtype(int type) { int i; for (i = 0; reg_value_types[i].name; i++) { - if (reg_value_types[i].id == type) + if (reg_value_types[i].id == type) return reg_value_types[i].name; } return "Unknown"; } -_PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, +_PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, const DATA_BLOB data) -{ - char *ret = NULL; - - if (data.length == 0) - return talloc_strdup(mem_ctx, ""); - - switch (type) { - case REG_EXPAND_SZ: - case REG_SZ: - convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, data.data, data.length, - (void **)&ret); - return ret; - - case REG_BINARY: - ret = data_blob_hex_string(mem_ctx, &data); - return ret; - - case REG_DWORD: - if (*(int *)data.data == 0) - return talloc_strdup(mem_ctx, "0"); - - return talloc_asprintf(mem_ctx, "0x%x", *(int *)data.data); +{ + char *ret = NULL; - case REG_MULTI_SZ: - /* FIXME */ - break; + if (data.length == 0) + return talloc_strdup(mem_ctx, ""); - default: - break; - } + switch (type) { + case REG_EXPAND_SZ: + case REG_SZ: + convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, + data.data, data.length, + (void **)&ret); + return ret; + case REG_BINARY: + ret = data_blob_hex_string(mem_ctx, &data); + return ret; + case REG_DWORD: + if (*(int *)data.data == 0) + return talloc_strdup(mem_ctx, "0"); + return talloc_asprintf(mem_ctx, "0x%x", + *(int *)data.data); + case REG_MULTI_SZ: + /* FIXME */ + break; + default: + break; + } - return ret; + return ret; } /** Generate a string that describes a registry value */ -_PUBLIC_ char *reg_val_description(TALLOC_CTX *mem_ctx, const char *name, - uint32_t data_type, - const DATA_BLOB data) +_PUBLIC_ char *reg_val_description(TALLOC_CTX *mem_ctx, const char *name, + uint32_t data_type, + const DATA_BLOB data) { - return talloc_asprintf(mem_ctx, "%s = %s : %s", name?name:"", - str_regtype(data_type), - reg_val_data_string(mem_ctx, data_type, data)); + return talloc_asprintf(mem_ctx, "%s = %s : %s", name?name:"", + str_regtype(data_type), + reg_val_data_string(mem_ctx, data_type, data)); } -_PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data) +_PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, + const char *data_str, uint32_t *type, + DATA_BLOB *data) { int i; *type = -1; @@ -109,16 +108,18 @@ _PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const } } - if (*type == -1) + if (*type == -1) return false; /* Convert data appropriately */ - switch (*type) + switch (*type) { case REG_SZ: case REG_EXPAND_SZ: - data->length = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, data_str, strlen(data_str), (void **)&data->data); + data->length = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, + data_str, strlen(data_str), + (void **)&data->data); break; case REG_DWORD: { @@ -130,12 +131,12 @@ _PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const case REG_NONE: ZERO_STRUCTP(data); break; - - case REG_BINARY: + + case REG_BINARY: *data = strhex_to_data_blob(data_str); talloc_steal(mem_ctx, data->data); break; - + default: /* FIXME */ return false; @@ -144,16 +145,17 @@ _PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const } /** Open a key by name (including the predefined key name!) */ -WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result) +WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, + const char *name, struct registry_key **result) { struct registry_key *predef; WERROR error; int predeflength; char *predefname; - if (strchr(name, '\\') != NULL) + if (strchr(name, '\\') != NULL) predeflength = strchr(name, '\\')-name; - else + else predeflength = strlen(name); predefname = talloc_strndup(mem_ctx, name, predeflength); @@ -165,31 +167,32 @@ WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, co } if (strchr(name, '\\')) { - return reg_open_key(mem_ctx, predef, strchr(name, '\\')+1, result); + return reg_open_key(mem_ctx, predef, strchr(name, '\\')+1, + result); } else { *result = predef; return WERR_OK; } } -static WERROR get_abs_parent(TALLOC_CTX *mem_ctx, struct registry_context *ctx, - const char *path, struct registry_key **parent, - const char **name) +static WERROR get_abs_parent(TALLOC_CTX *mem_ctx, struct registry_context *ctx, + const char *path, struct registry_key **parent, + const char **name) { char *parent_name; WERROR error; - + if (strchr(path, '\\') == NULL) { return WERR_FOOBAR; } - + parent_name = talloc_strndup(mem_ctx, path, strrchr(path, '\\')-path); error = reg_open_key_abs(mem_ctx, ctx, parent_name, parent); if (!W_ERROR_IS_OK(error)) { return error; } - + *name = talloc_strdup(mem_ctx, strrchr(path, '\\')+1); return WERR_OK; @@ -201,11 +204,11 @@ WERROR reg_key_del_abs(struct registry_context *ctx, const char *path) const char *n; TALLOC_CTX *mem_ctx = talloc_init("reg_key_del_abs"); WERROR error; - + if (!strchr(path, '\\')) { return WERR_FOOBAR; } - + error = get_abs_parent(mem_ctx, ctx, path, &parent, &n); if (W_ERROR_IS_OK(error)) { error = reg_key_del(parent, n); @@ -216,22 +219,22 @@ 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_t access_mask, - struct security_descriptor *sec_desc, - struct registry_key **result) +WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx, + const char *path, uint32_t access_mask, + struct security_descriptor *sec_desc, + struct registry_key **result) { struct registry_key *parent; const char *n; WERROR error; - + if (!strchr(path, '\\')) { return WERR_ALREADY_EXISTS; } - + error = get_abs_parent(mem_ctx, ctx, path, &parent, &n); if (!W_ERROR_IS_OK(error)) { - DEBUG(2, ("Opening parent of %s failed with %s\n", path, + DEBUG(2, ("Opening parent of %s failed with %s\n", path, win_errstr(error))); return error; } diff --git a/source4/lib/registry/wine.c b/source4/lib/registry/wine.c index 2cb0b9955e..77d2ce66e9 100644 --- a/source4/lib/registry/wine.c +++ b/source4/lib/registry/wine.c @@ -1,18 +1,18 @@ -/* +/* Unix SMB/CIFS implementation. Registry interface Copyright (C) Jelmer Vernooij 2007. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -29,7 +29,7 @@ static WERROR wine_open_reg (struct registry_hive *h, struct registry_key **key) static REG_OPS reg_backend_wine = { .name = "wine", .open_hive = wine_open_reg, - + }; NTSTATUS registry_wine_init(void) -- cgit From 33032276f532f5344d56ca6c436befb2e3b74fc5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 10 Oct 2007 12:27:24 +0200 Subject: r25603: More reformat. Guenther (This used to be commit 176614423ea57e853211c43b9853203243c6a978) --- source4/lib/registry/tools/common.c | 28 ++++--- source4/lib/registry/tools/regdiff.c | 26 +++--- source4/lib/registry/tools/regpatch.c | 12 +-- source4/lib/registry/tools/regshell.c | 146 +++++++++++++++++++--------------- source4/lib/registry/tools/regtree.c | 70 +++++++++------- 5 files changed, 164 insertions(+), 118 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/common.c b/source4/lib/registry/tools/common.c index aa11eccbee..0233f27437 100644 --- a/source4/lib/registry/tools/common.c +++ b/source4/lib/registry/tools/common.c @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. Popt routines specifically for registry @@ -8,12 +8,12 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -23,22 +23,25 @@ #include "lib/registry/registry.h" #include "lib/registry/tools/common.h" -struct registry_context *reg_common_open_remote(const char *remote, struct cli_credentials *creds) +struct registry_context *reg_common_open_remote(const char *remote, + struct cli_credentials *creds) { struct registry_context *h; WERROR error; - + error = reg_open_remote(&h, NULL, creds, remote, NULL); if (!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Unable to open remote registry at %s:%s \n", remote, win_errstr(error)); + fprintf(stderr, "Unable to open remote registry at %s:%s \n", + remote, win_errstr(error)); return NULL; } return h; } -struct registry_key *reg_common_open_file(const char *path, struct cli_credentials *creds) +struct registry_key *reg_common_open_file(const char *path, + struct cli_credentials *creds) { struct hive_key *hive_root; struct registry_context *h; @@ -47,13 +50,15 @@ struct registry_key *reg_common_open_file(const char *path, struct cli_credentia error = reg_open_hive(NULL, path, NULL, creds, &hive_root); if(!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Unable to open '%s': %s \n", path, win_errstr(error)); + fprintf(stderr, "Unable to open '%s': %s \n", + path, win_errstr(error)); return NULL; } error = reg_open_local(NULL, &h, NULL, creds); if (!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Unable to initialize local registry: %s\n", win_errstr(error)); + fprintf(stderr, "Unable to initialize local registry: %s\n", + win_errstr(error)); return NULL; } @@ -64,11 +69,12 @@ struct registry_context *reg_common_open_local(struct cli_credentials *creds) { WERROR error; struct registry_context *h; - + error = reg_open_samba(NULL, &h, NULL, creds); if(!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Unable to open local registry:%s \n", win_errstr(error)); + fprintf(stderr, "Unable to open local registry:%s \n", + win_errstr(error)); return NULL; } diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 8030457f5c..f96761cda0 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -1,7 +1,7 @@ -/* +/* Unix SMB/CIFS implementation. simple registry frontend - + Copyright (C) Jelmer Vernooij 2004-2007 Copyright (C) Wilco Baan Hofman 2006 @@ -9,12 +9,12 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -27,11 +27,13 @@ enum reg_backend { REG_UNKNOWN, REG_LOCAL, REG_REMOTE, REG_NULL }; -static struct registry_context *open_backend(poptContext pc, enum reg_backend backend, const char *remote_host) +static struct registry_context *open_backend(poptContext pc, + enum reg_backend backend, + const char *remote_host) { WERROR error; struct registry_context *ctx; - + switch (backend) { case REG_UNKNOWN: poptPrintUsage(pc, stderr, 0); @@ -40,7 +42,8 @@ static struct registry_context *open_backend(poptContext pc, enum reg_backend ba error = reg_open_samba(NULL, &ctx, NULL, cmdline_credentials); break; case REG_REMOTE: - error = reg_open_remote(&ctx, NULL, cmdline_credentials, remote_host, NULL); + error = reg_open_remote(&ctx, NULL, cmdline_credentials, + remote_host, NULL); break; case REG_NULL: error = reg_open_local(NULL, &ctx, NULL, cmdline_credentials); @@ -121,15 +124,18 @@ int main(int argc, const char **argv) poptFreeContext(pc); - error = reg_dotreg_diff_save(ctx, outputfile, &callbacks, &callback_data); + error = reg_dotreg_diff_save(ctx, outputfile, &callbacks, + &callback_data); if (!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Problem saving registry diff to '%s': %s\n", outputfile, win_errstr(error)); + fprintf(stderr, "Problem saving registry diff to '%s': %s\n", + outputfile, win_errstr(error)); return -1; } error = reg_generate_diff(h1, h2, callbacks, callback_data); if (!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Unable to generate diff between keys: %s\n", win_errstr(error)); + fprintf(stderr, "Unable to generate diff between keys: %s\n", + win_errstr(error)); return -1; } diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 1e6d15a7af..35f12c7e62 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -1,19 +1,19 @@ -/* +/* Unix SMB/CIFS implementation. simple registry frontend - + Copyright (C) 2004-2007 Jelmer Vernooij, jelmer@samba.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -52,10 +52,10 @@ int main(int argc, char **argv) } else { h = reg_common_open_local (cmdline_credentials); } - + if (h == NULL) return 1; - + patch = poptGetArg(pc); if (patch == NULL) { poptPrintUsage(pc, stderr, 0); diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index cdf688b39e..7dbcf2f875 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -1,19 +1,19 @@ -/* +/* Unix SMB/CIFS implementation. simple registry frontend - + Copyright (C) Jelmer Vernooij 2004-2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -55,14 +55,15 @@ static WERROR cmd_info(struct regshell_context *ctx, int argc, char **argv) const char *classname; NTTIME last_change; - error = reg_key_get_info(ctx, ctx->current, &classname, NULL, NULL, &last_change); + error = reg_key_get_info(ctx, ctx->current, &classname, NULL, NULL, + &last_change); if (!W_ERROR_IS_OK(error)) { printf("Error getting key info: %s\n", win_errstr(error)); return error; } - - printf("Name: %s\n", strchr(ctx->path, '\\')?strrchr(ctx->path, '\\')+1: + + printf("Name: %s\n", strchr(ctx->path, '\\')?strrchr(ctx->path, '\\')+1: ctx->path); printf("Full path: %s\n", ctx->path); printf("Key Class: %s\n", classname); @@ -73,8 +74,9 @@ static WERROR cmd_info(struct regshell_context *ctx, int argc, char **argv) if (!W_ERROR_IS_OK(error)) { printf("Error getting security descriptor\n"); return error; - } - ndr_print_debug((ndr_print_fn_t)ndr_print_security_descriptor, "Security", sec_desc); + } + ndr_print_debug((ndr_print_fn_t)ndr_print_security_descriptor, + "Security", sec_desc); talloc_free(sec_desc); return WERR_OK; @@ -88,10 +90,12 @@ static WERROR cmd_predef(struct regshell_context *ctx, int argc, char **argv) } else if (!ctx) { fprintf(stderr, "No full registry loaded, no predefined keys defined\n"); } else { - WERROR error = reg_get_predefined_key_by_name(ctx->registry, argv[1], &ret); + WERROR error = reg_get_predefined_key_by_name(ctx->registry, + argv[1], &ret); if (!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Error opening predefined key %s: %s\n", argv[1], win_errstr(error)); + fprintf(stderr, "Error opening predefined key %s: %s\n", + argv[1], win_errstr(error)); return error; } } @@ -100,7 +104,7 @@ static WERROR cmd_predef(struct regshell_context *ctx, int argc, char **argv) } static WERROR cmd_pwd(struct regshell_context *ctx, - int argc, char **argv) + int argc, char **argv) { printf("%s\n", ctx->path); return WERR_OK; @@ -114,10 +118,10 @@ static WERROR cmd_set(struct regshell_context *ctx, int argc, char **argv) if (argc < 4) { fprintf(stderr, "Usage: set value-name type value\n"); return WERR_INVALID_PARAM; - } + } - if (!reg_string_to_val(ctx, argv[2], argv[3], &val.data_type, - &val.data)) { + if (!reg_string_to_val(ctx, argv[2], argv[3], &val.data_type, + &val.data)) { fprintf(stderr, "Unable to interpret data\n"); return WERR_INVALID_PARAM; } @@ -132,24 +136,26 @@ static WERROR cmd_set(struct regshell_context *ctx, int argc, char **argv) } static WERROR cmd_ck(struct regshell_context *ctx, int argc, char **argv) -{ +{ struct registry_key *new = NULL; WERROR error; if(argc < 2) { new = ctx->current; } else { - error = reg_open_key(ctx->registry, ctx->current, argv[1], &new); + error = reg_open_key(ctx->registry, ctx->current, argv[1], + &new); if(!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error opening specified key: %s\n", win_errstr(error))); + DEBUG(0, ("Error opening specified key: %s\n", + win_errstr(error))); return error; } - } + } ctx->path = talloc_asprintf(ctx, "%s\\%s", ctx->path, argv[1]); printf("Current path is: %s\n", ctx->path); ctx->current = new; - + return WERR_OK; } @@ -163,15 +169,15 @@ static WERROR cmd_print(struct regshell_context *ctx, int argc, char **argv) fprintf(stderr, "Usage: print "); return WERR_INVALID_PARAM; } - - error = reg_key_get_value_by_name(ctx, ctx->current, argv[1], - &value_type, &value_data); + + error = reg_key_get_value_by_name(ctx, ctx->current, argv[1], + &value_type, &value_data); if (!W_ERROR_IS_OK(error)) { fprintf(stderr, "No such value '%s'\n", argv[1]); return error; } - printf("%s\n%s\n", str_regtype(value_type), + printf("%s\n%s\n", str_regtype(value_type), reg_val_data_string(ctx, value_type, value_data)); return WERR_OK; @@ -186,23 +192,34 @@ static WERROR cmd_ls(struct regshell_context *ctx, int argc, char **argv) DATA_BLOB data; const char *name; - for (i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(ctx, ctx->current, i, &name, NULL, NULL)); i++) { + for (i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(ctx, + ctx->current, + i, + &name, + NULL, + NULL)); i++) { printf("K %s\n", name); } if (!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while browsing thru keys: %s\n", win_errstr(error))); + DEBUG(0, ("Error occured while browsing thru keys: %s\n", + win_errstr(error))); } - for (i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(ctx, ctx->current, i, &name, &data_type, &data)); i++) { - printf("V \"%s\" %s %s\n", value->name, str_regtype(data_type), + for (i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(ctx, + ctx->current, + i, + &name, + &data_type, + &data)); i++) { + printf("V \"%s\" %s %s\n", value->name, str_regtype(data_type), reg_val_data_string(ctx, data_type, data)); } - - return WERR_OK; + + return WERR_OK; } static WERROR cmd_mkkey(struct regshell_context *ctx, int argc, char **argv) -{ +{ struct registry_key *tmp; WERROR error; @@ -212,18 +229,18 @@ static WERROR cmd_mkkey(struct regshell_context *ctx, int argc, char **argv) } error = reg_key_add_name(ctx, ctx->current, argv[1], 0, NULL, &tmp); - + if (!W_ERROR_IS_OK(error)) { fprintf(stderr, "Error adding new subkey '%s'\n", argv[1]); return error; } - return WERR_OK; + return WERR_OK; } static WERROR cmd_rmkey(struct regshell_context *ctx, - int argc, char **argv) -{ + int argc, char **argv) +{ WERROR error; if(argc < 2) { @@ -238,12 +255,12 @@ static WERROR cmd_rmkey(struct regshell_context *ctx, } else { fprintf(stderr, "Successfully deleted '%s'\n", argv[1]); } - + return WERR_OK; } static WERROR cmd_rmval(struct regshell_context *ctx, int argc, char **argv) -{ +{ WERROR error; if(argc < 2) { @@ -259,10 +276,11 @@ static WERROR cmd_rmval(struct regshell_context *ctx, int argc, char **argv) fprintf(stderr, "Successfully deleted value '%s'\n", argv[1]); } - return WERR_OK; + return WERR_OK; } -_NORETURN_ static WERROR cmd_exit(struct regshell_context *ctx, int argc, char **argv) +_NORETURN_ static WERROR cmd_exit(struct regshell_context *ctx, + int argc, char **argv) { exit(0); return WERR_OK; @@ -292,18 +310,19 @@ static struct { }; static WERROR cmd_help(struct regshell_context *ctx, - int argc, char **argv) + int argc, char **argv) { int i; printf("Available commands:\n"); for(i = 0; regshell_cmds[i].name; i++) { - printf("%s - %s\n", regshell_cmds[i].name, regshell_cmds[i].help); + printf("%s - %s\n", regshell_cmds[i].name, + regshell_cmds[i].help); } return WERR_OK; -} +} static WERROR process_cmd(struct regshell_context *ctx, - char *line) + char *line) { int argc; char **argv = NULL; @@ -315,14 +334,14 @@ static WERROR process_cmd(struct regshell_context *ctx, } for(i = 0; regshell_cmds[i].name; i++) { - if(!strcmp(regshell_cmds[i].name, argv[0]) || + if(!strcmp(regshell_cmds[i].name, argv[0]) || (regshell_cmds[i].alias && !strcmp(regshell_cmds[i].alias, argv[0]))) { return regshell_cmds[i].handle(ctx, argc, argv); } } fprintf(stderr, "No such command '%s'\n", argv[0]); - + return WERR_INVALID_PARAM; } @@ -399,8 +418,8 @@ static char **reg_complete_key(const char *text, int start, int end) len = strlen(text); for(i = 0; j < MAX_COMPLETIONS-1; i++) { - status = reg_key_get_subkey_by_index(mem_ctx, base, i, &subkeyname, - NULL, NULL); + status = reg_key_get_subkey_by_index(mem_ctx, base, i, + &subkeyname, NULL, NULL); if(W_ERROR_IS_OK(status)) { if(!strncmp(text, subkeyname, len)) { matches[j] = strdup(subkeyname); @@ -415,7 +434,8 @@ static char **reg_complete_key(const char *text, int start, int end) } else if(W_ERROR_EQUAL(status, WERR_NO_MORE_ITEMS)) { break; } else { - printf("Error creating completion list: %s\n", win_errstr(status)); + printf("Error creating completion list: %s\n", + win_errstr(status)); talloc_free(mem_ctx); return NULL; } @@ -430,9 +450,9 @@ static char **reg_complete_key(const char *text, int start, int end) if (j == 2) { /* Exact match */ asprintf(&matches[0], "%s%s", base_n, matches[1]); } else { - asprintf(&matches[0], "%s%s", base_n, + asprintf(&matches[0], "%s%s", base_n, talloc_strndup(mem_ctx, matches[1], samelen)); - } + } talloc_free(mem_ctx); matches[j] = NULL; @@ -469,14 +489,15 @@ int main(int argc, char **argv) }; pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); - + while((opt = poptGetNextOpt(pc)) != -1) { } ctx = talloc_zero(NULL, struct regshell_context); if (remote != NULL) { - ctx->registry = reg_common_open_remote(remote, cmdline_credentials); + ctx->registry = reg_common_open_remote(remote, + cmdline_credentials); } else if (file != NULL) { ctx->current = reg_common_open_file(file, cmdline_credentials); if (ctx->current == NULL) @@ -495,11 +516,12 @@ int main(int argc, char **argv) for (i = 0; reg_predefined_keys[i].handle; i++) { WERROR err; - err = reg_get_predefined_key(ctx->registry, - reg_predefined_keys[i].handle, - &ctx->current); + err = reg_get_predefined_key(ctx->registry, + reg_predefined_keys[i].handle, + &ctx->current); if (W_ERROR_IS_OK(err)) { - ctx->path = talloc_strdup(ctx, reg_predefined_keys[i].name); + ctx->path = talloc_strdup(ctx, + reg_predefined_keys[i].name); break; } else { ctx->current = NULL; @@ -511,16 +533,16 @@ int main(int argc, char **argv) fprintf(stderr, "Unable to access any of the predefined keys\n"); return -1; } - + poptFreeContext(pc); - + while (true) { char *line, *prompt; - + asprintf(&prompt, "%s> ", ctx->path); - - current_key = ctx->current; /* No way to pass a void * pointer - via readline :-( */ + + current_key = ctx->current; /* No way to pass a void * pointer + via readline :-( */ line = smb_readline(prompt, NULL, reg_completion); if (line == NULL) diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 8d2460a93e..9f8d8c012d 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -1,19 +1,19 @@ -/* +/* Unix SMB/CIFS implementation. simple registry frontend - + Copyright (C) Jelmer Vernooij 2004-2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -25,16 +25,16 @@ #include "lib/cmdline/popt_common.h" /** - * Print a registry key recursively - * + * Print a registry key recursively + * * @param level Level at which to print * @param p Key to print * @param fullpath Whether the full pat hshould be printed or just the last bit * @param novals Whether values should not be printed */ -static void print_tree(int level, struct registry_key *p, - const char *name, - bool fullpath, bool novals) +static void print_tree(int level, struct registry_key *p, + const char *name, + bool fullpath, bool novals) { struct registry_key *subkey; const char *valuename; @@ -49,37 +49,47 @@ static void print_tree(int level, struct registry_key *p, for(i = 0; i < level; i++) putchar(' '); puts(name); mem_ctx = talloc_init("print_tree"); - for (i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(mem_ctx, p, i, &keyname, NULL, NULL)); i++) { + for (i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(mem_ctx, + p, + i, + &keyname, + NULL, + NULL)); i++) { SMB_ASSERT(strlen(keyname) > 0); - if (!W_ERROR_IS_OK(reg_open_key(mem_ctx, p, keyname, &subkey))) + if (!W_ERROR_IS_OK(reg_open_key(mem_ctx, p, keyname, &subkey))) continue; print_tree(level+1, subkey, (fullpath && strlen(name))? - talloc_asprintf(mem_ctx, "%s\\%s", name, keyname): + talloc_asprintf(mem_ctx, "%s\\%s", + name, keyname): keyname, fullpath, novals); } talloc_free(mem_ctx); if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while fetching subkeys for '%s': %s\n", + DEBUG(0, ("Error occured while fetching subkeys for '%s': %s\n", name, win_errstr(error))); } if (!novals) { mem_ctx = talloc_init("print_tree"); - for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(mem_ctx, - p, i, &valuename, &value_type, &value_data)); i++) { + for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(mem_ctx, + p, + i, + &valuename, + &value_type, + &value_data)); i++) { int j; char *desc; for(j = 0; j < level+1; j++) putchar(' '); - desc = reg_val_description(mem_ctx, valuename, value_type, - value_data); + desc = reg_val_description(mem_ctx, valuename, + value_type, value_data); printf("%s\n", desc); } talloc_free(mem_ctx); if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { - DEBUG(0, ("Error occured while fetching values for '%s': %s\n", - name, win_errstr(error))); + DEBUG(0, ("Error occured while fetching values for '%s': %s\n", + name, win_errstr(error))); } } @@ -106,14 +116,14 @@ int main(int argc, char **argv) {"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL }, {"fullpath", 'f', POPT_ARG_NONE, &fullpath, 0, "show full paths", NULL}, {"no-values", 'V', POPT_ARG_NONE, &no_values, 0, "don't show values", NULL}, - POPT_COMMON_SAMBA - POPT_COMMON_CREDENTIALS + POPT_COMMON_SAMBA + POPT_COMMON_CREDENTIALS POPT_COMMON_VERSION { NULL } }; pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0); - + while((opt = poptGetNextOpt(pc)) != -1) { } @@ -131,21 +141,23 @@ int main(int argc, char **argv) poptFreeContext(pc); error = WERR_OK; - + if (start_key != NULL) { print_tree(0, start_key, "", fullpath, no_values); } else { for(i = 0; reg_predefined_keys[i].handle; i++) { - error = reg_get_predefined_key(h, reg_predefined_keys[i].handle, - &start_key); + error = reg_get_predefined_key(h, + reg_predefined_keys[i].handle, + &start_key); if (!W_ERROR_IS_OK(error)) { - fprintf(stderr, "Skipping %s: %s\n", reg_predefined_keys[i].name, - win_errstr(error)); + fprintf(stderr, "Skipping %s: %s\n", + reg_predefined_keys[i].name, + win_errstr(error)); continue; } SMB_ASSERT(start_key != NULL); - print_tree(0, start_key, reg_predefined_keys[i].name, fullpath, - no_values); + print_tree(0, start_key, reg_predefined_keys[i].name, + fullpath, no_values); } } -- cgit From c353a7b05e8475bbc726123ae41c91102d96c6f5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 10 Oct 2007 12:44:48 +0200 Subject: r25605: Last round of registry reformats (before this gets an obsession...). Guenther (This used to be commit ceb2ebfbf1eeb80bd34beadbba3a3c7a04da306a) --- source4/lib/registry/tests/diff.c | 34 ++-- source4/lib/registry/tests/generic.c | 99 ++++++----- source4/lib/registry/tests/hive.c | 154 +++++++++-------- source4/lib/registry/tests/registry.c | 312 +++++++++++++++++++--------------- 4 files changed, 328 insertions(+), 271 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/diff.c b/source4/lib/registry/tests/diff.c index 99a4589309..8e6907382c 100644 --- a/source4/lib/registry/tests/diff.c +++ b/source4/lib/registry/tests/diff.c @@ -1,20 +1,20 @@ -/* +/* Unix SMB/CIFS implementation. local testing of registry diff functionality Copyright (C) Jelmer Vernooij 2007 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -27,8 +27,8 @@ static bool test_generate_diff(struct torture_context *test) { - /* WERROR reg_generate_diff(struct registry_context *ctx1, - struct registry_context *ctx2, + /* WERROR reg_generate_diff(struct registry_context *ctx1, + struct registry_context *ctx2, const struct reg_diff_callbacks *callbacks, void *callback_data) */ @@ -52,7 +52,7 @@ static bool test_diff_apply(struct torture_context *test) static const char *added_key = NULL; -static WERROR test_add_key (void *callback_data, const char *key_name) +static WERROR test_add_key(void *callback_data, const char *key_name) { added_key = talloc_strdup(callback_data, key_name); @@ -90,14 +90,18 @@ static bool test_generate_diff_key_null(struct torture_context *test) return true; } -struct torture_suite *torture_registry_diff(TALLOC_CTX *mem_ctx) +struct torture_suite *torture_registry_diff(TALLOC_CTX *mem_ctx) { - struct torture_suite *suite = torture_suite_create(mem_ctx, - "DIFF"); - torture_suite_add_simple_test(suite, "test_generate_diff_key_add", test_generate_diff_key_add); - torture_suite_add_simple_test(suite, "test_generate_diff_key_null", test_generate_diff_key_null); - torture_suite_add_simple_test(suite, "test_diff_apply", test_diff_apply); - torture_suite_add_simple_test(suite, "test_generate_diff", test_generate_diff); - torture_suite_add_simple_test(suite, "test_diff_load", test_diff_load); + struct torture_suite *suite = torture_suite_create(mem_ctx, "DIFF"); + torture_suite_add_simple_test(suite, "test_generate_diff_key_add", + test_generate_diff_key_add); + torture_suite_add_simple_test(suite, "test_generate_diff_key_null", + test_generate_diff_key_null); + torture_suite_add_simple_test(suite, "test_diff_apply", + test_diff_apply); + torture_suite_add_simple_test(suite, "test_generate_diff", + test_generate_diff); + torture_suite_add_simple_test(suite, "test_diff_load", + test_diff_load); return suite; } diff --git a/source4/lib/registry/tests/generic.c b/source4/lib/registry/tests/generic.c index 549ed6282d..1b680f20b7 100644 --- a/source4/lib/registry/tests/generic.c +++ b/source4/lib/registry/tests/generic.c @@ -1,20 +1,20 @@ -/* +/* Unix SMB/CIFS implementation. local testing of registry library Copyright (C) Jelmer Vernooij 2005-2007 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -31,8 +31,10 @@ struct torture_suite *torture_registry_diff(TALLOC_CTX *mem_ctx); static bool test_str_regtype(struct torture_context *ctx) { - torture_assert_str_equal(ctx, str_regtype(1), "REG_SZ", "REG_SZ failed"); - torture_assert_str_equal(ctx, str_regtype(4), "REG_DWORD", "REG_DWORD failed"); + torture_assert_str_equal(ctx, str_regtype(1), + "REG_SZ", "REG_SZ failed"); + torture_assert_str_equal(ctx, str_regtype(4), + "REG_DWORD", "REG_DWORD failed"); return true; } @@ -42,18 +44,24 @@ static bool test_reg_val_data_string_dword(struct torture_context *ctx) { uint32_t d = 0x20; DATA_BLOB db = { (uint8_t *)&d, sizeof(d) }; - torture_assert_str_equal(ctx, "0x20", - reg_val_data_string(ctx, REG_DWORD, db), "dword failed"); + torture_assert_str_equal(ctx, "0x20", + reg_val_data_string(ctx, REG_DWORD, db), + "dword failed"); return true; } static bool test_reg_val_data_string_sz(struct torture_context *ctx) { DATA_BLOB db; - db.length = convert_string_talloc(ctx, CH_UNIX, CH_UTF16, "bla", 3, (void **)&db.data); - torture_assert_str_equal(ctx, "bla", reg_val_data_string(ctx, REG_SZ, db), "sz failed"); + db.length = convert_string_talloc(ctx, CH_UNIX, CH_UTF16, + "bla", 3, (void **)&db.data); + torture_assert_str_equal(ctx, "bla", + reg_val_data_string(ctx, REG_SZ, db), + "sz failed"); db.length = 4; - torture_assert_str_equal(ctx, "bl", reg_val_data_string(ctx, REG_SZ, db), "sz failed"); + torture_assert_str_equal(ctx, "bl", + reg_val_data_string(ctx, REG_SZ, db), + "sz failed"); return true; } @@ -61,9 +69,9 @@ static bool test_reg_val_data_string_binary(struct torture_context *ctx) { uint8_t x[] = { 0x1, 0x2, 0x3, 0x4 }; DATA_BLOB db = { x, 4 }; - torture_assert_str_equal(ctx, "01020304", - reg_val_data_string(ctx, REG_BINARY, db), - "binary failed"); + torture_assert_str_equal(ctx, "01020304", + reg_val_data_string(ctx, REG_BINARY, db), + "binary failed"); return true; } @@ -71,21 +79,22 @@ static bool test_reg_val_data_string_binary(struct torture_context *ctx) static bool test_reg_val_data_string_empty(struct torture_context *ctx) { DATA_BLOB db = { NULL, 0 }; - torture_assert_str_equal(ctx, "", - reg_val_data_string(ctx, REG_BINARY, db), "empty failed"); + torture_assert_str_equal(ctx, "", + reg_val_data_string(ctx, REG_BINARY, db), + "empty failed"); return true; } static bool test_reg_val_description(struct torture_context *ctx) { DATA_BLOB data; - data.length = convert_string_talloc(ctx, CH_UNIX, CH_UTF16, - "stationary traveller", - strlen("stationary traveller"), - (void **)&data.data); - torture_assert_str_equal(ctx, "camel = REG_SZ : stationary traveller", - reg_val_description(ctx, "camel", REG_SZ, data), - "reg_val_description failed"); + data.length = convert_string_talloc(ctx, CH_UNIX, CH_UTF16, + "stationary traveller", + strlen("stationary traveller"), + (void **)&data.data); + torture_assert_str_equal(ctx, "camel = REG_SZ : stationary traveller", + reg_val_description(ctx, "camel", REG_SZ, data), + "reg_val_description failed"); return true; } @@ -93,33 +102,35 @@ static bool test_reg_val_description(struct torture_context *ctx) static bool test_reg_val_description_nullname(struct torture_context *ctx) { DATA_BLOB data; - data.length = convert_string_talloc(ctx, CH_UNIX, CH_UTF16, "west berlin", - strlen("west berlin"), (void **)&data.data); - torture_assert_str_equal(ctx, " = REG_SZ : west berlin", - reg_val_description(ctx, NULL, REG_SZ, data), - "description with null name failed"); + data.length = convert_string_talloc(ctx, CH_UNIX, CH_UTF16, + "west berlin", + strlen("west berlin"), + (void **)&data.data); + torture_assert_str_equal(ctx, " = REG_SZ : west berlin", + reg_val_description(ctx, NULL, REG_SZ, data), + "description with null name failed"); return true; } -struct torture_suite *torture_registry(TALLOC_CTX *mem_ctx) +struct torture_suite *torture_registry(TALLOC_CTX *mem_ctx) { - struct torture_suite *suite = torture_suite_create(mem_ctx, - "REGISTRY"); - torture_suite_add_simple_test(suite, "str_regtype", test_str_regtype); - torture_suite_add_simple_test(suite, "reg_val_data_string dword", - test_reg_val_data_string_dword); - torture_suite_add_simple_test(suite, "reg_val_data_string sz", - test_reg_val_data_string_sz); - torture_suite_add_simple_test(suite, "reg_val_data_string binary", - test_reg_val_data_string_binary); - torture_suite_add_simple_test(suite, "reg_val_data_string empty", - test_reg_val_data_string_empty); - torture_suite_add_simple_test(suite, "reg_val_description", - test_reg_val_description); - torture_suite_add_simple_test(suite, "reg_val_description null", - test_reg_val_description_nullname); + struct torture_suite *suite = torture_suite_create(mem_ctx, "REGISTRY"); + torture_suite_add_simple_test(suite, "str_regtype", + test_str_regtype); + torture_suite_add_simple_test(suite, "reg_val_data_string dword", + test_reg_val_data_string_dword); + torture_suite_add_simple_test(suite, "reg_val_data_string sz", + test_reg_val_data_string_sz); + torture_suite_add_simple_test(suite, "reg_val_data_string binary", + test_reg_val_data_string_binary); + torture_suite_add_simple_test(suite, "reg_val_data_string empty", + test_reg_val_data_string_empty); + torture_suite_add_simple_test(suite, "reg_val_description", + test_reg_val_description); + torture_suite_add_simple_test(suite, "reg_val_description null", + test_reg_val_description_nullname); torture_suite_add_suite(suite, torture_registry_hive(mem_ctx)); torture_suite_add_suite(suite, torture_registry_registry(mem_ctx)); diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index dff6d1e829..9e76ce6aa1 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -1,20 +1,20 @@ -/* +/* Unix SMB/CIFS implementation. local testing of registry library - hives Copyright (C) Jelmer Vernooij 2005-2007 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -32,36 +32,38 @@ static bool test_del_nonexistant_key(struct torture_context *tctx, { const struct hive_key *root = (const struct hive_key *)test_data; WERROR error = hive_key_del(root, "bla"); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, - "invalid return code"); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + "invalid return code"); return true; } static bool test_keyinfo_root(struct torture_context *tctx, - const void *test_data) + const void *test_data) { uint32_t num_subkeys, num_values; const struct hive_key *root = (const struct hive_key *)test_data; WERROR error; - /* This is a new backend. There should be no subkeys and no + /* This is a new backend. There should be no subkeys and no * values */ - error = hive_key_get_info(tctx, root, NULL, &num_subkeys, &num_values, - NULL); + error = hive_key_get_info(tctx, root, NULL, &num_subkeys, &num_values, + NULL); torture_assert_werr_ok(tctx, error, "reg_key_num_subkeys()"); - torture_assert_int_equal(tctx, num_subkeys, 0, "New key has non-zero subkey count"); + torture_assert_int_equal(tctx, num_subkeys, 0, + "New key has non-zero subkey count"); torture_assert_werr_ok(tctx, error, "reg_key_num_values"); - torture_assert_int_equal(tctx, num_values, 0, "New key has non-zero value count"); + torture_assert_int_equal(tctx, num_values, 0, + "New key has non-zero value count"); return true; } static bool test_keyinfo_nums(struct torture_context *tctx, - const void *test_data) + const void *test_data) { uint32_t num_subkeys, num_values; const struct hive_key *root = (const struct hive_key *)test_data; @@ -69,18 +71,18 @@ static bool test_keyinfo_nums(struct torture_context *tctx, struct hive_key *subkey; uint32_t data = 42; - error = hive_key_add_name(tctx, root, "Nested Keyll", NULL, - NULL, &subkey); + error = hive_key_add_name(tctx, root, "Nested Keyll", NULL, + NULL, &subkey); torture_assert_werr_ok(tctx, error, "hive_key_add_name"); - error = hive_set_value(root, "Answer", REG_DWORD, - data_blob_talloc(tctx, &data, sizeof(data))); + error = hive_set_value(root, "Answer", REG_DWORD, + data_blob_talloc(tctx, &data, sizeof(data))); torture_assert_werr_ok(tctx, error, "hive_set_value"); - /* This is a new backend. There should be no subkeys and no + /* This is a new backend. There should be no subkeys and no * values */ - error = hive_key_get_info(tctx, root, NULL, &num_subkeys, &num_values, - NULL); + error = hive_key_get_info(tctx, root, NULL, &num_subkeys, &num_values, + NULL); torture_assert_werr_ok(tctx, error, "reg_key_num_subkeys()"); torture_assert_int_equal(tctx, num_subkeys, 1, "subkey count"); @@ -93,15 +95,15 @@ static bool test_keyinfo_nums(struct torture_context *tctx, } static bool test_add_subkey(struct torture_context *tctx, - const void *test_data) + const void *test_data) { WERROR error; struct hive_key *subkey; const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; - error = hive_key_add_name(mem_ctx, root, "Nested Key", NULL, - NULL, &subkey); + error = hive_key_add_name(mem_ctx, root, "Nested Key", NULL, + NULL, &subkey); torture_assert_werr_ok(tctx, error, "hive_key_add_name"); error = hive_key_del(root, "Nested Key"); @@ -127,8 +129,8 @@ static bool test_del_key(struct torture_context *tctx, const void *test_data) const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; - error = hive_key_add_name(mem_ctx, root, "Nested Key", NULL, - NULL, &subkey); + error = hive_key_add_name(mem_ctx, root, "Nested Key", NULL, + NULL, &subkey); torture_assert_werr_ok(tctx, error, "hive_key_add_name"); error = hive_key_del(root, "Nested Key"); @@ -141,7 +143,7 @@ static bool test_del_key(struct torture_context *tctx, const void *test_data) } static bool test_set_value(struct torture_context *tctx, - const void *test_data) + const void *test_data) { WERROR error; struct hive_key *subkey; @@ -149,12 +151,12 @@ static bool test_set_value(struct torture_context *tctx, TALLOC_CTX *mem_ctx = tctx; uint32_t data = 42; - error = hive_key_add_name(mem_ctx, root, "YA Nested Key", NULL, - NULL, &subkey); + error = hive_key_add_name(mem_ctx, root, "YA Nested Key", NULL, + NULL, &subkey); torture_assert_werr_ok(tctx, error, "hive_key_add_name"); - error = hive_set_value(subkey, "Answer", REG_DWORD, - data_blob_talloc(mem_ctx, &data, sizeof(data))); + error = hive_set_value(subkey, "Answer", REG_DWORD, + data_blob_talloc(mem_ctx, &data, sizeof(data))); torture_assert_werr_ok(tctx, error, "hive_set_value"); return true; @@ -170,16 +172,16 @@ static bool test_get_value(struct torture_context *tctx, const void *test_data) uint32_t type; DATA_BLOB value; - error = hive_key_add_name(mem_ctx, root, "EYA Nested Key", NULL, - NULL, &subkey); + error = hive_key_add_name(mem_ctx, root, "EYA Nested Key", NULL, + NULL, &subkey); torture_assert_werr_ok(tctx, error, "hive_key_add_name"); error = hive_get_value(mem_ctx, subkey, "Answer", &type, &value); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, - "getting missing value"); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + "getting missing value"); - error = hive_set_value(subkey, "Answer", REG_DWORD, - data_blob_talloc(mem_ctx, &data, sizeof(data))); + error = hive_set_value(subkey, "Answer", REG_DWORD, + data_blob_talloc(mem_ctx, &data, sizeof(data))); torture_assert_werr_ok(tctx, error, "hive_set_value"); error = hive_get_value(mem_ctx, subkey, "Answer", &type, &value); @@ -203,12 +205,12 @@ static bool test_del_value(struct torture_context *tctx, const void *test_data) uint32_t type; DATA_BLOB value; - error = hive_key_add_name(mem_ctx, root, "EEYA Nested Key", NULL, + error = hive_key_add_name(mem_ctx, root, "EEYA Nested Key", NULL, NULL, &subkey); torture_assert_werr_ok(tctx, error, "hive_key_add_name"); - error = hive_set_value(subkey, "Answer", REG_DWORD, - data_blob_talloc(mem_ctx, &data, sizeof(data))); + error = hive_set_value(subkey, "Answer", REG_DWORD, + data_blob_talloc(mem_ctx, &data, sizeof(data))); torture_assert_werr_ok(tctx, error, "hive_set_value"); error = hive_del_value(subkey, "Answer"); @@ -218,13 +220,14 @@ static bool test_del_value(struct torture_context *tctx, const void *test_data) torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "getting value"); error = hive_del_value(subkey, "Answer"); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "deleting value"); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + "deleting value"); return true; } -static bool test_list_values(struct torture_context *tctx, - const void *test_data) +static bool test_list_values(struct torture_context *tctx, + const void *test_data) { WERROR error; struct hive_key *subkey; @@ -235,15 +238,16 @@ static bool test_list_values(struct torture_context *tctx, DATA_BLOB value; const char *name; - error = hive_key_add_name(mem_ctx, root, "AYAYA Nested Key", NULL, - NULL, &subkey); + error = hive_key_add_name(mem_ctx, root, "AYAYA Nested Key", NULL, + NULL, &subkey); torture_assert_werr_ok(tctx, error, "hive_key_add_name"); - error = hive_set_value(subkey, "Answer", REG_DWORD, - data_blob_talloc(mem_ctx, &data, sizeof(data))); + error = hive_set_value(subkey, "Answer", REG_DWORD, + data_blob_talloc(mem_ctx, &data, sizeof(data))); torture_assert_werr_ok(tctx, error, "hive_set_value"); - error = hive_get_value_by_index(mem_ctx, subkey, 0, &name, &type, &value); + error = hive_get_value_by_index(mem_ctx, subkey, 0, &name, + &type, &value); torture_assert_werr_ok(tctx, error, "getting value"); torture_assert_str_equal(tctx, name, "Answer", "value name"); @@ -252,26 +256,36 @@ static bool test_list_values(struct torture_context *tctx, torture_assert_int_equal(tctx, value.length, 4, "value length"); torture_assert_int_equal(tctx, type, REG_DWORD, "value type"); - error = hive_get_value_by_index(mem_ctx, subkey, 1, &name, &type, &value); - torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS, - "getting missing value"); + error = hive_get_value_by_index(mem_ctx, subkey, 1, &name, + &type, &value); + torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS, + "getting missing value"); return true; } -static void tcase_add_tests(struct torture_tcase *tcase) +static void tcase_add_tests(struct torture_tcase *tcase) { - torture_tcase_add_simple_test(tcase, "del_nonexistant_key", - test_del_nonexistant_key); - torture_tcase_add_simple_test(tcase, "add_subkey", test_add_subkey); - torture_tcase_add_simple_test(tcase, "flush_key", test_flush_key); - torture_tcase_add_simple_test(tcase, "get_info", test_keyinfo_root); - torture_tcase_add_simple_test(tcase, "get_info_nums", test_keyinfo_nums); - torture_tcase_add_simple_test(tcase, "set_value", test_set_value); - torture_tcase_add_simple_test(tcase, "get_value", test_get_value); - torture_tcase_add_simple_test(tcase, "list_values", test_list_values); - torture_tcase_add_simple_test(tcase, "del_key", test_del_key); - torture_tcase_add_simple_test(tcase, "del_value", test_del_value); + torture_tcase_add_simple_test(tcase, "del_nonexistant_key", + test_del_nonexistant_key); + torture_tcase_add_simple_test(tcase, "add_subkey", + test_add_subkey); + torture_tcase_add_simple_test(tcase, "flush_key", + test_flush_key); + torture_tcase_add_simple_test(tcase, "get_info", + test_keyinfo_root); + torture_tcase_add_simple_test(tcase, "get_info_nums", + test_keyinfo_nums); + torture_tcase_add_simple_test(tcase, "set_value", + test_set_value); + torture_tcase_add_simple_test(tcase, "get_value", + test_get_value); + torture_tcase_add_simple_test(tcase, "list_values", + test_list_values); + torture_tcase_add_simple_test(tcase, "del_key", + test_del_key); + torture_tcase_add_simple_test(tcase, "del_value", + test_del_value); } static bool hive_setup_dir(struct torture_context *tctx, void **data) @@ -348,21 +362,19 @@ static bool hive_setup_regf(struct torture_context *tctx, void **data) static bool test_dir_refuses_null_location(struct torture_context *tctx) { - torture_assert_werr_equal(tctx, WERR_INVALID_PARAM, - reg_open_directory(NULL, NULL, NULL), - "reg_open_directory accepts NULL location"); + torture_assert_werr_equal(tctx, WERR_INVALID_PARAM, + reg_open_directory(NULL, NULL, NULL), + "reg_open_directory accepts NULL location"); return true; } -struct torture_suite *torture_registry_hive(TALLOC_CTX *mem_ctx) +struct torture_suite *torture_registry_hive(TALLOC_CTX *mem_ctx) { struct torture_tcase *tcase; - struct torture_suite *suite = torture_suite_create(mem_ctx, - "HIVE"); - - torture_suite_add_simple_test(suite, "dir-refuses-null-location", - test_dir_refuses_null_location); + struct torture_suite *suite = torture_suite_create(mem_ctx, "HIVE"); + torture_suite_add_simple_test(suite, "dir-refuses-null-location", + test_dir_refuses_null_location); tcase = torture_suite_add_tcase(suite, "dir"); torture_tcase_set_fixture(tcase, hive_setup_dir, NULL); diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 962c7fd2b5..9b1c6ff249 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -1,20 +1,20 @@ -/* +/* Unix SMB/CIFS implementation. local testing of registry library - registry backend Copyright (C) Jelmer Vernooij 2005-2007 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -32,16 +32,16 @@ * Test obtaining a predefined key. */ static bool test_get_predefined(struct torture_context *tctx, - const void *_data) + const void *_data) { - const struct registry_context *rctx = + const struct registry_context *rctx = (const struct registry_context *)_data; struct registry_key *root; WERROR error; error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root); - torture_assert_werr_ok(tctx, error, - "getting predefined key failed"); + torture_assert_werr_ok(tctx, error, + "getting predefined key failed"); return true; } @@ -49,7 +49,7 @@ static bool test_get_predefined(struct torture_context *tctx, * Test obtaining a predefined key. */ static bool test_get_predefined_unknown(struct torture_context *tctx, - const void *_data) + const void *_data) { const struct registry_context *rctx = _data; struct registry_key *root; @@ -57,40 +57,42 @@ static bool test_get_predefined_unknown(struct torture_context *tctx, error = reg_get_predefined_key(rctx, 1337, &root); torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, - "getting predefined key failed"); + "getting predefined key failed"); return true; } static bool test_predef_key_by_name(struct torture_context *tctx, - const void *_data) + const void *_data) { - const struct registry_context *rctx = + const struct registry_context *rctx = (const struct registry_context *)_data; struct registry_key *root; WERROR error; - error = reg_get_predefined_key_by_name(rctx, "HKEY_CLASSES_ROOT", &root); - torture_assert_werr_ok(tctx, error, - "getting predefined key failed"); + error = reg_get_predefined_key_by_name(rctx, "HKEY_CLASSES_ROOT", + &root); + torture_assert_werr_ok(tctx, error, + "getting predefined key failed"); - error = reg_get_predefined_key_by_name(rctx, "HKEY_classes_ROOT", &root); - torture_assert_werr_ok(tctx, error, - "getting predefined key case insensitively failed"); + error = reg_get_predefined_key_by_name(rctx, "HKEY_classes_ROOT", + &root); + torture_assert_werr_ok(tctx, error, + "getting predefined key case insensitively failed"); return true; } static bool test_predef_key_by_name_invalid(struct torture_context *tctx, - const void *_data) + const void *_data) { - const struct registry_context *rctx = + const struct registry_context *rctx = (const struct registry_context *)_data; struct registry_key *root; WERROR error; error = reg_get_predefined_key_by_name(rctx, "BLA", &root); torture_assert_werr_equal(tctx, error, WERR_BADFILE, - "getting predefined key failed"); + "getting predefined key failed"); return true; } @@ -98,18 +100,19 @@ static bool test_predef_key_by_name_invalid(struct torture_context *tctx, * Test creating a new subkey */ static bool test_create_subkey(struct torture_context *tctx, - const void *_data) + const void *_data) { - const struct registry_context *rctx = + const struct registry_context *rctx = (const struct registry_context *)_data; struct registry_key *root, *newkey; WERROR error; error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root); - torture_assert_werr_ok(tctx, error, - "getting predefined key failed"); + torture_assert_werr_ok(tctx, error, + "getting predefined key failed"); - error = reg_key_add_name(rctx, root, "Bad Bentheim", NULL, NULL, &newkey); + error = reg_key_add_name(rctx, root, "Bad Bentheim", NULL, NULL, + &newkey); torture_assert_werr_ok(tctx, error, "Creating key return code"); torture_assert(tctx, newkey != NULL, "Creating new key"); @@ -120,24 +123,24 @@ static bool test_create_subkey(struct torture_context *tctx, * Test creating a new nested subkey */ static bool test_create_nested_subkey(struct torture_context *tctx, - const void *_data) + const void *_data) { - const struct registry_context *rctx = + const struct registry_context *rctx = (const struct registry_context *)_data; struct registry_key *root, *newkey1, *newkey2; WERROR error; error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root); - torture_assert_werr_ok(tctx, error, - "getting predefined key failed"); + torture_assert_werr_ok(tctx, error, + "getting predefined key failed"); - error = reg_key_add_name(rctx, root, "Hamburg", NULL, NULL, - &newkey1); + error = reg_key_add_name(rctx, root, "Hamburg", NULL, NULL, + &newkey1); torture_assert_werr_ok(tctx, error, "Creating key return code"); torture_assert(tctx, newkey1 != NULL, "Creating new key"); - error = reg_key_add_name(rctx, root, "Hamburg\\Hamburg", NULL, NULL, - &newkey2); + error = reg_key_add_name(rctx, root, "Hamburg\\Hamburg", NULL, NULL, + &newkey2); torture_assert_werr_ok(tctx, error, "Creating key return code"); torture_assert(tctx, newkey2 != NULL, "Creating new key"); @@ -148,15 +151,17 @@ static bool test_create_nested_subkey(struct torture_context *tctx, * Test creating a new subkey */ static bool test_key_add_abs_top(struct torture_context *tctx, - const void *_data) + const void *_data) { - const struct registry_context *rctx = + const struct registry_context *rctx = (const struct registry_context *)_data; struct registry_key *root; WERROR error; - error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT", 0, NULL, &root); - torture_assert_werr_equal(tctx, error, WERR_ALREADY_EXISTS, "create top level"); + error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT", 0, NULL, + &root); + torture_assert_werr_equal(tctx, error, WERR_ALREADY_EXISTS, + "create top level"); return true; } @@ -165,22 +170,24 @@ static bool test_key_add_abs_top(struct torture_context *tctx, * Test creating a new subkey */ static bool test_key_add_abs(struct torture_context *tctx, - const void *_data) + const void *_data) { WERROR error; - const struct registry_context *rctx = + const struct registry_context *rctx = (const struct registry_context *)_data; struct registry_key *root, *result1, *result2; - error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT\\bloe", 0, NULL, &result1); + error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT\\bloe", 0, NULL, + &result1); torture_assert_werr_ok(tctx, error, "create lowest"); - error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT\\bloe\\bla", 0, NULL, &result1); + error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT\\bloe\\bla", 0, + NULL, &result1); torture_assert_werr_ok(tctx, error, "create nested"); error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root); - torture_assert_werr_ok(tctx, error, - "getting predefined key failed"); + torture_assert_werr_ok(tctx, error, + "getting predefined key failed"); error = reg_open_key(tctx, root, "bloe", &result2); torture_assert_werr_ok(tctx, error, "opening key"); @@ -194,14 +201,14 @@ static bool test_key_add_abs(struct torture_context *tctx, static bool test_del_key(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = + const struct registry_context *rctx = (const struct registry_context *)_data; struct registry_key *root, *newkey; WERROR error; error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root); - torture_assert_werr_ok(tctx, error, - "getting predefined key failed"); + torture_assert_werr_ok(tctx, error, + "getting predefined key failed"); error = reg_key_add_name(rctx, root, "Hamburg", NULL, NULL, &newkey); @@ -212,27 +219,27 @@ static bool test_del_key(struct torture_context *tctx, const void *_data) torture_assert_werr_ok(tctx, error, "Delete key"); error = reg_key_del(root, "Hamburg"); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, - "Delete missing key"); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + "Delete missing key"); return true; } /** - * Convenience function for opening the HKEY_CLASSES_ROOT hive and + * Convenience function for opening the HKEY_CLASSES_ROOT hive and * creating a single key for testing purposes. */ -static bool create_test_key(struct torture_context *tctx, - const struct registry_context *rctx, - const char *name, - struct registry_key **root, - struct registry_key **subkey) +static bool create_test_key(struct torture_context *tctx, + const struct registry_context *rctx, + const char *name, + struct registry_key **root, + struct registry_key **subkey) { WERROR error; error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, root); - torture_assert_werr_ok(tctx, error, - "getting predefined key failed"); + torture_assert_werr_ok(tctx, error, + "getting predefined key failed"); error = reg_key_add_name(rctx, *root, name, NULL, NULL, subkey); torture_assert_werr_ok(tctx, error, "Creating key return code"); @@ -243,7 +250,7 @@ static bool create_test_key(struct torture_context *tctx, static bool test_flush_key(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = + const struct registry_context *rctx = (const struct registry_context *)_data; struct registry_key *root, *subkey; WERROR error; @@ -254,15 +261,15 @@ static bool test_flush_key(struct torture_context *tctx, const void *_data) error = reg_key_flush(subkey); torture_assert_werr_ok(tctx, error, "flush key"); - torture_assert_werr_equal(tctx, reg_key_flush(NULL), - WERR_INVALID_PARAM, "flush key"); + torture_assert_werr_equal(tctx, reg_key_flush(NULL), + WERR_INVALID_PARAM, "flush key"); return true; } static bool test_query_key(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = + const struct registry_context *rctx = (const struct registry_context *)_data; struct registry_key *root, *subkey; WERROR error; @@ -274,8 +281,8 @@ static bool test_query_key(struct torture_context *tctx, const void *_data) return false; error = reg_key_get_info(tctx, subkey, &classname, - &num_subkeys, &num_values, - &last_changed_time); + &num_subkeys, &num_values, + &last_changed_time); torture_assert_werr_ok(tctx, error, "get info key"); torture_assert(tctx, classname == NULL, "classname"); @@ -287,7 +294,7 @@ static bool test_query_key(struct torture_context *tctx, const void *_data) static bool test_query_key_nums(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = + const struct registry_context *rctx = (const struct registry_context *)_data; struct registry_key *root, *subkey1, *subkey2; WERROR error; @@ -297,15 +304,16 @@ static bool test_query_key_nums(struct torture_context *tctx, const void *_data) if (!create_test_key(tctx, rctx, "Berlin", &root, &subkey1)) return false; - error = reg_key_add_name(rctx, subkey1, "Bentheim", NULL, NULL, &subkey2); + error = reg_key_add_name(rctx, subkey1, "Bentheim", NULL, NULL, + &subkey2); torture_assert_werr_ok(tctx, error, "Creating key return code"); - error = reg_val_set(subkey1, "Answer", REG_DWORD, - data_blob_talloc(tctx, &data, sizeof(data))); + error = reg_val_set(subkey1, "Answer", REG_DWORD, + data_blob_talloc(tctx, &data, sizeof(data))); torture_assert_werr_ok(tctx, error, "set value"); error = reg_key_get_info(tctx, subkey1, NULL, &num_subkeys, - &num_values, NULL); + &num_values, NULL); torture_assert_werr_ok(tctx, error, "get info key"); torture_assert_int_equal(tctx, num_subkeys, 1, "num subkeys"); @@ -315,13 +323,13 @@ static bool test_query_key_nums(struct torture_context *tctx, const void *_data) } /** - * Test that the subkeys of a key can be enumerated, that - * the returned parameters for get_subkey_by_index are optional and + * Test that the subkeys of a key can be enumerated, that + * the returned parameters for get_subkey_by_index are optional and * that enumerating the parents of a non-top-level node works. */ static bool test_list_subkeys(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = + const struct registry_context *rctx = (const struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; @@ -331,8 +339,8 @@ static bool test_list_subkeys(struct torture_context *tctx, const void *_data) if (!create_test_key(tctx, rctx, "Goettingen", &root, &subkey)) return false; - error = reg_key_get_subkey_by_index(tctx, root, 0, &name, &classname, - &last_mod_time); + error = reg_key_get_subkey_by_index(tctx, root, 0, &name, &classname, + &last_mod_time); torture_assert_werr_ok(tctx, error, "Enum keys return code"); torture_assert_str_equal(tctx, name, "Goettingen", "Enum keys data"); @@ -340,17 +348,18 @@ static bool test_list_subkeys(struct torture_context *tctx, const void *_data) error = reg_key_get_subkey_by_index(tctx, root, 0, NULL, NULL, NULL); - torture_assert_werr_ok(tctx, error, "Enum keys with NULL arguments return code"); + torture_assert_werr_ok(tctx, error, + "Enum keys with NULL arguments return code"); error = reg_key_get_subkey_by_index(tctx, root, 1, NULL, NULL, NULL); - - torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS, - "Invalid error for no more items"); + + torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS, + "Invalid error for no more items"); error = reg_key_get_subkey_by_index(tctx, subkey, 0, NULL, NULL, NULL); - - torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS, - "Invalid error for no more items"); + + torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS, + "Invalid error for no more items"); return true; } @@ -360,7 +369,7 @@ static bool test_list_subkeys(struct torture_context *tctx, const void *_data) */ static bool test_set_value(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = + const struct registry_context *rctx = (const struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; @@ -369,8 +378,8 @@ static bool test_set_value(struct torture_context *tctx, const void *_data) if (!create_test_key(tctx, rctx, "Dusseldorf", &root, &subkey)) return false; - error = reg_val_set(subkey, "Answer", REG_DWORD, - data_blob_talloc(tctx, &data, sizeof(data))); + error = reg_val_set(subkey, "Answer", REG_DWORD, + data_blob_talloc(tctx, &data, sizeof(data))); torture_assert_werr_ok (tctx, error, "setting value"); return true; @@ -381,7 +390,7 @@ static bool test_set_value(struct torture_context *tctx, const void *_data) */ static bool test_security(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = + const struct registry_context *rctx = (const struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; @@ -391,12 +400,12 @@ static bool test_security(struct torture_context *tctx, const void *_data) return false; osd = security_descriptor_create(tctx, - NULL, NULL, - SID_NT_AUTHENTICATED_USERS, - SEC_ACE_TYPE_ACCESS_ALLOWED, - SEC_GENERIC_ALL, - SEC_ACE_FLAG_OBJECT_INHERIT, - NULL); + NULL, NULL, + SID_NT_AUTHENTICATED_USERS, + SEC_ACE_TYPE_ACCESS_ALLOWED, + SEC_GENERIC_ALL, + SEC_ACE_FLAG_OBJECT_INHERIT, + NULL); error = reg_set_security(subkey, osd); torture_assert_werr_ok(tctx, error, "setting security"); @@ -404,8 +413,8 @@ static bool test_security(struct torture_context *tctx, const void *_data) error = reg_get_security(tctx, subkey, &nsd); torture_assert_werr_ok (tctx, error, "setting security"); - torture_assert(tctx, security_descriptor_equal(osd, nsd), - "security descriptor changed!"); + torture_assert(tctx, security_descriptor_equal(osd, nsd), + "security descriptor changed!"); return true; } @@ -415,7 +424,7 @@ static bool test_security(struct torture_context *tctx, const void *_data) */ static bool test_get_value(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = + const struct registry_context *rctx = (const struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; @@ -426,21 +435,22 @@ static bool test_get_value(struct torture_context *tctx, const void *_data) if (!create_test_key(tctx, rctx, "Duisburg", &root, &subkey)) return false; - error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, - &data); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, - "getting missing value"); + error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, + &data); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + "getting missing value"); - error = reg_val_set(subkey, __FUNCTION__, REG_DWORD, - data_blob_talloc(tctx, &value, 4)); - torture_assert_werr_ok (tctx, error, "setting value"); + error = reg_val_set(subkey, __FUNCTION__, REG_DWORD, + data_blob_talloc(tctx, &value, 4)); + torture_assert_werr_ok(tctx, error, "setting value"); - error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, - &data); + error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, + &data); torture_assert_werr_ok(tctx, error, "getting value"); torture_assert_int_equal(tctx, 4, data.length, "value length ok"); - torture_assert(tctx, memcmp(data.data, &value, 4) == 0, "value content ok"); + torture_assert(tctx, memcmp(data.data, &value, 4) == 0, + "value content ok"); torture_assert_int_equal(tctx, REG_DWORD, type, "value type"); return true; @@ -451,7 +461,7 @@ static bool test_get_value(struct torture_context *tctx, const void *_data) */ static bool test_del_value(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = + const struct registry_context *rctx = (const struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; @@ -462,21 +472,22 @@ static bool test_del_value(struct torture_context *tctx, const void *_data) if (!create_test_key(tctx, rctx, "Duisburg", &root, &subkey)) return false; - error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, - &data); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, - "getting missing value"); + error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, + &data); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + "getting missing value"); - error = reg_val_set(subkey, __FUNCTION__, REG_DWORD, - data_blob_talloc(tctx, &value, 4)); + error = reg_val_set(subkey, __FUNCTION__, REG_DWORD, + data_blob_talloc(tctx, &value, 4)); torture_assert_werr_ok (tctx, error, "setting value"); error = reg_del_value(subkey, __FUNCTION__); torture_assert_werr_ok (tctx, error, "unsetting value"); - error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, &data); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, - "getting missing value"); + error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, + &type, &data); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + "getting missing value"); return true; } @@ -486,7 +497,7 @@ static bool test_del_value(struct torture_context *tctx, const void *_data) */ static bool test_list_values(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = + const struct registry_context *rctx = (const struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; @@ -498,21 +509,24 @@ static bool test_list_values(struct torture_context *tctx, const void *_data) if (!create_test_key(tctx, rctx, "Bonn", &root, &subkey)) return false; - error = reg_val_set(subkey, "bar", REG_DWORD, - data_blob_talloc(tctx, &value, 4)); + error = reg_val_set(subkey, "bar", REG_DWORD, + data_blob_talloc(tctx, &value, 4)); torture_assert_werr_ok (tctx, error, "setting value"); - error = reg_key_get_value_by_index(tctx, subkey, 0, &name, &type, &data); + error = reg_key_get_value_by_index(tctx, subkey, 0, &name, + &type, &data); torture_assert_werr_ok(tctx, error, "getting value"); torture_assert_str_equal(tctx, name, "bar", "value name"); torture_assert_int_equal(tctx, 4, data.length, "value length"); - torture_assert(tctx, memcmp(data.data, &value, 4) == 0, "value content"); + torture_assert(tctx, memcmp(data.data, &value, 4) == 0, + "value content"); torture_assert_int_equal(tctx, REG_DWORD, type, "value type"); - error = reg_key_get_value_by_index(tctx, subkey, 1, &name, &type, &data); - torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS, - "getting missing value"); + error = reg_key_get_value_by_index(tctx, subkey, 1, &name, + &type, &data); + torture_assert_werr_equal(tctx, error, WERR_NO_MORE_ITEMS, + "getting missing value"); return true; } @@ -546,33 +560,49 @@ static bool setup_local_registry(struct torture_context *tctx, void **data) static void tcase_add_tests(struct torture_tcase *tcase) { - torture_tcase_add_simple_test(tcase, "list_subkeys", test_list_subkeys); - torture_tcase_add_simple_test(tcase, "get_predefined_key", test_get_predefined); - torture_tcase_add_simple_test(tcase, "get_predefined_key", test_get_predefined_unknown); - torture_tcase_add_simple_test(tcase, "create_key", test_create_subkey); - torture_tcase_add_simple_test(tcase, "create_key", test_create_nested_subkey); - torture_tcase_add_simple_test(tcase, "key_add_abs", test_key_add_abs); - torture_tcase_add_simple_test(tcase, "key_add_abs_top", test_key_add_abs_top); - torture_tcase_add_simple_test(tcase, "set_value", test_set_value); - torture_tcase_add_simple_test(tcase, "get_value", test_get_value); - torture_tcase_add_simple_test(tcase, "list_values", test_list_values); - torture_tcase_add_simple_test(tcase, "del_key", test_del_key); - torture_tcase_add_simple_test(tcase, "del_value", test_del_value); - torture_tcase_add_simple_test(tcase, "flush_key", test_flush_key); - torture_tcase_add_simple_test(tcase, "query_key", test_query_key); - torture_tcase_add_simple_test(tcase, "query_key_nums", test_query_key_nums); - torture_tcase_add_simple_test(tcase, "test_predef_key_by_name", + torture_tcase_add_simple_test(tcase, "list_subkeys", + test_list_subkeys); + torture_tcase_add_simple_test(tcase, "get_predefined_key", + test_get_predefined); + torture_tcase_add_simple_test(tcase, "get_predefined_key", + test_get_predefined_unknown); + torture_tcase_add_simple_test(tcase, "create_key", + test_create_subkey); + torture_tcase_add_simple_test(tcase, "create_key", + test_create_nested_subkey); + torture_tcase_add_simple_test(tcase, "key_add_abs", + test_key_add_abs); + torture_tcase_add_simple_test(tcase, "key_add_abs_top", + test_key_add_abs_top); + torture_tcase_add_simple_test(tcase, "set_value", + test_set_value); + torture_tcase_add_simple_test(tcase, "get_value", + test_get_value); + torture_tcase_add_simple_test(tcase, "list_values", + test_list_values); + torture_tcase_add_simple_test(tcase, "del_key", + test_del_key); + torture_tcase_add_simple_test(tcase, "del_value", + test_del_value); + torture_tcase_add_simple_test(tcase, "flush_key", + test_flush_key); + torture_tcase_add_simple_test(tcase, "query_key", + test_query_key); + torture_tcase_add_simple_test(tcase, "query_key_nums", + test_query_key_nums); + torture_tcase_add_simple_test(tcase, "test_predef_key_by_name", test_predef_key_by_name); - torture_tcase_add_simple_test(tcase, "security", test_security); - torture_tcase_add_simple_test(tcase, "test_predef_key_by_name_invalid", + torture_tcase_add_simple_test(tcase, "security", + test_security); + torture_tcase_add_simple_test(tcase, "test_predef_key_by_name_invalid", test_predef_key_by_name_invalid); } -struct torture_suite *torture_registry_registry(TALLOC_CTX *mem_ctx) +struct torture_suite *torture_registry_registry(TALLOC_CTX *mem_ctx) { struct torture_tcase *tcase; struct torture_suite *suite = torture_suite_create(mem_ctx, "REGISTRY"); - + tcase = torture_suite_add_tcase(suite, "local"); torture_tcase_set_fixture(tcase, setup_local_registry, NULL); tcase_add_tests(tcase); -- cgit From a6c4b9d1793c7ea1965a23e1d23b73012acd151b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 10 Oct 2007 13:12:53 +0200 Subject: r25607: Allow to set security descriptor type flags at creation time with security_descriptor_create(). Guenther (This used to be commit 7dd0d28d254f78891b0807492baafa188b42df16) --- source4/lib/registry/tests/registry.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 9b1c6ff249..d2838e363f 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -400,6 +400,7 @@ static bool test_security(struct torture_context *tctx, const void *_data) return false; osd = security_descriptor_create(tctx, + 0, NULL, NULL, SID_NT_AUTHENTICATED_USERS, SEC_ACE_TYPE_ACCESS_ALLOWED, -- cgit From 0e3069186186ffed24269968d75c8f007900fd95 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 10 Oct 2007 14:12:25 +0200 Subject: r25613: verify the length and type before checking the value, hopefully gives more info why this fails some bigendian platforms metze (This used to be commit 1d2bc79aa5841bbdbaf003005a161bbf294c7366) --- source4/lib/registry/tests/hive.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index 9e76ce6aa1..2ddfe6f036 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -187,10 +187,9 @@ static bool test_get_value(struct torture_context *tctx, const void *test_data) error = hive_get_value(mem_ctx, subkey, "Answer", &type, &value); torture_assert_werr_ok(tctx, error, "getting value"); - torture_assert(tctx, memcmp(value.data, &data, 4) == 0, "value data"); - torture_assert_int_equal(tctx, value.length, 4, "value length"); torture_assert_int_equal(tctx, type, REG_DWORD, "value type"); + torture_assert(tctx, memcmp(value.data, &data, 4) == 0, "value data"); return true; } @@ -251,10 +250,10 @@ static bool test_list_values(struct torture_context *tctx, torture_assert_werr_ok(tctx, error, "getting value"); torture_assert_str_equal(tctx, name, "Answer", "value name"); - torture_assert(tctx, memcmp(value.data, &data, 4) == 0, "value data"); torture_assert_int_equal(tctx, value.length, 4, "value length"); torture_assert_int_equal(tctx, type, REG_DWORD, "value type"); + torture_assert(tctx, memcmp(value.data, &data, 4) == 0, "value data"); error = hive_get_value_by_index(mem_ctx, subkey, 1, &name, &type, &value); -- cgit From f2002541ced97da3658348fe9ac9e212dd50c55b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 2 Nov 2007 12:54:19 +0100 Subject: r25803: Make our security descriptor acl manipulation methods more generic so that we can add and delete ACEs for SACLs as well as for DACLs. Guenther (This used to be commit 947fff994181f0ae50ac76d09621ddd684873112) --- source4/lib/registry/tests/registry.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index d2838e363f..155e891c40 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -399,7 +399,7 @@ static bool test_security(struct torture_context *tctx, const void *_data) if (!create_test_key(tctx, rctx, "Düsseldorf", &root, &subkey)) return false; - osd = security_descriptor_create(tctx, + osd = security_descriptor_dacl_create(tctx, 0, NULL, NULL, SID_NT_AUTHENTICATED_USERS, -- cgit From 529763a9aa192a6785ba878aceeb1683c2510913 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 9 Nov 2007 19:24:51 +0100 Subject: r25920: ndr: change NTSTAUS into enum ndr_err_code (samba4 callers) lib/messaging/ lib/registry/ lib/ldb-samba/ librpc/rpc/ auth/auth_winbind.c auth/gensec/ auth/kerberos/ dsdb/repl/ dsdb/samdb/ dsdb/schema/ torture/ cluster/ctdb/ kdc/ ntvfs/ipc/ torture/rap/ ntvfs/ utils/getntacl.c ntptr/ smb_server/ libcli/wrepl/ wrepl_server/ libcli/cldap/ libcli/dgram/ libcli/ldap/ libcli/raw/ libcli/nbt/ libnet/ winbind/ rpc_server/ metze (This used to be commit 6223c7fddc972687eb577e04fc1c8e0604c35435) --- source4/lib/registry/regf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 2dd27ca33d..3ae299b3ef 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -1021,7 +1021,7 @@ static WERROR regf_set_sec_desc(struct hive_key *key, (tdr_pull_fn_t) tdr_pull_nk_block, &root); /* Push the security descriptor to a blob */ - if (NT_STATUS_IS_ERR(ndr_push_struct_blob(&data, regf, sec_desc, + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(&data, regf, sec_desc, (ndr_push_flags_fn_t)ndr_push_security_descriptor))) { DEBUG(0, ("Unable to push security descriptor\n")); return WERR_GENERAL_FAILURE; @@ -1174,7 +1174,7 @@ static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, const struct hive_key *key, data.data = sk.sec_desc; data.length = sk.rec_size; - if (NT_STATUS_IS_ERR(ndr_pull_struct_blob(&data, ctx, *sd, + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_struct_blob(&data, ctx, *sd, (ndr_pull_flags_fn_t)ndr_pull_security_descriptor))) { DEBUG(0, ("Error parsing security descriptor\n")); return WERR_GENERAL_FAILURE; -- cgit From dbc78e20169c97f2592ddb18fdf48a1c91a3f77d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 Nov 2007 23:36:53 +0100 Subject: r25928: Split up torture-local a bit. (This used to be commit c6b109040856ba0f1ae0db2787cc838ff61df767) --- source4/lib/registry/config.mk | 10 ++++++++++ source4/lib/registry/tests/generic.c | 16 ++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 670410ff6a..6e8f8917d4 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -91,3 +91,13 @@ PRIVATE_DEPENDENCIES = \ MANPAGE = man/regtree.1 # End BINARY regtree ################################################ + +[MODULE::TORTURE_REGISTRY] +SUBSYSTEM = torture +INIT_FUNCTION = torture_registry_init +PRIVATE_DEPENDENCIES = registry +OBJ_FILES = \ + tests/generic.o \ + tests/hive.o \ + tests/diff.o \ + tests/registry.o diff --git a/source4/lib/registry/tests/generic.c b/source4/lib/registry/tests/generic.c index 1b680f20b7..69146186dc 100644 --- a/source4/lib/registry/tests/generic.c +++ b/source4/lib/registry/tests/generic.c @@ -112,11 +112,9 @@ static bool test_reg_val_description_nullname(struct torture_context *ctx) return true; } - - -struct torture_suite *torture_registry(TALLOC_CTX *mem_ctx) +_PUBLIC_ NTSTATUS torture_registry_init(void) { - struct torture_suite *suite = torture_suite_create(mem_ctx, "REGISTRY"); + struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "REGISTRY"); torture_suite_add_simple_test(suite, "str_regtype", test_str_regtype); torture_suite_add_simple_test(suite, "reg_val_data_string dword", @@ -132,9 +130,11 @@ struct torture_suite *torture_registry(TALLOC_CTX *mem_ctx) torture_suite_add_simple_test(suite, "reg_val_description null", test_reg_val_description_nullname); - torture_suite_add_suite(suite, torture_registry_hive(mem_ctx)); - torture_suite_add_suite(suite, torture_registry_registry(mem_ctx)); - torture_suite_add_suite(suite, torture_registry_diff(mem_ctx)); + torture_suite_add_suite(suite, torture_registry_hive(suite)); + torture_suite_add_suite(suite, torture_registry_registry(suite)); + torture_suite_add_suite(suite, torture_registry_diff(suite)); - return suite; + torture_register_suite(suite); + + return NT_STATUS_OK; } -- cgit From 0b2780a6a424eea9989443d288435b248d653763 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 Nov 2007 23:37:01 +0100 Subject: r25930: fix test name (This used to be commit 41dcd8c261aecaccee21667367bb524c13d620d9) --- source4/lib/registry/tests/generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/generic.c b/source4/lib/registry/tests/generic.c index 69146186dc..68040ea98e 100644 --- a/source4/lib/registry/tests/generic.c +++ b/source4/lib/registry/tests/generic.c @@ -114,7 +114,7 @@ static bool test_reg_val_description_nullname(struct torture_context *ctx) _PUBLIC_ NTSTATUS torture_registry_init(void) { - struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "REGISTRY"); + struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "LOCAL-REGISTRY"); torture_suite_add_simple_test(suite, "str_regtype", test_str_regtype); torture_suite_add_simple_test(suite, "reg_val_data_string dword", -- cgit From d0d0a69d0b2fafafa1ab340c8a352406b07329ef Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 12 Nov 2007 17:22:12 +0100 Subject: r25932: Remove unnecessary include - should fix the build on hosts without popt. (This used to be commit f250ae0c361aef864f25dfc7599ce1e7a4e29cf8) --- source4/lib/registry/tests/diff.c | 1 - source4/lib/registry/tests/generic.c | 1 - source4/lib/registry/tests/hive.c | 1 - source4/lib/registry/tests/registry.c | 1 - 4 files changed, 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/diff.c b/source4/lib/registry/tests/diff.c index 8e6907382c..690f71fcf7 100644 --- a/source4/lib/registry/tests/diff.c +++ b/source4/lib/registry/tests/diff.c @@ -21,7 +21,6 @@ #include "includes.h" #include "lib/registry/registry.h" -#include "lib/cmdline/popt_common.h" #include "torture/torture.h" #include "librpc/gen_ndr/winreg.h" diff --git a/source4/lib/registry/tests/generic.c b/source4/lib/registry/tests/generic.c index 68040ea98e..d18d300423 100644 --- a/source4/lib/registry/tests/generic.c +++ b/source4/lib/registry/tests/generic.c @@ -21,7 +21,6 @@ #include "includes.h" #include "lib/registry/registry.h" -#include "lib/cmdline/popt_common.h" #include "torture/torture.h" #include "librpc/gen_ndr/winreg.h" diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index 2ddfe6f036..2a0f04eb54 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -22,7 +22,6 @@ #include "includes.h" #include "lib/registry/registry.h" -#include "lib/cmdline/popt_common.h" #include "torture/torture.h" #include "librpc/gen_ndr/winreg.h" #include "system/filesys.h" diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 155e891c40..f0035071f2 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -22,7 +22,6 @@ #include "includes.h" #include "lib/registry/registry.h" -#include "lib/cmdline/popt_common.h" #include "torture/torture.h" #include "librpc/gen_ndr/winreg.h" #include "libcli/security/security.h" -- cgit From 81ad27b3096af61f792dc9bd8983a86161f0f30b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 13 Nov 2007 04:57:09 +0100 Subject: r25935: Fix registry tests. (This used to be commit b311094714b4d51ea7ea756df1aecba169dc0d45) --- source4/lib/registry/config.mk | 5 ++--- source4/lib/registry/tests/generic.c | 8 +++----- 2 files changed, 5 insertions(+), 8 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 6e8f8917d4..58ee6deb51 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -92,10 +92,9 @@ MANPAGE = man/regtree.1 # End BINARY regtree ################################################ -[MODULE::TORTURE_REGISTRY] -SUBSYSTEM = torture -INIT_FUNCTION = torture_registry_init +[SUBSYSTEM::torture_registry] PRIVATE_DEPENDENCIES = registry +PRIVATE_PROTO_HEADER = tests/proto.h OBJ_FILES = \ tests/generic.o \ tests/hive.o \ diff --git a/source4/lib/registry/tests/generic.c b/source4/lib/registry/tests/generic.c index d18d300423..13e27cd80b 100644 --- a/source4/lib/registry/tests/generic.c +++ b/source4/lib/registry/tests/generic.c @@ -111,9 +111,9 @@ static bool test_reg_val_description_nullname(struct torture_context *ctx) return true; } -_PUBLIC_ NTSTATUS torture_registry_init(void) +_PUBLIC_ struct torture_suite *torture_registry(TALLOC_CTX *mem_ctx) { - struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "LOCAL-REGISTRY"); + struct torture_suite *suite = torture_suite_create(mem_ctx, "REGISTRY"); torture_suite_add_simple_test(suite, "str_regtype", test_str_regtype); torture_suite_add_simple_test(suite, "reg_val_data_string dword", @@ -133,7 +133,5 @@ _PUBLIC_ NTSTATUS torture_registry_init(void) torture_suite_add_suite(suite, torture_registry_registry(suite)); torture_suite_add_suite(suite, torture_registry_diff(suite)); - torture_register_suite(suite); - - return NT_STATUS_OK; + return suite; } -- cgit From ca0b72a1fdb7bd965065e833df34662afef0423e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 16 Nov 2007 20:12:00 +0100 Subject: r26003: Split up DB_WRAP, as first step in an attempt to sanitize dependencies. (This used to be commit 56dfcb4f2f8e74c9d8b2fe3a0df043781188a555) --- source4/lib/registry/ldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 4a6ef65bc4..fdd4c27599 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -21,7 +21,7 @@ #include "registry.h" #include "lib/ldb/include/ldb.h" #include "lib/ldb/include/ldb_errors.h" -#include "db_wrap.h" +#include "ldb_wrap.h" #include "librpc/gen_ndr/winreg.h" #include "param/param.h" -- cgit From 75c7fd4030a7c2ec5eeb752ccbc0f5fde74d1029 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 Nov 2007 12:31:26 +0100 Subject: r26073: Import Python bindings for the registry. (This used to be commit 777205b5705940c00384172c531ea99ba3eae235) --- source4/lib/registry/config.mk | 7 +- source4/lib/registry/registry.i | 150 +++++++++++++++++++++++++++++++++ source4/lib/registry/tests/bindings.py | 34 ++++++++ 3 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 source4/lib/registry/registry.i create mode 100644 source4/lib/registry/tests/bindings.py (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 58ee6deb51..b289ff9afd 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -35,7 +35,7 @@ OBJ_FILES = \ rpc.o PUBLIC_DEPENDENCIES = \ LIBSAMBA-UTIL CHARSET TDR_REGF LIBLDB \ - RPC_NDR_WINREG + RPC_NDR_WINREG LDB_WRAP PUBLIC_HEADERS = registry.h hive.h patchfile.h # End MODULE registry_ldb ################################################ @@ -100,3 +100,8 @@ OBJ_FILES = \ tests/hive.o \ tests/diff.o \ tests/registry.o + +[PYTHON::swig_registry] +PUBLIC_DEPENDENCIES = registry LIBPYTHON +SWIG_FILE = registry.i + diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i new file mode 100644 index 0000000000..7e33f43a14 --- /dev/null +++ b/source4/lib/registry/registry.i @@ -0,0 +1,150 @@ +/* + Unix SMB/CIFS implementation. + Copyright (C) Jelmer Vernooij 2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +%module registry + +%{ +/* Include headers */ +#include +#include + +#include "includes.h" +#include "registry.h" + +typedef struct registry_context reg; +typedef struct hive_key hive; +%} + +/* FIXME: This should be in another file */ +%typemap(default) struct auth_session_info * { + $1 = NULL; +} + +%import "stdint.i" +%import "../../lib/talloc/talloc.i" +%import "../../auth/credentials/credentials.i" +%import "../../libcli/util/errors.i" + +/* Utility functions */ + +const char *reg_get_predef_name(uint32_t hkey); +const char *str_regtype(int type); + +/* Registry contexts */ +%typemap(in,numinputs=0) struct registry_context ** (struct registry_context *tmp) { + $1 = &tmp; +} + +%typemap(argout) struct registry_context ** { + $result = SWIG_NewPointerObj(*$1, SWIGTYPE_p_registry_context, 0); +} + +%rename(Registry) reg_open_local; +WERROR reg_open_local(TALLOC_CTX *parent_ctx, struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials); + +%typemap(in) const char ** { + /* Check if is a list */ + if (PyList_Check($input)) { + int size = PyList_Size($input); + int i = 0; + $1 = (char **) malloc((size+1)*sizeof(const char *)); + for (i = 0; i < size; i++) { + PyObject *o = PyList_GetItem($input,i); + if (PyString_Check(o)) + $1[i] = PyString_AsString(PyList_GetItem($input,i)); + else { + PyErr_SetString(PyExc_TypeError,"list must contain strings"); + free($1); + return NULL; + } + } + $1[i] = 0; + } else { + PyErr_SetString(PyExc_TypeError,"not a list"); + return NULL; + } +} + +%typemap(freearg) const char ** { + free((char **) $1); +} + +typedef struct registry_context { + %extend { + + ~reg() { talloc_free($self); } + WERROR get_predefined_key_by_name(const char *name, + struct registry_key **key); + + WERROR get_predefined_key(uint32_t hkey_id, struct registry_key **key); + WERROR apply_patchfile(const char *filename) + { + return reg_diff_apply(filename, $self); + } + + WERROR mount_hive(struct hive_key *hive_key, uint32_t hkey_id, + const char **elements=NULL); + } + + %pythoncode { + def mount(self, path, hkey_id, elements=[]): + self.mount_hive(Hive(path), hkey_id, elements) + } +} reg; + +/* Hives */ +%typemap(in,numinputs=0) struct hive_key ** (struct hive_key *tmp) { + $1 = &tmp; +} + +%typemap(argout) struct hive_key ** { + Py_XDECREF($result); + $result = SWIG_NewPointerObj(*$1, SWIGTYPE_p_hive_key, 0); +} + +%rename(Hive) reg_open_hive; +WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + struct hive_key **root); + +typedef struct hive_key { + %extend { + ~hive() { talloc_free($self); } + } +} hive; + +%rename(open_samba) reg_open_samba; + +WERROR reg_open_samba(TALLOC_CTX *mem_ctx, + struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials); + +/* Constants */ +%constant uint32_t HKEY_CLASSES_ROOT = HKEY_CLASSES_ROOT; +%constant uint32_t HKEY_CURRENT_USER = HKEY_CURRENT_USER; +%constant uint32_t HKEY_LOCAL_MACHINE = HKEY_LOCAL_MACHINE; +%constant uint32_t HKEY_USERS = HKEY_USERS; +%constant uint32_t HKEY_PERFORMANCE_DATA = HKEY_PERFORMANCE_DATA; +%constant uint32_t HKEY_CURRENT_CONFIG = HKEY_CURRENT_CONFIG; +%constant uint32_t HKEY_DYN_DATA = HKEY_DYN_DATA; +%constant uint32_t HKEY_PERFORMANCE_TEXT = HKEY_PERFORMANCE_TEXT; +%constant uint32_t HKEY_PERFORMANCE_NLSTEXT = HKEY_PERFORMANCE_NLSTEXT; diff --git a/source4/lib/registry/tests/bindings.py b/source4/lib/registry/tests/bindings.py new file mode 100644 index 0000000000..be87efe594 --- /dev/null +++ b/source4/lib/registry/tests/bindings.py @@ -0,0 +1,34 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 2007 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import unittest +import registry + +class HelperTests(unittest.TestCase): + def test_predef_to_name(self): + self.assertEquals("HKEY_LOCAL_MACHINE", + registry.reg_get_predef_name(0x80000002)) + + def test_str_regtype(self): + self.assertEquals("REG_DWORD", registry.str_regtype(4)) + + +class RegistryTests(unittest.TestCase): + def test_new(self): + self.registry = registry.Registry() -- cgit From 6c999cd12344f2bb8b1d2941210b4c205b3e0aad Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 2 Dec 2007 22:32:11 +0100 Subject: r26236: Remove more uses of global_loadparm or specify loadparm_context explicitly. (This used to be commit 5b29ef7c03d9ae76b0ca909e9f03a58e1bad3521) --- source4/lib/registry/registry.h | 2 ++ source4/lib/registry/registry.i | 1 + source4/lib/registry/samba.c | 12 +++++++----- source4/lib/registry/tools/common.c | 4 ++-- source4/lib/registry/tools/regdiff.c | 8 +++++--- source4/lib/registry/tools/regpatch.c | 3 ++- source4/lib/registry/tools/regshell.c | 3 ++- source4/lib/registry/tools/regtree.c | 3 ++- 8 files changed, 23 insertions(+), 13 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index c1159dde2e..c53e3dfbe5 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -164,6 +164,7 @@ struct registry_context { struct auth_session_info; struct event_context; +struct loadparm_context; /** * Open the locally defined registry. @@ -175,6 +176,7 @@ WERROR reg_open_local(TALLOC_CTX *mem_ctx, WERROR reg_open_samba(TALLOC_CTX *mem_ctx, struct registry_context **ctx, + struct loadparm_context *lp_ctx, struct auth_session_info *session_info, struct cli_credentials *credentials); diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i index 7e33f43a14..330f0856e1 100644 --- a/source4/lib/registry/registry.i +++ b/source4/lib/registry/registry.i @@ -135,6 +135,7 @@ typedef struct hive_key { WERROR reg_open_samba(TALLOC_CTX *mem_ctx, struct registry_context **ctx, + struct loadparm_context *lp_ctx, struct auth_session_info *session_info, struct cli_credentials *credentials); diff --git a/source4/lib/registry/samba.c b/source4/lib/registry/samba.c index 2397432f0b..a5a60ba610 100644 --- a/source4/lib/registry/samba.c +++ b/source4/lib/registry/samba.c @@ -26,6 +26,7 @@ */ static WERROR mount_samba_hive(struct registry_context *ctx, + struct loadparm_context *lp_ctx, struct auth_session_info *auth_info, struct cli_credentials *creds, const char *name, @@ -36,7 +37,7 @@ static WERROR mount_samba_hive(struct registry_context *ctx, const char *location; location = talloc_asprintf(ctx, "%s/%s.ldb", - lp_private_dir(global_loadparm), + lp_private_dir(lp_ctx), name); error = reg_open_hive(ctx, location, auth_info, creds, &hive); @@ -54,6 +55,7 @@ static WERROR mount_samba_hive(struct registry_context *ctx, _PUBLIC_ WERROR reg_open_samba(TALLOC_CTX *mem_ctx, struct registry_context **ctx, + struct loadparm_context *lp_ctx, struct auth_session_info *session_info, struct cli_credentials *credentials) { @@ -64,18 +66,18 @@ _PUBLIC_ WERROR reg_open_samba(TALLOC_CTX *mem_ctx, return result; } - mount_samba_hive(*ctx, session_info, credentials, + mount_samba_hive(*ctx, lp_ctx, session_info, credentials, "hklm", HKEY_LOCAL_MACHINE); - mount_samba_hive(*ctx, session_info, credentials, + mount_samba_hive(*ctx, lp_ctx, session_info, credentials, "hkcr", HKEY_CLASSES_ROOT); /* FIXME: Should be mounted from NTUSER.DAT in the home directory of the * current user */ - mount_samba_hive(*ctx, session_info, credentials, + mount_samba_hive(*ctx, lp_ctx, session_info, credentials, "hkcu", HKEY_CURRENT_USER); - mount_samba_hive(*ctx, session_info, credentials, + mount_samba_hive(*ctx, lp_ctx, session_info, credentials, "hku", HKEY_USERS); /* FIXME: Different hive backend for HKEY_CLASSES_ROOT: merged view of HKEY_LOCAL_MACHINE\Software\Classes diff --git a/source4/lib/registry/tools/common.c b/source4/lib/registry/tools/common.c index 0233f27437..6d766fd25c 100644 --- a/source4/lib/registry/tools/common.c +++ b/source4/lib/registry/tools/common.c @@ -65,12 +65,12 @@ struct registry_key *reg_common_open_file(const char *path, return reg_import_hive_key(h, hive_root, -1, NULL); } -struct registry_context *reg_common_open_local(struct cli_credentials *creds) +struct registry_context *reg_common_open_local(struct cli_credentials *creds, struct loadparm_context *lp_ctx) { WERROR error; struct registry_context *h; - error = reg_open_samba(NULL, &h, NULL, creds); + error = reg_open_samba(NULL, &h, lp_ctx, NULL, creds); if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open local registry:%s \n", diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index f96761cda0..1996861a2a 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -24,10 +24,12 @@ #include "lib/events/events.h" #include "lib/cmdline/popt_common.h" #include "lib/registry/tools/common.h" +#include "param/param.h" enum reg_backend { REG_UNKNOWN, REG_LOCAL, REG_REMOTE, REG_NULL }; static struct registry_context *open_backend(poptContext pc, + struct loadparm_context *lp_ctx, enum reg_backend backend, const char *remote_host) { @@ -39,7 +41,7 @@ static struct registry_context *open_backend(poptContext pc, poptPrintUsage(pc, stderr, 0); return NULL; case REG_LOCAL: - error = reg_open_samba(NULL, &ctx, NULL, cmdline_credentials); + error = reg_open_samba(NULL, &ctx, lp_ctx, NULL, cmdline_credentials); break; case REG_REMOTE: error = reg_open_remote(&ctx, NULL, cmdline_credentials, @@ -114,11 +116,11 @@ int main(int argc, const char **argv) } - h1 = open_backend(pc, backend1, remote1); + h1 = open_backend(pc, global_loadparm, backend1, remote1); if (h1 == NULL) return 1; - h2 = open_backend(pc, backend2, remote2); + h2 = open_backend(pc, global_loadparm, backend2, remote2); if (h2 == NULL) return 1; diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 35f12c7e62..2f2cf789a9 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -24,6 +24,7 @@ #include "lib/cmdline/popt_common.h" #include "lib/registry/tools/common.h" #include "lib/registry/patchfile.h" +#include "param/param.h" int main(int argc, char **argv) { @@ -50,7 +51,7 @@ int main(int argc, char **argv) if (remote) { h = reg_common_open_remote (remote, cmdline_credentials); } else { - h = reg_common_open_local (cmdline_credentials); + h = reg_common_open_local (cmdline_credentials, global_loadparm); } if (h == NULL) diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 7dbcf2f875..9b582c3c02 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -26,6 +26,7 @@ #include "lib/smbreadline/smbreadline.h" #include "librpc/gen_ndr/ndr_security.h" #include "lib/registry/tools/common.h" +#include "param/param.h" struct regshell_context { struct registry_context *registry; @@ -505,7 +506,7 @@ int main(int argc, char **argv) ctx->registry = ctx->current->context; ctx->path = talloc_strdup(ctx, ""); } else { - ctx->registry = reg_common_open_local(cmdline_credentials); + ctx->registry = reg_common_open_local(cmdline_credentials, global_loadparm); } if (ctx->registry == NULL) diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 9f8d8c012d..f95fc1968d 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -23,6 +23,7 @@ #include "lib/registry/tools/common.h" #include "lib/events/events.h" #include "lib/cmdline/popt_common.h" +#include "param/param.h" /** * Print a registry key recursively @@ -132,7 +133,7 @@ int main(int argc, char **argv) } else if (file != NULL) { start_key = reg_common_open_file(file, cmdline_credentials); } else { - h = reg_common_open_local(cmdline_credentials); + h = reg_common_open_local(cmdline_credentials, global_loadparm); } if (h == NULL && start_key == NULL) -- cgit From 53ae9bc9f6f66578948c3995073bdc1f1acae0f1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 13:48:09 +0100 Subject: r26248: Check in SWIG output so SWIG is not required when running out of svn. (This used to be commit 08501fbef38f81ce5ff4885a1696f9cb392fd631) --- source4/lib/registry/registry.py | 104 + source4/lib/registry/registry_wrap.c | 4047 ++++++++++++++++++++++++++++++++++ 2 files changed, 4151 insertions(+) create mode 100644 source4/lib/registry/registry.py create mode 100644 source4/lib/registry/registry_wrap.c (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.py b/source4/lib/registry/registry.py new file mode 100644 index 0000000000..b61d713df8 --- /dev/null +++ b/source4/lib/registry/registry.py @@ -0,0 +1,104 @@ +# This file was automatically generated by SWIG (http://www.swig.org). +# Version 1.3.33 +# +# Don't modify this file, modify the SWIG interface instead. +# This file is compatible with both classic and new-style classes. + +import _registry +import new +new_instancemethod = new.instancemethod +try: + _swig_property = property +except NameError: + pass # Python < 2.2 doesn't have 'property'. +def _swig_setattr_nondynamic(self,class_type,name,value,static=1): + if (name == "thisown"): return self.this.own(value) + if (name == "this"): + if type(value).__name__ == 'PySwigObject': + self.__dict__[name] = value + return + method = class_type.__swig_setmethods__.get(name,None) + if method: return method(self,value) + if (not static) or hasattr(self,name): + self.__dict__[name] = value + else: + raise AttributeError("You cannot add attributes to %s" % self) + +def _swig_setattr(self,class_type,name,value): + return _swig_setattr_nondynamic(self,class_type,name,value,0) + +def _swig_getattr(self,class_type,name): + if (name == "thisown"): return self.this.own() + method = class_type.__swig_getmethods__.get(name,None) + if method: return method(self) + raise AttributeError,name + +def _swig_repr(self): + try: strthis = "proxy of " + self.this.__repr__() + except: strthis = "" + return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) + +import types +try: + _object = types.ObjectType + _newclass = 1 +except AttributeError: + class _object : pass + _newclass = 0 +del types + + +import credentials +reg_get_predef_name = _registry.reg_get_predef_name +str_regtype = _registry.str_regtype +Registry = _registry.Registry +class reg(_object): + __swig_setmethods__ = {} + __setattr__ = lambda self, name, value: _swig_setattr(self, reg, name, value) + __swig_getmethods__ = {} + __getattr__ = lambda self, name: _swig_getattr(self, reg, name) + __repr__ = _swig_repr + __swig_destroy__ = _registry.delete_reg + __del__ = lambda self : None; + def get_predefined_key_by_name(*args, **kwargs): return _registry.reg_get_predefined_key_by_name(*args, **kwargs) + def get_predefined_key(*args, **kwargs): return _registry.reg_get_predefined_key(*args, **kwargs) + def apply_patchfile(*args, **kwargs): return _registry.reg_apply_patchfile(*args, **kwargs) + def mount_hive(*args, **kwargs): return _registry.reg_mount_hive(*args, **kwargs) + def mount(self, path, hkey_id, elements=[]): + self.mount_hive(Hive(path), hkey_id, elements) + + def __init__(self, *args, **kwargs): + this = _registry.new_reg(*args, **kwargs) + try: self.this.append(this) + except: self.this = this +reg_swigregister = _registry.reg_swigregister +reg_swigregister(reg) + +Hive = _registry.Hive +class hive(_object): + __swig_setmethods__ = {} + __setattr__ = lambda self, name, value: _swig_setattr(self, hive, name, value) + __swig_getmethods__ = {} + __getattr__ = lambda self, name: _swig_getattr(self, hive, name) + __repr__ = _swig_repr + __swig_destroy__ = _registry.delete_hive + __del__ = lambda self : None; + def __init__(self, *args, **kwargs): + this = _registry.new_hive(*args, **kwargs) + try: self.this.append(this) + except: self.this = this +hive_swigregister = _registry.hive_swigregister +hive_swigregister(hive) + +open_samba = _registry.open_samba +HKEY_CLASSES_ROOT = _registry.HKEY_CLASSES_ROOT +HKEY_CURRENT_USER = _registry.HKEY_CURRENT_USER +HKEY_LOCAL_MACHINE = _registry.HKEY_LOCAL_MACHINE +HKEY_USERS = _registry.HKEY_USERS +HKEY_PERFORMANCE_DATA = _registry.HKEY_PERFORMANCE_DATA +HKEY_CURRENT_CONFIG = _registry.HKEY_CURRENT_CONFIG +HKEY_DYN_DATA = _registry.HKEY_DYN_DATA +HKEY_PERFORMANCE_TEXT = _registry.HKEY_PERFORMANCE_TEXT +HKEY_PERFORMANCE_NLSTEXT = _registry.HKEY_PERFORMANCE_NLSTEXT + + diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c new file mode 100644 index 0000000000..3ab0af10b5 --- /dev/null +++ b/source4/lib/registry/registry_wrap.c @@ -0,0 +1,4047 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.33 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +#define SWIGPYTHON +#define SWIG_PYTHON_DIRECTOR_NO_VTABLE +/* ----------------------------------------------------------------------------- + * This section contains generic SWIG labels for method/variable + * declarations/attributes, and other compiler dependent labels. + * ----------------------------------------------------------------------------- */ + +/* template workaround for compilers that cannot correctly implement the C++ standard */ +#ifndef SWIGTEMPLATEDISAMBIGUATOR +# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) +# define SWIGTEMPLATEDISAMBIGUATOR template +# elif defined(__HP_aCC) +/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ +/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ +# define SWIGTEMPLATEDISAMBIGUATOR template +# else +# define SWIGTEMPLATEDISAMBIGUATOR +# endif +#endif + +/* inline attribute */ +#ifndef SWIGINLINE +# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +# else +# define SWIGINLINE +# endif +#endif + +/* attribute recognised by some compilers to avoid 'unused' warnings */ +#ifndef SWIGUNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* exporting methods */ +#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + + + +/* Python.h has to appear first */ +#include + +/* ----------------------------------------------------------------------------- + * swigrun.swg + * + * This file contains generic CAPI SWIG runtime support for pointer + * type checking. + * ----------------------------------------------------------------------------- */ + +/* This should only be incremented when either the layout of swig_type_info changes, + or for whatever reason, the runtime changes incompatibly */ +#define SWIG_RUNTIME_VERSION "3" + +/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ +#ifdef SWIG_TYPE_TABLE +# define SWIG_QUOTE_STRING(x) #x +# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) +# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) +#else +# define SWIG_TYPE_TABLE_NAME +#endif + +/* + You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for + creating a static or dynamic library from the swig runtime code. + In 99.9% of the cases, swig just needs to declare them as 'static'. + + But only do this if is strictly necessary, ie, if you have problems + with your compiler or so. +*/ + +#ifndef SWIGRUNTIME +# define SWIGRUNTIME SWIGINTERN +#endif + +#ifndef SWIGRUNTIMEINLINE +# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE +#endif + +/* Generic buffer size */ +#ifndef SWIG_BUFFER_SIZE +# define SWIG_BUFFER_SIZE 1024 +#endif + +/* Flags for pointer conversions */ +#define SWIG_POINTER_DISOWN 0x1 + +/* Flags for new pointer objects */ +#define SWIG_POINTER_OWN 0x1 + + +/* + Flags/methods for returning states. + + The swig conversion methods, as ConvertPtr, return and integer + that tells if the conversion was successful or not. And if not, + an error code can be returned (see swigerrors.swg for the codes). + + Use the following macros/flags to set or process the returning + states. + + In old swig versions, you usually write code as: + + if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { + // success code + } else { + //fail code + } + + Now you can be more explicit as: + + int res = SWIG_ConvertPtr(obj,vptr,ty.flags); + if (SWIG_IsOK(res)) { + // success code + } else { + // fail code + } + + that seems to be the same, but now you can also do + + Type *ptr; + int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); + if (SWIG_IsOK(res)) { + // success code + if (SWIG_IsNewObj(res) { + ... + delete *ptr; + } else { + ... + } + } else { + // fail code + } + + I.e., now SWIG_ConvertPtr can return new objects and you can + identify the case and take care of the deallocation. Of course that + requires also to SWIG_ConvertPtr to return new result values, as + + int SWIG_ConvertPtr(obj, ptr,...) { + if () { + if () { + *ptr = ; + return SWIG_NEWOBJ; + } else { + *ptr = ; + return SWIG_OLDOBJ; + } + } else { + return SWIG_BADOBJ; + } + } + + Of course, returning the plain '0(success)/-1(fail)' still works, but you can be + more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the + swig errors code. + + Finally, if the SWIG_CASTRANK_MODE is enabled, the result code + allows to return the 'cast rank', for example, if you have this + + int food(double) + int fooi(int); + + and you call + + food(1) // cast rank '1' (1 -> 1.0) + fooi(1) // cast rank '0' + + just use the SWIG_AddCast()/SWIG_CheckState() + + + */ +#define SWIG_OK (0) +#define SWIG_ERROR (-1) +#define SWIG_IsOK(r) (r >= 0) +#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) + +/* The CastRankLimit says how many bits are used for the cast rank */ +#define SWIG_CASTRANKLIMIT (1 << 8) +/* The NewMask denotes the object was created (using new/malloc) */ +#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) +/* The TmpMask is for in/out typemaps that use temporal objects */ +#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) +/* Simple returning values */ +#define SWIG_BADOBJ (SWIG_ERROR) +#define SWIG_OLDOBJ (SWIG_OK) +#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) +#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) +/* Check, add and del mask methods */ +#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) +#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) +#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) +#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) +#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) +#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) + + +/* Cast-Rank Mode */ +#if defined(SWIG_CASTRANK_MODE) +# ifndef SWIG_TypeRank +# define SWIG_TypeRank unsigned long +# endif +# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ +# define SWIG_MAXCASTRANK (2) +# endif +# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) +# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) +SWIGINTERNINLINE int SWIG_AddCast(int r) { + return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; +} +SWIGINTERNINLINE int SWIG_CheckState(int r) { + return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; +} +#else /* no cast-rank mode */ +# define SWIG_AddCast +# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) +#endif + + + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *(*swig_converter_func)(void *); +typedef struct swig_type_info *(*swig_dycast_func)(void **); + +/* Structure to store inforomation on one type */ +typedef struct swig_type_info { + const char *name; /* mangled name of this type */ + const char *str; /* human readable name of this type */ + swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ + struct swig_cast_info *cast; /* linked list of types that can cast into this type */ + void *clientdata; /* language specific type data */ + int owndata; /* flag if the structure owns the clientdata */ +} swig_type_info; + +/* Structure to store a type and conversion function used for casting */ +typedef struct swig_cast_info { + swig_type_info *type; /* pointer to type that is equivalent to this type */ + swig_converter_func converter; /* function to cast the void pointers */ + struct swig_cast_info *next; /* pointer to next cast in linked list */ + struct swig_cast_info *prev; /* pointer to the previous cast */ +} swig_cast_info; + +/* Structure used to store module information + * Each module generates one structure like this, and the runtime collects + * all of these structures and stores them in a circularly linked list.*/ +typedef struct swig_module_info { + swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ + size_t size; /* Number of types in this module */ + struct swig_module_info *next; /* Pointer to next element in circularly linked list */ + swig_type_info **type_initial; /* Array of initially generated type structures */ + swig_cast_info **cast_initial; /* Array of initially generated casting structures */ + void *clientdata; /* Language specific module data */ +} swig_module_info; + +/* + Compare two type names skipping the space characters, therefore + "char*" == "char *" and "Class" == "Class", etc. + + Return 0 when the two name types are equivalent, as in + strncmp, but skipping ' '. +*/ +SWIGRUNTIME int +SWIG_TypeNameComp(const char *f1, const char *l1, + const char *f2, const char *l2) { + for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { + while ((*f1 == ' ') && (f1 != l1)) ++f1; + while ((*f2 == ' ') && (f2 != l2)) ++f2; + if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; + } + return (int)((l1 - f1) - (l2 - f2)); +} + +/* + Check type equivalence in a name list like ||... + Return 0 if not equal, 1 if equal +*/ +SWIGRUNTIME int +SWIG_TypeEquiv(const char *nb, const char *tb) { + int equiv = 0; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (!equiv && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; + if (*ne) ++ne; + } + return equiv; +} + +/* + Check type equivalence in a name list like ||... + Return 0 if equal, -1 if nb < tb, 1 if nb > tb +*/ +SWIGRUNTIME int +SWIG_TypeCompare(const char *nb, const char *tb) { + int equiv = 0; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (!equiv && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; + if (*ne) ++ne; + } + return equiv; +} + + +/* think of this as a c++ template<> or a scheme macro */ +#define SWIG_TypeCheck_Template(comparison, ty) \ + if (ty) { \ + swig_cast_info *iter = ty->cast; \ + while (iter) { \ + if (comparison) { \ + if (iter == ty->cast) return iter; \ + /* Move iter to the top of the linked list */ \ + iter->prev->next = iter->next; \ + if (iter->next) \ + iter->next->prev = iter->prev; \ + iter->next = ty->cast; \ + iter->prev = 0; \ + if (ty->cast) ty->cast->prev = iter; \ + ty->cast = iter; \ + return iter; \ + } \ + iter = iter->next; \ + } \ + } \ + return 0 + +/* + Check the typename +*/ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheck(const char *c, swig_type_info *ty) { + SWIG_TypeCheck_Template(strcmp(iter->type->name, c) == 0, ty); +} + +/* Same as previous function, except strcmp is replaced with a pointer comparison */ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { + SWIG_TypeCheck_Template(iter->type == from, into); +} + +/* + Cast a pointer up an inheritance hierarchy +*/ +SWIGRUNTIMEINLINE void * +SWIG_TypeCast(swig_cast_info *ty, void *ptr) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr); +} + +/* + Dynamic pointer casting. Down an inheritance hierarchy +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { + swig_type_info *lastty = ty; + if (!ty || !ty->dcast) return ty; + while (ty && (ty->dcast)) { + ty = (*ty->dcast)(ptr); + if (ty) lastty = ty; + } + return lastty; +} + +/* + Return the name associated with this type +*/ +SWIGRUNTIMEINLINE const char * +SWIG_TypeName(const swig_type_info *ty) { + return ty->name; +} + +/* + Return the pretty name associated with this type, + that is an unmangled type name in a form presentable to the user. +*/ +SWIGRUNTIME const char * +SWIG_TypePrettyName(const swig_type_info *type) { + /* The "str" field contains the equivalent pretty names of the + type, separated by vertical-bar characters. We choose + to print the last name, as it is often (?) the most + specific. */ + if (!type) return NULL; + if (type->str != NULL) { + const char *last_name = type->str; + const char *s; + for (s = type->str; *s; s++) + if (*s == '|') last_name = s+1; + return last_name; + } + else + return type->name; +} + +/* + Set the clientdata field for a type +*/ +SWIGRUNTIME void +SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { + swig_cast_info *cast = ti->cast; + /* if (ti->clientdata == clientdata) return; */ + ti->clientdata = clientdata; + + while (cast) { + if (!cast->converter) { + swig_type_info *tc = cast->type; + if (!tc->clientdata) { + SWIG_TypeClientData(tc, clientdata); + } + } + cast = cast->next; + } +} +SWIGRUNTIME void +SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { + SWIG_TypeClientData(ti, clientdata); + ti->owndata = 1; +} + +/* + Search for a swig_type_info structure only by mangled name + Search is a O(log #types) + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_MangledTypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + swig_module_info *iter = start; + do { + if (iter->size) { + register size_t l = 0; + register size_t r = iter->size - 1; + do { + /* since l+r >= 0, we can (>> 1) instead (/ 2) */ + register size_t i = (l + r) >> 1; + const char *iname = iter->types[i]->name; + if (iname) { + register int compare = strcmp(name, iname); + if (compare == 0) { + return iter->types[i]; + } else if (compare < 0) { + if (i) { + r = i - 1; + } else { + break; + } + } else if (compare > 0) { + l = i + 1; + } + } else { + break; /* should never happen */ + } + } while (l <= r); + } + iter = iter->next; + } while (iter != end); + return 0; +} + +/* + Search for a swig_type_info structure for either a mangled name or a human readable name. + It first searches the mangled names of the types, which is a O(log #types) + If a type is not found it then searches the human readable names, which is O(#types). + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + /* STEP 1: Search the name field using binary search */ + swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); + if (ret) { + return ret; + } else { + /* STEP 2: If the type hasn't been found, do a complete search + of the str field (the human readable name) */ + swig_module_info *iter = start; + do { + register size_t i = 0; + for (; i < iter->size; ++i) { + if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) + return iter->types[i]; + } + iter = iter->next; + } while (iter != end); + } + + /* neither found a match */ + return 0; +} + +/* + Pack binary data into a string +*/ +SWIGRUNTIME char * +SWIG_PackData(char *c, void *ptr, size_t sz) { + static const char hex[17] = "0123456789abcdef"; + register const unsigned char *u = (unsigned char *) ptr; + register const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + register unsigned char uu = *u; + *(c++) = hex[(uu & 0xf0) >> 4]; + *(c++) = hex[uu & 0xf]; + } + return c; +} + +/* + Unpack binary data from a string +*/ +SWIGRUNTIME const char * +SWIG_UnpackData(const char *c, void *ptr, size_t sz) { + register unsigned char *u = (unsigned char *) ptr; + register const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + register char d = *(c++); + register unsigned char uu; + if ((d >= '0') && (d <= '9')) + uu = ((d - '0') << 4); + else if ((d >= 'a') && (d <= 'f')) + uu = ((d - ('a'-10)) << 4); + else + return (char *) 0; + d = *(c++); + if ((d >= '0') && (d <= '9')) + uu |= (d - '0'); + else if ((d >= 'a') && (d <= 'f')) + uu |= (d - ('a'-10)); + else + return (char *) 0; + *u = uu; + } + return c; +} + +/* + Pack 'void *' into a string buffer. +*/ +SWIGRUNTIME char * +SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { + char *r = buff; + if ((2*sizeof(void *) + 2) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,&ptr,sizeof(void *)); + if (strlen(name) + 1 > (bsz - (r - buff))) return 0; + strcpy(r,name); + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + *ptr = (void *) 0; + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sizeof(void *)); +} + +SWIGRUNTIME char * +SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { + char *r = buff; + size_t lname = (name ? strlen(name) : 0); + if ((2*sz + 2 + lname) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,ptr,sz); + if (lname) { + strncpy(r,name,lname+1); + } else { + *r = 0; + } + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + memset(ptr,0,sz); + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sz); +} + +#ifdef __cplusplus +} +#endif + +/* Errors in SWIG */ +#define SWIG_UnknownError -1 +#define SWIG_IOError -2 +#define SWIG_RuntimeError -3 +#define SWIG_IndexError -4 +#define SWIG_TypeError -5 +#define SWIG_DivisionByZero -6 +#define SWIG_OverflowError -7 +#define SWIG_SyntaxError -8 +#define SWIG_ValueError -9 +#define SWIG_SystemError -10 +#define SWIG_AttributeError -11 +#define SWIG_MemoryError -12 +#define SWIG_NullReferenceError -13 + + + + +/* Add PyOS_snprintf for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 +# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) +# define PyOS_snprintf _snprintf +# else +# define PyOS_snprintf snprintf +# endif +#endif + +/* A crude PyString_FromFormat implementation for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 + +#ifndef SWIG_PYBUFFER_SIZE +# define SWIG_PYBUFFER_SIZE 1024 +#endif + +static PyObject * +PyString_FromFormat(const char *fmt, ...) { + va_list ap; + char buf[SWIG_PYBUFFER_SIZE * 2]; + int res; + va_start(ap, fmt); + res = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf); +} +#endif + +/* Add PyObject_Del for old Pythons */ +#if PY_VERSION_HEX < 0x01060000 +# define PyObject_Del(op) PyMem_DEL((op)) +#endif +#ifndef PyObject_DEL +# define PyObject_DEL PyObject_Del +#endif + +/* A crude PyExc_StopIteration exception for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 +# ifndef PyExc_StopIteration +# define PyExc_StopIteration PyExc_RuntimeError +# endif +# ifndef PyObject_GenericGetAttr +# define PyObject_GenericGetAttr 0 +# endif +#endif +/* Py_NotImplemented is defined in 2.1 and up. */ +#if PY_VERSION_HEX < 0x02010000 +# ifndef Py_NotImplemented +# define Py_NotImplemented PyExc_RuntimeError +# endif +#endif + + +/* A crude PyString_AsStringAndSize implementation for old Pythons */ +#if PY_VERSION_HEX < 0x02010000 +# ifndef PyString_AsStringAndSize +# define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;} +# endif +#endif + +/* PySequence_Size for old Pythons */ +#if PY_VERSION_HEX < 0x02000000 +# ifndef PySequence_Size +# define PySequence_Size PySequence_Length +# endif +#endif + + +/* PyBool_FromLong for old Pythons */ +#if PY_VERSION_HEX < 0x02030000 +static +PyObject *PyBool_FromLong(long ok) +{ + PyObject *result = ok ? Py_True : Py_False; + Py_INCREF(result); + return result; +} +#endif + +/* Py_ssize_t for old Pythons */ +/* This code is as recommended by: */ +/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */ +#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) +typedef int Py_ssize_t; +# define PY_SSIZE_T_MAX INT_MAX +# define PY_SSIZE_T_MIN INT_MIN +#endif + +/* ----------------------------------------------------------------------------- + * error manipulation + * ----------------------------------------------------------------------------- */ + +SWIGRUNTIME PyObject* +SWIG_Python_ErrorType(int code) { + PyObject* type = 0; + switch(code) { + case SWIG_MemoryError: + type = PyExc_MemoryError; + break; + case SWIG_IOError: + type = PyExc_IOError; + break; + case SWIG_RuntimeError: + type = PyExc_RuntimeError; + break; + case SWIG_IndexError: + type = PyExc_IndexError; + break; + case SWIG_TypeError: + type = PyExc_TypeError; + break; + case SWIG_DivisionByZero: + type = PyExc_ZeroDivisionError; + break; + case SWIG_OverflowError: + type = PyExc_OverflowError; + break; + case SWIG_SyntaxError: + type = PyExc_SyntaxError; + break; + case SWIG_ValueError: + type = PyExc_ValueError; + break; + case SWIG_SystemError: + type = PyExc_SystemError; + break; + case SWIG_AttributeError: + type = PyExc_AttributeError; + break; + default: + type = PyExc_RuntimeError; + } + return type; +} + + +SWIGRUNTIME void +SWIG_Python_AddErrorMsg(const char* mesg) +{ + PyObject *type = 0; + PyObject *value = 0; + PyObject *traceback = 0; + + if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback); + if (value) { + PyObject *old_str = PyObject_Str(value); + PyErr_Clear(); + Py_XINCREF(type); + PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); + Py_DECREF(old_str); + Py_DECREF(value); + } else { + PyErr_Format(PyExc_RuntimeError, mesg); + } +} + + + +#if defined(SWIG_PYTHON_NO_THREADS) +# if defined(SWIG_PYTHON_THREADS) +# undef SWIG_PYTHON_THREADS +# endif +#endif +#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */ +# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL) +# if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */ +# define SWIG_PYTHON_USE_GIL +# endif +# endif +# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */ +# ifndef SWIG_PYTHON_INITIALIZE_THREADS +# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads() +# endif +# ifdef __cplusplus /* C++ code */ + class SWIG_Python_Thread_Block { + bool status; + PyGILState_STATE state; + public: + void end() { if (status) { PyGILState_Release(state); status = false;} } + SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {} + ~SWIG_Python_Thread_Block() { end(); } + }; + class SWIG_Python_Thread_Allow { + bool status; + PyThreadState *save; + public: + void end() { if (status) { PyEval_RestoreThread(save); status = false; }} + SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {} + ~SWIG_Python_Thread_Allow() { end(); } + }; +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block +# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end() +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow +# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end() +# else /* C code */ +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure() +# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block) +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread() +# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow) +# endif +# else /* Old thread way, not implemented, user must provide it */ +# if !defined(SWIG_PYTHON_INITIALIZE_THREADS) +# define SWIG_PYTHON_INITIALIZE_THREADS +# endif +# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK) +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK +# endif +# if !defined(SWIG_PYTHON_THREAD_END_BLOCK) +# define SWIG_PYTHON_THREAD_END_BLOCK +# endif +# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW) +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW +# endif +# if !defined(SWIG_PYTHON_THREAD_END_ALLOW) +# define SWIG_PYTHON_THREAD_END_ALLOW +# endif +# endif +#else /* No thread support */ +# define SWIG_PYTHON_INITIALIZE_THREADS +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK +# define SWIG_PYTHON_THREAD_END_BLOCK +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW +# define SWIG_PYTHON_THREAD_END_ALLOW +#endif + +/* ----------------------------------------------------------------------------- + * Python API portion that goes into the runtime + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* cc-mode */ +#endif +#endif + +/* ----------------------------------------------------------------------------- + * Constant declarations + * ----------------------------------------------------------------------------- */ + +/* Constant Types */ +#define SWIG_PY_POINTER 4 +#define SWIG_PY_BINARY 5 + +/* Constant information structure */ +typedef struct swig_const_info { + int type; + char *name; + long lvalue; + double dvalue; + void *pvalue; + swig_type_info **ptype; +} swig_const_info; + +#ifdef __cplusplus +#if 0 +{ /* cc-mode */ +#endif +} +#endif + + +/* ----------------------------------------------------------------------------- + * See the LICENSE file for information on copyright, usage and redistribution + * of SWIG, and the README file for authors - http://www.swig.org/release.html. + * + * pyrun.swg + * + * This file contains the runtime support for Python modules + * and includes code for managing global variables and pointer + * type checking. + * + * ----------------------------------------------------------------------------- */ + +/* Common SWIG API */ + +/* for raw pointers */ +#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0) +#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags) +#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own) +#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags) +#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty) +#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src) +#define swig_owntype int + +/* for raw packed data */ +#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) + +/* for class or struct pointers */ +#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags) +#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags) + +/* for C or C++ function pointers */ +#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type) +#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(ptr, type, 0) + +/* for C++ member pointers, ie, member methods */ +#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) + + +/* Runtime API */ + +#define SWIG_GetModule(clientdata) SWIG_Python_GetModule() +#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer) +#define SWIG_NewClientData(obj) PySwigClientData_New(obj) + +#define SWIG_SetErrorObj SWIG_Python_SetErrorObj +#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg +#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code) +#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) +#define SWIG_fail goto fail + + +/* Runtime API implementation */ + +/* Error manipulation */ + +SWIGINTERN void +SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyErr_SetObject(errtype, obj); + Py_DECREF(obj); + SWIG_PYTHON_THREAD_END_BLOCK; +} + +SWIGINTERN void +SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyErr_SetString(errtype, (char *) msg); + SWIG_PYTHON_THREAD_END_BLOCK; +} + +#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj) + +/* Set a constant value */ + +SWIGINTERN void +SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) { + PyDict_SetItemString(d, (char*) name, obj); + Py_DECREF(obj); +} + +/* Append a value to the result obj */ + +SWIGINTERN PyObject* +SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) { +#if !defined(SWIG_PYTHON_OUTPUT_TUPLE) + if (!result) { + result = obj; + } else if (result == Py_None) { + Py_DECREF(result); + result = obj; + } else { + if (!PyList_Check(result)) { + PyObject *o2 = result; + result = PyList_New(1); + PyList_SetItem(result, 0, o2); + } + PyList_Append(result,obj); + Py_DECREF(obj); + } + return result; +#else + PyObject* o2; + PyObject* o3; + if (!result) { + result = obj; + } else if (result == Py_None) { + Py_DECREF(result); + result = obj; + } else { + if (!PyTuple_Check(result)) { + o2 = result; + result = PyTuple_New(1); + PyTuple_SET_ITEM(result, 0, o2); + } + o3 = PyTuple_New(1); + PyTuple_SET_ITEM(o3, 0, obj); + o2 = result; + result = PySequence_Concat(o2, o3); + Py_DECREF(o2); + Py_DECREF(o3); + } + return result; +#endif +} + +/* Unpack the argument tuple */ + +SWIGINTERN int +SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs) +{ + if (!args) { + if (!min && !max) { + return 1; + } else { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", + name, (min == max ? "" : "at least "), (int)min); + return 0; + } + } + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple"); + return 0; + } else { + register Py_ssize_t l = PyTuple_GET_SIZE(args); + if (l < min) { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at least "), (int)min, (int)l); + return 0; + } else if (l > max) { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at most "), (int)max, (int)l); + return 0; + } else { + register int i; + for (i = 0; i < l; ++i) { + objs[i] = PyTuple_GET_ITEM(args, i); + } + for (; l < max; ++l) { + objs[l] = 0; + } + return i + 1; + } + } +} + +/* A functor is a function object with one single object argument */ +#if PY_VERSION_HEX >= 0x02020000 +#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL); +#else +#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj); +#endif + +/* + Helper for static pointer initialization for both C and C++ code, for example + static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...); +*/ +#ifdef __cplusplus +#define SWIG_STATIC_POINTER(var) var +#else +#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var +#endif + +/* ----------------------------------------------------------------------------- + * Pointer declarations + * ----------------------------------------------------------------------------- */ + +/* Flags for new pointer objects */ +#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1) +#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN) + +#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1) + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* cc-mode */ +#endif +#endif + +/* How to access Py_None */ +#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# ifndef SWIG_PYTHON_NO_BUILD_NONE +# ifndef SWIG_PYTHON_BUILD_NONE +# define SWIG_PYTHON_BUILD_NONE +# endif +# endif +#endif + +#ifdef SWIG_PYTHON_BUILD_NONE +# ifdef Py_None +# undef Py_None +# define Py_None SWIG_Py_None() +# endif +SWIGRUNTIMEINLINE PyObject * +_SWIG_Py_None(void) +{ + PyObject *none = Py_BuildValue((char*)""); + Py_DECREF(none); + return none; +} +SWIGRUNTIME PyObject * +SWIG_Py_None(void) +{ + static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None(); + return none; +} +#endif + +/* The python void return value */ + +SWIGRUNTIMEINLINE PyObject * +SWIG_Py_Void(void) +{ + PyObject *none = Py_None; + Py_INCREF(none); + return none; +} + +/* PySwigClientData */ + +typedef struct { + PyObject *klass; + PyObject *newraw; + PyObject *newargs; + PyObject *destroy; + int delargs; + int implicitconv; +} PySwigClientData; + +SWIGRUNTIMEINLINE int +SWIG_Python_CheckImplicit(swig_type_info *ty) +{ + PySwigClientData *data = (PySwigClientData *)ty->clientdata; + return data ? data->implicitconv : 0; +} + +SWIGRUNTIMEINLINE PyObject * +SWIG_Python_ExceptionType(swig_type_info *desc) { + PySwigClientData *data = desc ? (PySwigClientData *) desc->clientdata : 0; + PyObject *klass = data ? data->klass : 0; + return (klass ? klass : PyExc_RuntimeError); +} + + +SWIGRUNTIME PySwigClientData * +PySwigClientData_New(PyObject* obj) +{ + if (!obj) { + return 0; + } else { + PySwigClientData *data = (PySwigClientData *)malloc(sizeof(PySwigClientData)); + /* the klass element */ + data->klass = obj; + Py_INCREF(data->klass); + /* the newraw method and newargs arguments used to create a new raw instance */ + if (PyClass_Check(obj)) { + data->newraw = 0; + data->newargs = obj; + Py_INCREF(obj); + } else { +#if (PY_VERSION_HEX < 0x02020000) + data->newraw = 0; +#else + data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__"); +#endif + if (data->newraw) { + Py_INCREF(data->newraw); + data->newargs = PyTuple_New(1); + PyTuple_SetItem(data->newargs, 0, obj); + } else { + data->newargs = obj; + } + Py_INCREF(data->newargs); + } + /* the destroy method, aka as the C++ delete method */ + data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__"); + if (PyErr_Occurred()) { + PyErr_Clear(); + data->destroy = 0; + } + if (data->destroy) { + int flags; + Py_INCREF(data->destroy); + flags = PyCFunction_GET_FLAGS(data->destroy); +#ifdef METH_O + data->delargs = !(flags & (METH_O)); +#else + data->delargs = 0; +#endif + } else { + data->delargs = 0; + } + data->implicitconv = 0; + return data; + } +} + +SWIGRUNTIME void +PySwigClientData_Del(PySwigClientData* data) +{ + Py_XDECREF(data->newraw); + Py_XDECREF(data->newargs); + Py_XDECREF(data->destroy); +} + +/* =============== PySwigObject =====================*/ + +typedef struct { + PyObject_HEAD + void *ptr; + swig_type_info *ty; + int own; + PyObject *next; +} PySwigObject; + +SWIGRUNTIME PyObject * +PySwigObject_long(PySwigObject *v) +{ + return PyLong_FromVoidPtr(v->ptr); +} + +SWIGRUNTIME PyObject * +PySwigObject_format(const char* fmt, PySwigObject *v) +{ + PyObject *res = NULL; + PyObject *args = PyTuple_New(1); + if (args) { + if (PyTuple_SetItem(args, 0, PySwigObject_long(v)) == 0) { + PyObject *ofmt = PyString_FromString(fmt); + if (ofmt) { + res = PyString_Format(ofmt,args); + Py_DECREF(ofmt); + } + Py_DECREF(args); + } + } + return res; +} + +SWIGRUNTIME PyObject * +PySwigObject_oct(PySwigObject *v) +{ + return PySwigObject_format("%o",v); +} + +SWIGRUNTIME PyObject * +PySwigObject_hex(PySwigObject *v) +{ + return PySwigObject_format("%x",v); +} + +SWIGRUNTIME PyObject * +#ifdef METH_NOARGS +PySwigObject_repr(PySwigObject *v) +#else +PySwigObject_repr(PySwigObject *v, PyObject *args) +#endif +{ + const char *name = SWIG_TypePrettyName(v->ty); + PyObject *hex = PySwigObject_hex(v); + PyObject *repr = PyString_FromFormat("", name, PyString_AsString(hex)); + Py_DECREF(hex); + if (v->next) { +#ifdef METH_NOARGS + PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next); +#else + PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next, args); +#endif + PyString_ConcatAndDel(&repr,nrep); + } + return repr; +} + +SWIGRUNTIME int +PySwigObject_print(PySwigObject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) +{ +#ifdef METH_NOARGS + PyObject *repr = PySwigObject_repr(v); +#else + PyObject *repr = PySwigObject_repr(v, NULL); +#endif + if (repr) { + fputs(PyString_AsString(repr), fp); + Py_DECREF(repr); + return 0; + } else { + return 1; + } +} + +SWIGRUNTIME PyObject * +PySwigObject_str(PySwigObject *v) +{ + char result[SWIG_BUFFER_SIZE]; + return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ? + PyString_FromString(result) : 0; +} + +SWIGRUNTIME int +PySwigObject_compare(PySwigObject *v, PySwigObject *w) +{ + void *i = v->ptr; + void *j = w->ptr; + return (i < j) ? -1 : ((i > j) ? 1 : 0); +} + +SWIGRUNTIME PyTypeObject* _PySwigObject_type(void); + +SWIGRUNTIME PyTypeObject* +PySwigObject_type(void) { + static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigObject_type(); + return type; +} + +SWIGRUNTIMEINLINE int +PySwigObject_Check(PyObject *op) { + return ((op)->ob_type == PySwigObject_type()) + || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0); +} + +SWIGRUNTIME PyObject * +PySwigObject_New(void *ptr, swig_type_info *ty, int own); + +SWIGRUNTIME void +PySwigObject_dealloc(PyObject *v) +{ + PySwigObject *sobj = (PySwigObject *) v; + PyObject *next = sobj->next; + if (sobj->own) { + swig_type_info *ty = sobj->ty; + PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; + PyObject *destroy = data ? data->destroy : 0; + if (destroy) { + /* destroy is always a VARARGS method */ + PyObject *res; + if (data->delargs) { + /* we need to create a temporal object to carry the destroy operation */ + PyObject *tmp = PySwigObject_New(sobj->ptr, ty, 0); + res = SWIG_Python_CallFunctor(destroy, tmp); + Py_DECREF(tmp); + } else { + PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); + PyObject *mself = PyCFunction_GET_SELF(destroy); + res = ((*meth)(mself, v)); + } + Py_XDECREF(res); + } else { + const char *name = SWIG_TypePrettyName(ty); +#if !defined(SWIG_PYTHON_SILENT_MEMLEAK) + printf("swig/python detected a memory leak of type '%s', no destructor found.\n", name); +#endif + } + } + Py_XDECREF(next); + PyObject_DEL(v); +} + +SWIGRUNTIME PyObject* +PySwigObject_append(PyObject* v, PyObject* next) +{ + PySwigObject *sobj = (PySwigObject *) v; +#ifndef METH_O + PyObject *tmp = 0; + if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL; + next = tmp; +#endif + if (!PySwigObject_Check(next)) { + return NULL; + } + sobj->next = next; + Py_INCREF(next); + return SWIG_Py_Void(); +} + +SWIGRUNTIME PyObject* +#ifdef METH_NOARGS +PySwigObject_next(PyObject* v) +#else +PySwigObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + PySwigObject *sobj = (PySwigObject *) v; + if (sobj->next) { + Py_INCREF(sobj->next); + return sobj->next; + } else { + return SWIG_Py_Void(); + } +} + +SWIGINTERN PyObject* +#ifdef METH_NOARGS +PySwigObject_disown(PyObject *v) +#else +PySwigObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + PySwigObject *sobj = (PySwigObject *)v; + sobj->own = 0; + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject* +#ifdef METH_NOARGS +PySwigObject_acquire(PyObject *v) +#else +PySwigObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + PySwigObject *sobj = (PySwigObject *)v; + sobj->own = SWIG_POINTER_OWN; + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject* +PySwigObject_own(PyObject *v, PyObject *args) +{ + PyObject *val = 0; +#if (PY_VERSION_HEX < 0x02020000) + if (!PyArg_ParseTuple(args,(char *)"|O:own",&val)) +#else + if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) +#endif + { + return NULL; + } + else + { + PySwigObject *sobj = (PySwigObject *)v; + PyObject *obj = PyBool_FromLong(sobj->own); + if (val) { +#ifdef METH_NOARGS + if (PyObject_IsTrue(val)) { + PySwigObject_acquire(v); + } else { + PySwigObject_disown(v); + } +#else + if (PyObject_IsTrue(val)) { + PySwigObject_acquire(v,args); + } else { + PySwigObject_disown(v,args); + } +#endif + } + return obj; + } +} + +#ifdef METH_O +static PyMethodDef +swigobject_methods[] = { + {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"}, + {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, (char *)"aquires ownership of the pointer"}, + {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, + {(char *)"append", (PyCFunction)PySwigObject_append, METH_O, (char *)"appends another 'this' object"}, + {(char *)"next", (PyCFunction)PySwigObject_next, METH_NOARGS, (char *)"returns the next 'this' object"}, + {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_NOARGS, (char *)"returns object representation"}, + {0, 0, 0, 0} +}; +#else +static PyMethodDef +swigobject_methods[] = { + {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"}, + {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_VARARGS, (char *)"aquires ownership of the pointer"}, + {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, + {(char *)"append", (PyCFunction)PySwigObject_append, METH_VARARGS, (char *)"appends another 'this' object"}, + {(char *)"next", (PyCFunction)PySwigObject_next, METH_VARARGS, (char *)"returns the next 'this' object"}, + {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_VARARGS, (char *)"returns object representation"}, + {0, 0, 0, 0} +}; +#endif + +#if PY_VERSION_HEX < 0x02020000 +SWIGINTERN PyObject * +PySwigObject_getattr(PySwigObject *sobj,char *name) +{ + return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name); +} +#endif + +SWIGRUNTIME PyTypeObject* +_PySwigObject_type(void) { + static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; + + static PyNumberMethods PySwigObject_as_number = { + (binaryfunc)0, /*nb_add*/ + (binaryfunc)0, /*nb_subtract*/ + (binaryfunc)0, /*nb_multiply*/ + (binaryfunc)0, /*nb_divide*/ + (binaryfunc)0, /*nb_remainder*/ + (binaryfunc)0, /*nb_divmod*/ + (ternaryfunc)0,/*nb_power*/ + (unaryfunc)0, /*nb_negative*/ + (unaryfunc)0, /*nb_positive*/ + (unaryfunc)0, /*nb_absolute*/ + (inquiry)0, /*nb_nonzero*/ + 0, /*nb_invert*/ + 0, /*nb_lshift*/ + 0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ + (coercion)0, /*nb_coerce*/ + (unaryfunc)PySwigObject_long, /*nb_int*/ + (unaryfunc)PySwigObject_long, /*nb_long*/ + (unaryfunc)0, /*nb_float*/ + (unaryfunc)PySwigObject_oct, /*nb_oct*/ + (unaryfunc)PySwigObject_hex, /*nb_hex*/ +#if PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */ +#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */ +#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */ + 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */ +#endif + }; + + static PyTypeObject pyswigobject_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + (char *)"PySwigObject", /* tp_name */ + sizeof(PySwigObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)PySwigObject_dealloc, /* tp_dealloc */ + (printfunc)PySwigObject_print, /* tp_print */ +#if PY_VERSION_HEX < 0x02020000 + (getattrfunc)PySwigObject_getattr, /* tp_getattr */ +#else + (getattrfunc)0, /* tp_getattr */ +#endif + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)PySwigObject_compare, /* tp_compare */ + (reprfunc)PySwigObject_repr, /* tp_repr */ + &PySwigObject_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)PySwigObject_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + swigobject_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0, /* tp_iter */ + 0, /* tp_iternext */ + swigobject_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + pyswigobject_type = tmp; + pyswigobject_type.ob_type = &PyType_Type; + type_init = 1; + } + return &pyswigobject_type; +} + +SWIGRUNTIME PyObject * +PySwigObject_New(void *ptr, swig_type_info *ty, int own) +{ + PySwigObject *sobj = PyObject_NEW(PySwigObject, PySwigObject_type()); + if (sobj) { + sobj->ptr = ptr; + sobj->ty = ty; + sobj->own = own; + sobj->next = 0; + } + return (PyObject *)sobj; +} + +/* ----------------------------------------------------------------------------- + * Implements a simple Swig Packed type, and use it instead of string + * ----------------------------------------------------------------------------- */ + +typedef struct { + PyObject_HEAD + void *pack; + swig_type_info *ty; + size_t size; +} PySwigPacked; + +SWIGRUNTIME int +PySwigPacked_print(PySwigPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags)) +{ + char result[SWIG_BUFFER_SIZE]; + fputs("pack, v->size, 0, sizeof(result))) { + fputs("at ", fp); + fputs(result, fp); + } + fputs(v->ty->name,fp); + fputs(">", fp); + return 0; +} + +SWIGRUNTIME PyObject * +PySwigPacked_repr(PySwigPacked *v) +{ + char result[SWIG_BUFFER_SIZE]; + if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { + return PyString_FromFormat("", result, v->ty->name); + } else { + return PyString_FromFormat("", v->ty->name); + } +} + +SWIGRUNTIME PyObject * +PySwigPacked_str(PySwigPacked *v) +{ + char result[SWIG_BUFFER_SIZE]; + if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ + return PyString_FromFormat("%s%s", result, v->ty->name); + } else { + return PyString_FromString(v->ty->name); + } +} + +SWIGRUNTIME int +PySwigPacked_compare(PySwigPacked *v, PySwigPacked *w) +{ + size_t i = v->size; + size_t j = w->size; + int s = (i < j) ? -1 : ((i > j) ? 1 : 0); + return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size); +} + +SWIGRUNTIME PyTypeObject* _PySwigPacked_type(void); + +SWIGRUNTIME PyTypeObject* +PySwigPacked_type(void) { + static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigPacked_type(); + return type; +} + +SWIGRUNTIMEINLINE int +PySwigPacked_Check(PyObject *op) { + return ((op)->ob_type == _PySwigPacked_type()) + || (strcmp((op)->ob_type->tp_name,"PySwigPacked") == 0); +} + +SWIGRUNTIME void +PySwigPacked_dealloc(PyObject *v) +{ + if (PySwigPacked_Check(v)) { + PySwigPacked *sobj = (PySwigPacked *) v; + free(sobj->pack); + } + PyObject_DEL(v); +} + +SWIGRUNTIME PyTypeObject* +_PySwigPacked_type(void) { + static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer"; + static PyTypeObject pyswigpacked_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + (char *)"PySwigPacked", /* tp_name */ + sizeof(PySwigPacked), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)PySwigPacked_dealloc, /* tp_dealloc */ + (printfunc)PySwigPacked_print, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)PySwigPacked_compare, /* tp_compare */ + (reprfunc)PySwigPacked_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)PySwigPacked_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + swigpacked_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + pyswigpacked_type = tmp; + pyswigpacked_type.ob_type = &PyType_Type; + type_init = 1; + } + return &pyswigpacked_type; +} + +SWIGRUNTIME PyObject * +PySwigPacked_New(void *ptr, size_t size, swig_type_info *ty) +{ + PySwigPacked *sobj = PyObject_NEW(PySwigPacked, PySwigPacked_type()); + if (sobj) { + void *pack = malloc(size); + if (pack) { + memcpy(pack, ptr, size); + sobj->pack = pack; + sobj->ty = ty; + sobj->size = size; + } else { + PyObject_DEL((PyObject *) sobj); + sobj = 0; + } + } + return (PyObject *) sobj; +} + +SWIGRUNTIME swig_type_info * +PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size) +{ + if (PySwigPacked_Check(obj)) { + PySwigPacked *sobj = (PySwigPacked *)obj; + if (sobj->size != size) return 0; + memcpy(ptr, sobj->pack, size); + return sobj->ty; + } else { + return 0; + } +} + +/* ----------------------------------------------------------------------------- + * pointers/data manipulation + * ----------------------------------------------------------------------------- */ + +SWIGRUNTIMEINLINE PyObject * +_SWIG_This(void) +{ + return PyString_FromString("this"); +} + +SWIGRUNTIME PyObject * +SWIG_This(void) +{ + static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This(); + return swig_this; +} + +/* #define SWIG_PYTHON_SLOW_GETSET_THIS */ + +SWIGRUNTIME PySwigObject * +SWIG_Python_GetSwigThis(PyObject *pyobj) +{ + if (PySwigObject_Check(pyobj)) { + return (PySwigObject *) pyobj; + } else { + PyObject *obj = 0; +#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000)) + if (PyInstance_Check(pyobj)) { + obj = _PyInstance_Lookup(pyobj, SWIG_This()); + } else { + PyObject **dictptr = _PyObject_GetDictPtr(pyobj); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0; + } else { +#ifdef PyWeakref_CheckProxy + if (PyWeakref_CheckProxy(pyobj)) { + PyObject *wobj = PyWeakref_GET_OBJECT(pyobj); + return wobj ? SWIG_Python_GetSwigThis(wobj) : 0; + } +#endif + obj = PyObject_GetAttr(pyobj,SWIG_This()); + if (obj) { + Py_DECREF(obj); + } else { + if (PyErr_Occurred()) PyErr_Clear(); + return 0; + } + } + } +#else + obj = PyObject_GetAttr(pyobj,SWIG_This()); + if (obj) { + Py_DECREF(obj); + } else { + if (PyErr_Occurred()) PyErr_Clear(); + return 0; + } +#endif + if (obj && !PySwigObject_Check(obj)) { + /* a PyObject is called 'this', try to get the 'real this' + PySwigObject from it */ + return SWIG_Python_GetSwigThis(obj); + } + return (PySwigObject *)obj; + } +} + +/* Acquire a pointer value */ + +SWIGRUNTIME int +SWIG_Python_AcquirePtr(PyObject *obj, int own) { + if (own) { + PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + if (sobj) { + int oldown = sobj->own; + sobj->own = own; + return oldown; + } + } + return 0; +} + +/* Convert a pointer value */ + +SWIGRUNTIME int +SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) { + if (!obj) return SWIG_ERROR; + if (obj == Py_None) { + if (ptr) *ptr = 0; + return SWIG_OK; + } else { + PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + while (sobj) { + void *vptr = sobj->ptr; + if (ty) { + swig_type_info *to = sobj->ty; + if (to == ty) { + /* no type cast needed */ + if (ptr) *ptr = vptr; + break; + } else { + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) { + sobj = (PySwigObject *)sobj->next; + } else { + if (ptr) *ptr = SWIG_TypeCast(tc,vptr); + break; + } + } + } else { + if (ptr) *ptr = vptr; + break; + } + } + if (sobj) { + if (own) *own = sobj->own; + if (flags & SWIG_POINTER_DISOWN) { + sobj->own = 0; + } + return SWIG_OK; + } else { + int res = SWIG_ERROR; + if (flags & SWIG_POINTER_IMPLICIT_CONV) { + PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; + if (data && !data->implicitconv) { + PyObject *klass = data->klass; + if (klass) { + PyObject *impconv; + data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/ + impconv = SWIG_Python_CallFunctor(klass, obj); + data->implicitconv = 0; + if (PyErr_Occurred()) { + PyErr_Clear(); + impconv = 0; + } + if (impconv) { + PySwigObject *iobj = SWIG_Python_GetSwigThis(impconv); + if (iobj) { + void *vptr; + res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0); + if (SWIG_IsOK(res)) { + if (ptr) { + *ptr = vptr; + /* transfer the ownership to 'ptr' */ + iobj->own = 0; + res = SWIG_AddCast(res); + res = SWIG_AddNewMask(res); + } else { + res = SWIG_AddCast(res); + } + } + } + Py_DECREF(impconv); + } + } + } + } + return res; + } + } +} + +/* Convert a function ptr value */ + +SWIGRUNTIME int +SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { + if (!PyCFunction_Check(obj)) { + return SWIG_ConvertPtr(obj, ptr, ty, 0); + } else { + void *vptr = 0; + + /* here we get the method pointer for callbacks */ + const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); + const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0; + if (desc) { + desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0; + if (!desc) return SWIG_ERROR; + } + if (ty) { + swig_cast_info *tc = SWIG_TypeCheck(desc,ty); + if (!tc) return SWIG_ERROR; + *ptr = SWIG_TypeCast(tc,vptr); + } else { + *ptr = vptr; + } + return SWIG_OK; + } +} + +/* Convert a packed value value */ + +SWIGRUNTIME int +SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { + swig_type_info *to = PySwigPacked_UnpackData(obj, ptr, sz); + if (!to) return SWIG_ERROR; + if (ty) { + if (to != ty) { + /* check type cast? */ + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) return SWIG_ERROR; + } + } + return SWIG_OK; +} + +/* ----------------------------------------------------------------------------- + * Create a new pointer object + * ----------------------------------------------------------------------------- */ + +/* + Create a new instance object, whitout calling __init__, and set the + 'this' attribute. +*/ + +SWIGRUNTIME PyObject* +SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this) +{ +#if (PY_VERSION_HEX >= 0x02020000) + PyObject *inst = 0; + PyObject *newraw = data->newraw; + if (newraw) { + inst = PyObject_Call(newraw, data->newargs, NULL); + if (inst) { +#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + PyObject **dictptr = _PyObject_GetDictPtr(inst); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + *dictptr = dict; + PyDict_SetItem(dict, SWIG_This(), swig_this); + } + } +#else + PyObject *key = SWIG_This(); + PyObject_SetAttr(inst, key, swig_this); +#endif + } + } else { + PyObject *dict = PyDict_New(); + PyDict_SetItem(dict, SWIG_This(), swig_this); + inst = PyInstance_NewRaw(data->newargs, dict); + Py_DECREF(dict); + } + return inst; +#else +#if (PY_VERSION_HEX >= 0x02010000) + PyObject *inst; + PyObject *dict = PyDict_New(); + PyDict_SetItem(dict, SWIG_This(), swig_this); + inst = PyInstance_NewRaw(data->newargs, dict); + Py_DECREF(dict); + return (PyObject *) inst; +#else + PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); + if (inst == NULL) { + return NULL; + } + inst->in_class = (PyClassObject *)data->newargs; + Py_INCREF(inst->in_class); + inst->in_dict = PyDict_New(); + if (inst->in_dict == NULL) { + Py_DECREF(inst); + return NULL; + } +#ifdef Py_TPFLAGS_HAVE_WEAKREFS + inst->in_weakreflist = NULL; +#endif +#ifdef Py_TPFLAGS_GC + PyObject_GC_Init(inst); +#endif + PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this); + return (PyObject *) inst; +#endif +#endif +} + +SWIGRUNTIME void +SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) +{ + PyObject *dict; +#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + PyObject **dictptr = _PyObject_GetDictPtr(inst); + if (dictptr != NULL) { + dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + *dictptr = dict; + } + PyDict_SetItem(dict, SWIG_This(), swig_this); + return; + } +#endif + dict = PyObject_GetAttrString(inst, (char*)"__dict__"); + PyDict_SetItem(dict, SWIG_This(), swig_this); + Py_DECREF(dict); +} + + +SWIGINTERN PyObject * +SWIG_Python_InitShadowInstance(PyObject *args) { + PyObject *obj[2]; + if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) { + return NULL; + } else { + PySwigObject *sthis = SWIG_Python_GetSwigThis(obj[0]); + if (sthis) { + PySwigObject_append((PyObject*) sthis, obj[1]); + } else { + SWIG_Python_SetSwigThis(obj[0], obj[1]); + } + return SWIG_Py_Void(); + } +} + +/* Create a new pointer object */ + +SWIGRUNTIME PyObject * +SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) { + if (!ptr) { + return SWIG_Py_Void(); + } else { + int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0; + PyObject *robj = PySwigObject_New(ptr, type, own); + PySwigClientData *clientdata = type ? (PySwigClientData *)(type->clientdata) : 0; + if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { + PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); + if (inst) { + Py_DECREF(robj); + robj = inst; + } + } + return robj; + } +} + +/* Create a new packed object */ + +SWIGRUNTIMEINLINE PyObject * +SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { + return ptr ? PySwigPacked_New((void *) ptr, sz, type) : SWIG_Py_Void(); +} + +/* -----------------------------------------------------------------------------* + * Get type list + * -----------------------------------------------------------------------------*/ + +#ifdef SWIG_LINK_RUNTIME +void *SWIG_ReturnGlobalTypeList(void *); +#endif + +SWIGRUNTIME swig_module_info * +SWIG_Python_GetModule(void) { + static void *type_pointer = (void *)0; + /* first check if module already created */ + if (!type_pointer) { +#ifdef SWIG_LINK_RUNTIME + type_pointer = SWIG_ReturnGlobalTypeList((void *)0); +#else + type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, + (char*)"type_pointer" SWIG_TYPE_TABLE_NAME); + if (PyErr_Occurred()) { + PyErr_Clear(); + type_pointer = (void *)0; + } +#endif + } + return (swig_module_info *) type_pointer; +} + +#if PY_MAJOR_VERSION < 2 +/* PyModule_AddObject function was introduced in Python 2.0. The following function + is copied out of Python/modsupport.c in python version 2.3.4 */ +SWIGINTERN int +PyModule_AddObject(PyObject *m, char *name, PyObject *o) +{ + PyObject *dict; + if (!PyModule_Check(m)) { + PyErr_SetString(PyExc_TypeError, + "PyModule_AddObject() needs module as first arg"); + return SWIG_ERROR; + } + if (!o) { + PyErr_SetString(PyExc_TypeError, + "PyModule_AddObject() needs non-NULL value"); + return SWIG_ERROR; + } + + dict = PyModule_GetDict(m); + if (dict == NULL) { + /* Internal error -- modules must have a dict! */ + PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", + PyModule_GetName(m)); + return SWIG_ERROR; + } + if (PyDict_SetItemString(dict, name, o)) + return SWIG_ERROR; + Py_DECREF(o); + return SWIG_OK; +} +#endif + +SWIGRUNTIME void +SWIG_Python_DestroyModule(void *vptr) +{ + swig_module_info *swig_module = (swig_module_info *) vptr; + swig_type_info **types = swig_module->types; + size_t i; + for (i =0; i < swig_module->size; ++i) { + swig_type_info *ty = types[i]; + if (ty->owndata) { + PySwigClientData *data = (PySwigClientData *) ty->clientdata; + if (data) PySwigClientData_Del(data); + } + } + Py_DECREF(SWIG_This()); +} + +SWIGRUNTIME void +SWIG_Python_SetModule(swig_module_info *swig_module) { + static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} };/* Sentinel */ + + PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, + swig_empty_runtime_method_table); + PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule); + if (pointer && module) { + PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer); + } else { + Py_XDECREF(pointer); + } +} + +/* The python cached type query */ +SWIGRUNTIME PyObject * +SWIG_Python_TypeCache(void) { + static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New(); + return cache; +} + +SWIGRUNTIME swig_type_info * +SWIG_Python_TypeQuery(const char *type) +{ + PyObject *cache = SWIG_Python_TypeCache(); + PyObject *key = PyString_FromString(type); + PyObject *obj = PyDict_GetItem(cache, key); + swig_type_info *descriptor; + if (obj) { + descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj); + } else { + swig_module_info *swig_module = SWIG_Python_GetModule(); + descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type); + if (descriptor) { + obj = PyCObject_FromVoidPtr(descriptor, NULL); + PyDict_SetItem(cache, key, obj); + Py_DECREF(obj); + } + } + Py_DECREF(key); + return descriptor; +} + +/* + For backward compatibility only +*/ +#define SWIG_POINTER_EXCEPTION 0 +#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg) +#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags) + +SWIGRUNTIME int +SWIG_Python_AddErrMesg(const char* mesg, int infront) +{ + if (PyErr_Occurred()) { + PyObject *type = 0; + PyObject *value = 0; + PyObject *traceback = 0; + PyErr_Fetch(&type, &value, &traceback); + if (value) { + PyObject *old_str = PyObject_Str(value); + Py_XINCREF(type); + PyErr_Clear(); + if (infront) { + PyErr_Format(type, "%s %s", mesg, PyString_AsString(old_str)); + } else { + PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); + } + Py_DECREF(old_str); + } + return 1; + } else { + return 0; + } +} + +SWIGRUNTIME int +SWIG_Python_ArgFail(int argnum) +{ + if (PyErr_Occurred()) { + /* add information about failing argument */ + char mesg[256]; + PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum); + return SWIG_Python_AddErrMesg(mesg, 1); + } else { + return 0; + } +} + +SWIGRUNTIMEINLINE const char * +PySwigObject_GetDesc(PyObject *self) +{ + PySwigObject *v = (PySwigObject *)self; + swig_type_info *ty = v ? v->ty : 0; + return ty ? ty->str : (char*)""; +} + +SWIGRUNTIME void +SWIG_Python_TypeError(const char *type, PyObject *obj) +{ + if (type) { +#if defined(SWIG_COBJECT_TYPES) + if (obj && PySwigObject_Check(obj)) { + const char *otype = (const char *) PySwigObject_GetDesc(obj); + if (otype) { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'PySwigObject(%s)' is received", + type, otype); + return; + } + } else +#endif + { + const char *otype = (obj ? obj->ob_type->tp_name : 0); + if (otype) { + PyObject *str = PyObject_Str(obj); + const char *cstr = str ? PyString_AsString(str) : 0; + if (cstr) { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received", + type, otype, cstr); + } else { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received", + type, otype); + } + Py_XDECREF(str); + return; + } + } + PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); + } else { + PyErr_Format(PyExc_TypeError, "unexpected type is received"); + } +} + + +/* Convert a pointer value, signal an exception on a type mismatch */ +SWIGRUNTIME void * +SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) { + void *result; + if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) { + PyErr_Clear(); + if (flags & SWIG_POINTER_EXCEPTION) { + SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj); + SWIG_Python_ArgFail(argnum); + } + } + return result; +} + + +#ifdef __cplusplus +#if 0 +{ /* cc-mode */ +#endif +} +#endif + + + +#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) + +#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else + + + +/* -------- TYPES TABLE (BEGIN) -------- */ + +#define SWIGTYPE_p_TALLOC_CTX swig_types[0] +#define SWIGTYPE_p_auth_session_info swig_types[1] +#define SWIGTYPE_p_char swig_types[2] +#define SWIGTYPE_p_cli_credentials swig_types[3] +#define SWIGTYPE_p_hive_key swig_types[4] +#define SWIGTYPE_p_int swig_types[5] +#define SWIGTYPE_p_loadparm_context swig_types[6] +#define SWIGTYPE_p_long_long swig_types[7] +#define SWIGTYPE_p_p_char swig_types[8] +#define SWIGTYPE_p_p_hive_key swig_types[9] +#define SWIGTYPE_p_p_registry_context swig_types[10] +#define SWIGTYPE_p_p_registry_key swig_types[11] +#define SWIGTYPE_p_registry_context swig_types[12] +#define SWIGTYPE_p_short swig_types[13] +#define SWIGTYPE_p_signed_char swig_types[14] +#define SWIGTYPE_p_unsigned_char swig_types[15] +#define SWIGTYPE_p_unsigned_int swig_types[16] +#define SWIGTYPE_p_unsigned_long_long swig_types[17] +#define SWIGTYPE_p_unsigned_short swig_types[18] +static swig_type_info *swig_types[20]; +static swig_module_info swig_module = {swig_types, 19, 0, 0, 0, 0}; +#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) +#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) + +/* -------- TYPES TABLE (END) -------- */ + +#if (PY_VERSION_HEX <= 0x02000000) +# if !defined(SWIG_PYTHON_CLASSIC) +# error "This python version requires swig to be run with the '-classic' option" +# endif +#endif + +/*----------------------------------------------- + @(target):= _registry.so + ------------------------------------------------*/ +#define SWIG_init init_registry + +#define SWIG_name "_registry" + +#define SWIGVERSION 0x010333 +#define SWIG_VERSION SWIGVERSION + + +#define SWIG_as_voidptr(a) (void *)((const void *)(a)) +#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) + + +/* Include headers */ +#include +#include + +#include "includes.h" +#include "registry.h" + +typedef struct registry_context reg; +typedef struct hive_key hive; + + +#include +#if !defined(SWIG_NO_LLONG_MAX) +# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) +# define LLONG_MAX __LONG_LONG_MAX__ +# define LLONG_MIN (-LLONG_MAX - 1LL) +# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) +# endif +#endif + + +SWIGINTERN int +SWIG_AsVal_double (PyObject *obj, double *val) +{ + int res = SWIG_TypeError; + if (PyFloat_Check(obj)) { + if (val) *val = PyFloat_AsDouble(obj); + return SWIG_OK; + } else if (PyInt_Check(obj)) { + if (val) *val = PyInt_AsLong(obj); + return SWIG_OK; + } else if (PyLong_Check(obj)) { + double v = PyLong_AsDouble(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + double d = PyFloat_AsDouble(obj); + if (!PyErr_Occurred()) { + if (val) *val = d; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + long v = PyLong_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_AddCast(SWIG_OK)); + } else { + PyErr_Clear(); + } + } + } +#endif + return res; +} + + +#include + + +#include + + +SWIGINTERNINLINE int +SWIG_CanCastAsInteger(double *d, double min, double max) { + double x = *d; + if ((min <= x && x <= max)) { + double fx = floor(x); + double cx = ceil(x); + double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ + if ((errno == EDOM) || (errno == ERANGE)) { + errno = 0; + } else { + double summ, reps, diff; + if (rd < x) { + diff = x - rd; + } else if (rd > x) { + diff = rd - x; + } else { + return 1; + } + summ = rd + x; + reps = diff/summ; + if (reps < 8*DBL_EPSILON) { + *d = rd; + return 1; + } + } + } + return 0; +} + + +SWIGINTERN int +SWIG_AsVal_unsigned_SS_long (PyObject *obj, unsigned long *val) +{ + if (PyInt_Check(obj)) { + long v = PyInt_AsLong(obj); + if (v >= 0) { + if (val) *val = v; + return SWIG_OK; + } else { + return SWIG_OverflowError; + } + } else if (PyLong_Check(obj)) { + unsigned long v = PyLong_AsUnsignedLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + unsigned long v = PyLong_AsUnsignedLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + double d; + int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); + if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) { + if (val) *val = (unsigned long)(d); + return res; + } + } + } +#endif + return SWIG_TypeError; +} + + +SWIGINTERN int +SWIG_AsVal_unsigned_SS_int (PyObject * obj, unsigned int *val) +{ + unsigned long v; + int res = SWIG_AsVal_unsigned_SS_long (obj, &v); + if (SWIG_IsOK(res)) { + if ((v > UINT_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = (unsigned int)(v); + } + } + return res; +} + + +SWIGINTERN swig_type_info* +SWIG_pchar_descriptor(void) +{ + static int init = 0; + static swig_type_info* info = 0; + if (!init) { + info = SWIG_TypeQuery("_p_char"); + init = 1; + } + return info; +} + + +SWIGINTERNINLINE PyObject * +SWIG_FromCharPtrAndSize(const char* carray, size_t size) +{ + if (carray) { + if (size > INT_MAX) { + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + return pchar_descriptor ? + SWIG_NewPointerObj((char *)(carray), pchar_descriptor, 0) : SWIG_Py_Void(); + } else { + return PyString_FromStringAndSize(carray, (int)(size)); + } + } else { + return SWIG_Py_Void(); + } +} + + +SWIGINTERNINLINE PyObject * +SWIG_FromCharPtr(const char *cptr) +{ + return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0)); +} + + +SWIGINTERN int +SWIG_AsVal_long (PyObject *obj, long* val) +{ + if (PyInt_Check(obj)) { + if (val) *val = PyInt_AsLong(obj); + return SWIG_OK; + } else if (PyLong_Check(obj)) { + long v = PyLong_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + long v = PyInt_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + double d; + int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); + if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) { + if (val) *val = (long)(d); + return res; + } + } + } +#endif + return SWIG_TypeError; +} + + +SWIGINTERN int +SWIG_AsVal_int (PyObject * obj, int *val) +{ + long v; + int res = SWIG_AsVal_long (obj, &v); + if (SWIG_IsOK(res)) { + if ((v < INT_MIN || v > INT_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = (int)(v); + } + } + return res; +} + +SWIGINTERN void delete_reg(reg *self){ talloc_free(self); } + +SWIGINTERN int +SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) +{ + if (PyString_Check(obj)) { + char *cstr; Py_ssize_t len; + PyString_AsStringAndSize(obj, &cstr, &len); + if (cptr) { + if (alloc) { + /* + In python the user should not be able to modify the inner + string representation. To warranty that, if you define + SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string + buffer is always returned. + + The default behavior is just to return the pointer value, + so, be careful. + */ +#if defined(SWIG_PYTHON_SAFE_CSTRINGS) + if (*alloc != SWIG_OLDOBJ) +#else + if (*alloc == SWIG_NEWOBJ) +#endif + { + *cptr = (char *)memcpy((char *)malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1)); + *alloc = SWIG_NEWOBJ; + } + else { + *cptr = cstr; + *alloc = SWIG_OLDOBJ; + } + } else { + *cptr = PyString_AsString(obj); + } + } + if (psize) *psize = len + 1; + return SWIG_OK; + } else { + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + if (pchar_descriptor) { + void* vptr = 0; + if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { + if (cptr) *cptr = (char *) vptr; + if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; + if (alloc) *alloc = SWIG_OLDOBJ; + return SWIG_OK; + } + } + } + return SWIG_TypeError; +} + + + + +SWIGINTERN WERROR reg_apply_patchfile(reg *self,char const *filename){ + return reg_diff_apply(filename, self); + } +SWIGINTERN void delete_hive(hive *self){ talloc_free(self); } + + #define SWIG_From_long PyInt_FromLong + + +SWIGINTERNINLINE PyObject* +SWIG_From_unsigned_SS_long (unsigned long value) +{ + return (value > LONG_MAX) ? + PyLong_FromUnsignedLong(value) : PyInt_FromLong((long)(value)); +} + + +SWIGINTERNINLINE PyObject * +SWIG_From_unsigned_SS_int (unsigned int value) +{ + return SWIG_From_unsigned_SS_long (value); +} + +#ifdef __cplusplus +extern "C" { +#endif +SWIGINTERN PyObject *_wrap_reg_get_predef_name(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + uint32_t arg1 ; + char *result = 0 ; + unsigned int val1 ; + int ecode1 = 0 ; + PyObject * obj0 = 0 ; + char * kwnames[] = { + (char *) "hkey", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:reg_get_predef_name",kwnames,&obj0)) SWIG_fail; + ecode1 = SWIG_AsVal_unsigned_SS_int(obj0, &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "reg_get_predef_name" "', argument " "1"" of type '" "uint32_t""'"); + } + arg1 = (uint32_t)(val1); + result = (char *)reg_get_predef_name(arg1); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_str_regtype(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + int arg1 ; + char *result = 0 ; + int val1 ; + int ecode1 = 0 ; + PyObject * obj0 = 0 ; + char * kwnames[] = { + (char *) "type", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:str_regtype",kwnames,&obj0)) SWIG_fail; + ecode1 = SWIG_AsVal_int(obj0, &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "str_regtype" "', argument " "1"" of type '" "int""'"); + } + arg1 = (int)(val1); + result = (char *)str_regtype(arg1); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Registry(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; + struct registry_context **arg2 = (struct registry_context **) 0 ; + struct auth_session_info *arg3 = (struct auth_session_info *) 0 ; + struct cli_credentials *arg4 = (struct cli_credentials *) 0 ; + WERROR result; + struct registry_context *tmp2 ; + void *argp3 = 0 ; + int res3 = 0 ; + void *argp4 = 0 ; + int res4 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "session_info",(char *) "credentials", NULL + }; + + { + arg3 = NULL; + } + { + arg4 = NULL; + } + { + arg1 = NULL; + } + { + arg2 = &tmp2; + } + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|OO:Registry",kwnames,&obj0,&obj1)) SWIG_fail; + if (obj0) { + res3 = SWIG_ConvertPtr(obj0, &argp3,SWIGTYPE_p_auth_session_info, 0 | 0 ); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "Registry" "', argument " "3"" of type '" "struct auth_session_info *""'"); + } + arg3 = (struct auth_session_info *)(argp3); + } + if (obj1) { + res4 = SWIG_ConvertPtr(obj1, &argp4,SWIGTYPE_p_cli_credentials, 0 | 0 ); + if (!SWIG_IsOK(res4)) { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "Registry" "', argument " "4"" of type '" "struct cli_credentials *""'"); + } + arg4 = (struct cli_credentials *)(argp4); + } + result = reg_open_local(arg1,arg2,arg3,arg4); + { + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + { + resultobj = SWIG_NewPointerObj(*arg2, SWIGTYPE_p_registry_context, 0); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_reg(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + reg *arg1 = (reg *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:delete_reg",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_reg" "', argument " "1"" of type '" "reg *""'"); + } + arg1 = (reg *)(argp1); + delete_reg(arg1); + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_reg_get_predefined_key_by_name(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + reg *arg1 = (reg *) 0 ; + char *arg2 = (char *) 0 ; + struct registry_key **arg3 = (struct registry_key **) 0 ; + WERROR result; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + void *argp3 = 0 ; + int res3 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "name",(char *) "key", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:reg_get_predefined_key_by_name",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_get_predefined_key_by_name" "', argument " "1"" of type '" "reg *""'"); + } + arg1 = (reg *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "reg_get_predefined_key_by_name" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = (char *)(buf2); + res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_p_registry_key, 0 | 0 ); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "reg_get_predefined_key_by_name" "', argument " "3"" of type '" "struct registry_key **""'"); + } + arg3 = (struct registry_key **)(argp3); + result = reg_get_predefined_key_by_name(arg1,(char const *)arg2,arg3); + { + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_reg_get_predefined_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + reg *arg1 = (reg *) 0 ; + uint32_t arg2 ; + struct registry_key **arg3 = (struct registry_key **) 0 ; + WERROR result; + void *argp1 = 0 ; + int res1 = 0 ; + unsigned int val2 ; + int ecode2 = 0 ; + void *argp3 = 0 ; + int res3 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "hkey_id",(char *) "key", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:reg_get_predefined_key",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_get_predefined_key" "', argument " "1"" of type '" "reg *""'"); + } + arg1 = (reg *)(argp1); + ecode2 = SWIG_AsVal_unsigned_SS_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "reg_get_predefined_key" "', argument " "2"" of type '" "uint32_t""'"); + } + arg2 = (uint32_t)(val2); + res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_p_registry_key, 0 | 0 ); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "reg_get_predefined_key" "', argument " "3"" of type '" "struct registry_key **""'"); + } + arg3 = (struct registry_key **)(argp3); + result = reg_get_predefined_key(arg1,arg2,arg3); + { + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_reg_apply_patchfile(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + reg *arg1 = (reg *) 0 ; + char *arg2 = (char *) 0 ; + WERROR result; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "filename", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:reg_apply_patchfile",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_apply_patchfile" "', argument " "1"" of type '" "reg *""'"); + } + arg1 = (reg *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "reg_apply_patchfile" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = (char *)(buf2); + result = reg_apply_patchfile(arg1,(char const *)arg2); + { + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_reg_mount_hive(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + reg *arg1 = (reg *) 0 ; + struct hive_key *arg2 = (struct hive_key *) 0 ; + uint32_t arg3 ; + char **arg4 = (char **) NULL ; + WERROR result; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + unsigned int val3 ; + int ecode3 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + PyObject * obj3 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "hive_key",(char *) "hkey_id",(char *) "elements", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO|O:reg_mount_hive",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_mount_hive" "', argument " "1"" of type '" "reg *""'"); + } + arg1 = (reg *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_hive_key, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "reg_mount_hive" "', argument " "2"" of type '" "struct hive_key *""'"); + } + arg2 = (struct hive_key *)(argp2); + ecode3 = SWIG_AsVal_unsigned_SS_int(obj2, &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "reg_mount_hive" "', argument " "3"" of type '" "uint32_t""'"); + } + arg3 = (uint32_t)(val3); + if (obj3) { + { + /* Check if is a list */ + if (PyList_Check(obj3)) { + int size = PyList_Size(obj3); + int i = 0; + arg4 = (char **) malloc((size+1)*sizeof(const char *)); + for (i = 0; i < size; i++) { + PyObject *o = PyList_GetItem(obj3,i); + if (PyString_Check(o)) + arg4[i] = PyString_AsString(PyList_GetItem(obj3,i)); + else { + PyErr_SetString(PyExc_TypeError,"list must contain strings"); + free(arg4); + return NULL; + } + } + arg4[i] = 0; + } else { + PyErr_SetString(PyExc_TypeError,"not a list"); + return NULL; + } + } + } + result = reg_mount_hive(arg1,arg2,arg3,(char const **)arg4); + { + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + { + free((char **) arg4); + } + return resultobj; +fail: + { + free((char **) arg4); + } + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_reg(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + reg *result = 0 ; + + if (!PyArg_ParseTuple(args,(char *)":new_reg")) SWIG_fail; + result = (reg *)(reg *) calloc(1, sizeof(reg)); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_registry_context, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *reg_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_registry_context, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_Hive(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; + char *arg2 = (char *) 0 ; + struct auth_session_info *arg3 = (struct auth_session_info *) 0 ; + struct cli_credentials *arg4 = (struct cli_credentials *) 0 ; + struct hive_key **arg5 = (struct hive_key **) 0 ; + WERROR result; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + void *argp3 = 0 ; + int res3 = 0 ; + void *argp4 = 0 ; + int res4 = 0 ; + struct hive_key *tmp5 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + char * kwnames[] = { + (char *) "location",(char *) "session_info",(char *) "credentials", NULL + }; + + { + arg3 = NULL; + } + { + arg4 = NULL; + } + { + arg1 = NULL; + } + { + arg5 = &tmp5; + } + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OO:Hive",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; + res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Hive" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = (char *)(buf2); + if (obj1) { + res3 = SWIG_ConvertPtr(obj1, &argp3,SWIGTYPE_p_auth_session_info, 0 | 0 ); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "Hive" "', argument " "3"" of type '" "struct auth_session_info *""'"); + } + arg3 = (struct auth_session_info *)(argp3); + } + if (obj2) { + res4 = SWIG_ConvertPtr(obj2, &argp4,SWIGTYPE_p_cli_credentials, 0 | 0 ); + if (!SWIG_IsOK(res4)) { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "Hive" "', argument " "4"" of type '" "struct cli_credentials *""'"); + } + arg4 = (struct cli_credentials *)(argp4); + } + result = reg_open_hive(arg1,(char const *)arg2,arg3,arg4,arg5); + { + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + { + Py_XDECREF(resultobj); + resultobj = SWIG_NewPointerObj(*arg5, SWIGTYPE_p_hive_key, 0); + } + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_hive(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + hive *arg1 = (hive *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + + if (!PyArg_ParseTuple(args,(char *)"O:delete_hive",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_hive_key, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_hive" "', argument " "1"" of type '" "hive *""'"); + } + arg1 = (hive *)(argp1); + delete_hive(arg1); + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_hive(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + hive *result = 0 ; + + if (!PyArg_ParseTuple(args,(char *)":new_hive")) SWIG_fail; + result = (hive *)(hive *) calloc(1, sizeof(hive)); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_hive_key, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *hive_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_hive_key, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; + struct registry_context **arg2 = (struct registry_context **) 0 ; + struct loadparm_context *arg3 = (struct loadparm_context *) 0 ; + struct auth_session_info *arg4 = (struct auth_session_info *) 0 ; + struct cli_credentials *arg5 = (struct cli_credentials *) 0 ; + WERROR result; + struct registry_context *tmp2 ; + void *argp3 = 0 ; + int res3 = 0 ; + void *argp4 = 0 ; + int res4 = 0 ; + void *argp5 = 0 ; + int res5 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + char * kwnames[] = { + (char *) "lp_ctx",(char *) "session_info",(char *) "credentials", NULL + }; + + { + arg4 = NULL; + } + { + arg5 = NULL; + } + { + arg1 = NULL; + } + { + arg2 = &tmp2; + } + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OO:open_samba",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; + res3 = SWIG_ConvertPtr(obj0, &argp3,SWIGTYPE_p_loadparm_context, 0 | 0 ); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "open_samba" "', argument " "3"" of type '" "struct loadparm_context *""'"); + } + arg3 = (struct loadparm_context *)(argp3); + if (obj1) { + res4 = SWIG_ConvertPtr(obj1, &argp4,SWIGTYPE_p_auth_session_info, 0 | 0 ); + if (!SWIG_IsOK(res4)) { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "open_samba" "', argument " "4"" of type '" "struct auth_session_info *""'"); + } + arg4 = (struct auth_session_info *)(argp4); + } + if (obj2) { + res5 = SWIG_ConvertPtr(obj2, &argp5,SWIGTYPE_p_cli_credentials, 0 | 0 ); + if (!SWIG_IsOK(res5)) { + SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "open_samba" "', argument " "5"" of type '" "struct cli_credentials *""'"); + } + arg5 = (struct cli_credentials *)(argp5); + } + result = reg_open_samba(arg1,arg2,arg3,arg4,arg5); + { + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + { + resultobj = SWIG_NewPointerObj(*arg2, SWIGTYPE_p_registry_context, 0); + } + return resultobj; +fail: + return NULL; +} + + +static PyMethodDef SwigMethods[] = { + { (char *)"reg_get_predef_name", (PyCFunction) _wrap_reg_get_predef_name, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"str_regtype", (PyCFunction) _wrap_str_regtype, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"Registry", (PyCFunction) _wrap_Registry, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"delete_reg", _wrap_delete_reg, METH_VARARGS, NULL}, + { (char *)"reg_get_predefined_key_by_name", (PyCFunction) _wrap_reg_get_predefined_key_by_name, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"reg_get_predefined_key", (PyCFunction) _wrap_reg_get_predefined_key, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"reg_apply_patchfile", (PyCFunction) _wrap_reg_apply_patchfile, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"reg_mount_hive", (PyCFunction) _wrap_reg_mount_hive, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"new_reg", _wrap_new_reg, METH_VARARGS, NULL}, + { (char *)"reg_swigregister", reg_swigregister, METH_VARARGS, NULL}, + { (char *)"Hive", (PyCFunction) _wrap_Hive, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"delete_hive", _wrap_delete_hive, METH_VARARGS, NULL}, + { (char *)"new_hive", _wrap_new_hive, METH_VARARGS, NULL}, + { (char *)"hive_swigregister", hive_swigregister, METH_VARARGS, NULL}, + { (char *)"open_samba", (PyCFunction) _wrap_open_samba, METH_VARARGS | METH_KEYWORDS, NULL}, + { NULL, NULL, 0, NULL } +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ + +static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_auth_session_info = {"_p_auth_session_info", "struct auth_session_info *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_cli_credentials = {"_p_cli_credentials", "struct cli_credentials *|cli_credentials *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_hive_key = {"_p_hive_key", "struct hive_key *|hive *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_loadparm_context = {"_p_loadparm_context", "struct loadparm_context *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_p_hive_key = {"_p_p_hive_key", "struct hive_key **", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_p_registry_context = {"_p_p_registry_context", "struct registry_context **", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_p_registry_key = {"_p_p_registry_key", "struct registry_key **", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_registry_context = {"_p_registry_context", "struct registry_context *|reg *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "unsigned char *|uint_least8_t *|uint_fast8_t *|uint8_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_int = {"_p_unsigned_int", "uintptr_t *|uint_least32_t *|uint_fast32_t *|uint32_t *|unsigned int *|uint_fast16_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_long_long = {"_p_unsigned_long_long", "uint_least64_t *|uint_fast64_t *|uint64_t *|unsigned long long *|uintmax_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_short = {"_p_unsigned_short", "unsigned short *|uint_least16_t *|uint16_t *", 0, 0, (void*)0, 0}; + +static swig_type_info *swig_type_initial[] = { + &_swigt__p_TALLOC_CTX, + &_swigt__p_auth_session_info, + &_swigt__p_char, + &_swigt__p_cli_credentials, + &_swigt__p_hive_key, + &_swigt__p_int, + &_swigt__p_loadparm_context, + &_swigt__p_long_long, + &_swigt__p_p_char, + &_swigt__p_p_hive_key, + &_swigt__p_p_registry_context, + &_swigt__p_p_registry_key, + &_swigt__p_registry_context, + &_swigt__p_short, + &_swigt__p_signed_char, + &_swigt__p_unsigned_char, + &_swigt__p_unsigned_int, + &_swigt__p_unsigned_long_long, + &_swigt__p_unsigned_short, +}; + +static swig_cast_info _swigc__p_TALLOC_CTX[] = { {&_swigt__p_TALLOC_CTX, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_auth_session_info[] = { {&_swigt__p_auth_session_info, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_cli_credentials[] = { {&_swigt__p_cli_credentials, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_hive_key[] = { {&_swigt__p_hive_key, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_loadparm_context[] = { {&_swigt__p_loadparm_context, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_p_char[] = { {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_p_hive_key[] = { {&_swigt__p_p_hive_key, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_p_registry_context[] = { {&_swigt__p_p_registry_context, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_p_registry_key[] = { {&_swigt__p_p_registry_key, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_registry_context[] = { {&_swigt__p_registry_context, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_short[] = { {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_signed_char[] = { {&_swigt__p_signed_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_int[] = { {&_swigt__p_unsigned_int, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_long_long[] = { {&_swigt__p_unsigned_long_long, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_short[] = { {&_swigt__p_unsigned_short, 0, 0, 0},{0, 0, 0, 0}}; + +static swig_cast_info *swig_cast_initial[] = { + _swigc__p_TALLOC_CTX, + _swigc__p_auth_session_info, + _swigc__p_char, + _swigc__p_cli_credentials, + _swigc__p_hive_key, + _swigc__p_int, + _swigc__p_loadparm_context, + _swigc__p_long_long, + _swigc__p_p_char, + _swigc__p_p_hive_key, + _swigc__p_p_registry_context, + _swigc__p_p_registry_key, + _swigc__p_registry_context, + _swigc__p_short, + _swigc__p_signed_char, + _swigc__p_unsigned_char, + _swigc__p_unsigned_int, + _swigc__p_unsigned_long_long, + _swigc__p_unsigned_short, +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ + +static swig_const_info swig_const_table[] = { +{0, 0, 0, 0.0, 0, 0}}; + +#ifdef __cplusplus +} +#endif +/* ----------------------------------------------------------------------------- + * Type initialization: + * This problem is tough by the requirement that no dynamic + * memory is used. Also, since swig_type_info structures store pointers to + * swig_cast_info structures and swig_cast_info structures store pointers back + * to swig_type_info structures, we need some lookup code at initialization. + * The idea is that swig generates all the structures that are needed. + * The runtime then collects these partially filled structures. + * The SWIG_InitializeModule function takes these initial arrays out of + * swig_module, and does all the lookup, filling in the swig_module.types + * array with the correct data and linking the correct swig_cast_info + * structures together. + * + * The generated swig_type_info structures are assigned staticly to an initial + * array. We just loop through that array, and handle each type individually. + * First we lookup if this type has been already loaded, and if so, use the + * loaded structure instead of the generated one. Then we have to fill in the + * cast linked list. The cast data is initially stored in something like a + * two-dimensional array. Each row corresponds to a type (there are the same + * number of rows as there are in the swig_type_initial array). Each entry in + * a column is one of the swig_cast_info structures for that type. + * The cast_initial array is actually an array of arrays, because each row has + * a variable number of columns. So to actually build the cast linked list, + * we find the array of casts associated with the type, and loop through it + * adding the casts to the list. The one last trick we need to do is making + * sure the type pointer in the swig_cast_info struct is correct. + * + * First off, we lookup the cast->type name to see if it is already loaded. + * There are three cases to handle: + * 1) If the cast->type has already been loaded AND the type we are adding + * casting info to has not been loaded (it is in this module), THEN we + * replace the cast->type pointer with the type pointer that has already + * been loaded. + * 2) If BOTH types (the one we are adding casting info to, and the + * cast->type) are loaded, THEN the cast info has already been loaded by + * the previous module so we just ignore it. + * 3) Finally, if cast->type has not already been loaded, then we add that + * swig_cast_info to the linked list (because the cast->type) pointer will + * be correct. + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* c-mode */ +#endif +#endif + +#if 0 +#define SWIGRUNTIME_DEBUG +#endif + + +SWIGRUNTIME void +SWIG_InitializeModule(void *clientdata) { + size_t i; + swig_module_info *module_head, *iter; + int found; + + clientdata = clientdata; + + /* check to see if the circular list has been setup, if not, set it up */ + if (swig_module.next==0) { + /* Initialize the swig_module */ + swig_module.type_initial = swig_type_initial; + swig_module.cast_initial = swig_cast_initial; + swig_module.next = &swig_module; + } + + /* Try and load any already created modules */ + module_head = SWIG_GetModule(clientdata); + if (!module_head) { + /* This is the first module loaded for this interpreter */ + /* so set the swig module into the interpreter */ + SWIG_SetModule(clientdata, &swig_module); + module_head = &swig_module; + } else { + /* the interpreter has loaded a SWIG module, but has it loaded this one? */ + found=0; + iter=module_head; + do { + if (iter==&swig_module) { + found=1; + break; + } + iter=iter->next; + } while (iter!= module_head); + + /* if the is found in the list, then all is done and we may leave */ + if (found) return; + /* otherwise we must add out module into the list */ + swig_module.next = module_head->next; + module_head->next = &swig_module; + } + + /* Now work on filling in swig_module.types */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: size %d\n", swig_module.size); +#endif + for (i = 0; i < swig_module.size; ++i) { + swig_type_info *type = 0; + swig_type_info *ret; + swig_cast_info *cast; + +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); +#endif + + /* if there is another module already loaded */ + if (swig_module.next != &swig_module) { + type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); + } + if (type) { + /* Overwrite clientdata field */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found type %s\n", type->name); +#endif + if (swig_module.type_initial[i]->clientdata) { + type->clientdata = swig_module.type_initial[i]->clientdata; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); +#endif + } + } else { + type = swig_module.type_initial[i]; + } + + /* Insert casting types */ + cast = swig_module.cast_initial[i]; + while (cast->type) { + /* Don't need to add information already in the list */ + ret = 0; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); +#endif + if (swig_module.next != &swig_module) { + ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); +#ifdef SWIGRUNTIME_DEBUG + if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); +#endif + } + if (ret) { + if (type == swig_module.type_initial[i]) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: skip old type %s\n", ret->name); +#endif + cast->type = ret; + ret = 0; + } else { + /* Check for casting already in the list */ + swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); +#ifdef SWIGRUNTIME_DEBUG + if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); +#endif + if (!ocast) ret = 0; + } + } + + if (!ret) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); +#endif + if (type->cast) { + type->cast->prev = cast; + cast->next = type->cast; + } + type->cast = cast; + } + cast++; + } + /* Set entry in modules->types array equal to the type */ + swig_module.types[i] = type; + } + swig_module.types[i] = 0; + +#ifdef SWIGRUNTIME_DEBUG + printf("**** SWIG_InitializeModule: Cast List ******\n"); + for (i = 0; i < swig_module.size; ++i) { + int j = 0; + swig_cast_info *cast = swig_module.cast_initial[i]; + printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); + while (cast->type) { + printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); + cast++; + ++j; + } + printf("---- Total casts: %d\n",j); + } + printf("**** SWIG_InitializeModule: Cast List ******\n"); +#endif +} + +/* This function will propagate the clientdata field of type to +* any new swig_type_info structures that have been added into the list +* of equivalent types. It is like calling +* SWIG_TypeClientData(type, clientdata) a second time. +*/ +SWIGRUNTIME void +SWIG_PropagateClientData(void) { + size_t i; + swig_cast_info *equiv; + static int init_run = 0; + + if (init_run) return; + init_run = 1; + + for (i = 0; i < swig_module.size; i++) { + if (swig_module.types[i]->clientdata) { + equiv = swig_module.types[i]->cast; + while (equiv) { + if (!equiv->converter) { + if (equiv->type && !equiv->type->clientdata) + SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); + } + equiv = equiv->next; + } + } + } +} + +#ifdef __cplusplus +#if 0 +{ + /* c-mode */ +#endif +} +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + /* Python-specific SWIG API */ +#define SWIG_newvarlink() SWIG_Python_newvarlink() +#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr) +#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants) + + /* ----------------------------------------------------------------------------- + * global variable support code. + * ----------------------------------------------------------------------------- */ + + typedef struct swig_globalvar { + char *name; /* Name of global variable */ + PyObject *(*get_attr)(void); /* Return the current value */ + int (*set_attr)(PyObject *); /* Set the value */ + struct swig_globalvar *next; + } swig_globalvar; + + typedef struct swig_varlinkobject { + PyObject_HEAD + swig_globalvar *vars; + } swig_varlinkobject; + + SWIGINTERN PyObject * + swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) { + return PyString_FromString(""); + } + + SWIGINTERN PyObject * + swig_varlink_str(swig_varlinkobject *v) { + PyObject *str = PyString_FromString("("); + swig_globalvar *var; + for (var = v->vars; var; var=var->next) { + PyString_ConcatAndDel(&str,PyString_FromString(var->name)); + if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", ")); + } + PyString_ConcatAndDel(&str,PyString_FromString(")")); + return str; + } + + SWIGINTERN int + swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) { + PyObject *str = swig_varlink_str(v); + fprintf(fp,"Swig global variables "); + fprintf(fp,"%s\n", PyString_AsString(str)); + Py_DECREF(str); + return 0; + } + + SWIGINTERN void + swig_varlink_dealloc(swig_varlinkobject *v) { + swig_globalvar *var = v->vars; + while (var) { + swig_globalvar *n = var->next; + free(var->name); + free(var); + var = n; + } + } + + SWIGINTERN PyObject * + swig_varlink_getattr(swig_varlinkobject *v, char *n) { + PyObject *res = NULL; + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + res = (*var->get_attr)(); + break; + } + var = var->next; + } + if (res == NULL && !PyErr_Occurred()) { + PyErr_SetString(PyExc_NameError,"Unknown C global variable"); + } + return res; + } + + SWIGINTERN int + swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { + int res = 1; + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + res = (*var->set_attr)(p); + break; + } + var = var->next; + } + if (res == 1 && !PyErr_Occurred()) { + PyErr_SetString(PyExc_NameError,"Unknown C global variable"); + } + return res; + } + + SWIGINTERN PyTypeObject* + swig_varlink_type(void) { + static char varlink__doc__[] = "Swig var link object"; + static PyTypeObject varlink_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + PyObject_HEAD_INIT(NULL) + 0, /* Number of items in variable part (ob_size) */ + (char *)"swigvarlink", /* Type name (tp_name) */ + sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */ + 0, /* Itemsize (tp_itemsize) */ + (destructor) swig_varlink_dealloc, /* Deallocator (tp_dealloc) */ + (printfunc) swig_varlink_print, /* Print (tp_print) */ + (getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */ + (setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */ + 0, /* tp_compare */ + (reprfunc) swig_varlink_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)swig_varlink_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + varlink__doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + varlink_type = tmp; + varlink_type.ob_type = &PyType_Type; + type_init = 1; + } + return &varlink_type; + } + + /* Create a variable linking object for use later */ + SWIGINTERN PyObject * + SWIG_Python_newvarlink(void) { + swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type()); + if (result) { + result->vars = 0; + } + return ((PyObject*) result); + } + + SWIGINTERN void + SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { + swig_varlinkobject *v = (swig_varlinkobject *) p; + swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); + if (gv) { + size_t size = strlen(name)+1; + gv->name = (char *)malloc(size); + if (gv->name) { + strncpy(gv->name,name,size); + gv->get_attr = get_attr; + gv->set_attr = set_attr; + gv->next = v->vars; + } + } + v->vars = gv; + } + + SWIGINTERN PyObject * + SWIG_globals(void) { + static PyObject *_SWIG_globals = 0; + if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink(); + return _SWIG_globals; + } + + /* ----------------------------------------------------------------------------- + * constants/methods manipulation + * ----------------------------------------------------------------------------- */ + + /* Install Constants */ + SWIGINTERN void + SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { + PyObject *obj = 0; + size_t i; + for (i = 0; constants[i].type; ++i) { + switch(constants[i].type) { + case SWIG_PY_POINTER: + obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); + break; + case SWIG_PY_BINARY: + obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); + break; + default: + obj = 0; + break; + } + if (obj) { + PyDict_SetItemString(d, constants[i].name, obj); + Py_DECREF(obj); + } + } + } + + /* -----------------------------------------------------------------------------*/ + /* Fix SwigMethods to carry the callback ptrs when needed */ + /* -----------------------------------------------------------------------------*/ + + SWIGINTERN void + SWIG_Python_FixMethods(PyMethodDef *methods, + swig_const_info *const_table, + swig_type_info **types, + swig_type_info **types_initial) { + size_t i; + for (i = 0; methods[i].ml_name; ++i) { + const char *c = methods[i].ml_doc; + if (c && (c = strstr(c, "swig_ptr: "))) { + int j; + swig_const_info *ci = 0; + const char *name = c + 10; + for (j = 0; const_table[j].type; ++j) { + if (strncmp(const_table[j].name, name, + strlen(const_table[j].name)) == 0) { + ci = &(const_table[j]); + break; + } + } + if (ci) { + size_t shift = (ci->ptype) - types; + swig_type_info *ty = types_initial[shift]; + size_t ldoc = (c - methods[i].ml_doc); + size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; + char *ndoc = (char*)malloc(ldoc + lptr + 10); + if (ndoc) { + char *buff = ndoc; + void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; + if (ptr) { + strncpy(buff, methods[i].ml_doc, ldoc); + buff += ldoc; + strncpy(buff, "swig_ptr: ", 10); + buff += 10; + SWIG_PackVoidPtr(buff, ptr, ty->name, lptr); + methods[i].ml_doc = ndoc; + } + } + } + } + } + } + +#ifdef __cplusplus +} +#endif + +/* -----------------------------------------------------------------------------* + * Partial Init method + * -----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" +#endif +SWIGEXPORT void SWIG_init(void) { + PyObject *m, *d; + + /* Fix SwigMethods to carry the callback ptrs when needed */ + SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial); + + m = Py_InitModule((char *) SWIG_name, SwigMethods); + d = PyModule_GetDict(m); + + SWIG_InitializeModule(0); + SWIG_InstallConstants(d,swig_const_table); + + + SWIG_Python_SetConstant(d, "HKEY_CLASSES_ROOT",SWIG_From_unsigned_SS_int((unsigned int)(HKEY_CLASSES_ROOT))); + SWIG_Python_SetConstant(d, "HKEY_CURRENT_USER",SWIG_From_unsigned_SS_int((unsigned int)(HKEY_CURRENT_USER))); + SWIG_Python_SetConstant(d, "HKEY_LOCAL_MACHINE",SWIG_From_unsigned_SS_int((unsigned int)(HKEY_LOCAL_MACHINE))); + SWIG_Python_SetConstant(d, "HKEY_USERS",SWIG_From_unsigned_SS_int((unsigned int)(HKEY_USERS))); + SWIG_Python_SetConstant(d, "HKEY_PERFORMANCE_DATA",SWIG_From_unsigned_SS_int((unsigned int)(HKEY_PERFORMANCE_DATA))); + SWIG_Python_SetConstant(d, "HKEY_CURRENT_CONFIG",SWIG_From_unsigned_SS_int((unsigned int)(HKEY_CURRENT_CONFIG))); + SWIG_Python_SetConstant(d, "HKEY_DYN_DATA",SWIG_From_unsigned_SS_int((unsigned int)(HKEY_DYN_DATA))); + SWIG_Python_SetConstant(d, "HKEY_PERFORMANCE_TEXT",SWIG_From_unsigned_SS_int((unsigned int)(HKEY_PERFORMANCE_TEXT))); + SWIG_Python_SetConstant(d, "HKEY_PERFORMANCE_NLSTEXT",SWIG_From_unsigned_SS_int((unsigned int)(HKEY_PERFORMANCE_NLSTEXT))); +} + -- cgit From cb7c72a0ef9a8e6d145ead6286e54ec50ddf3988 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 17:58:04 +0100 Subject: r26263: Don't assume CH_UNIX is CH_UTF8. (This used to be commit 69157be9b180e4d82a66257afb5f774ef16cea89) --- source4/lib/registry/ldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index fdd4c27599..6ce422049b 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -85,7 +85,7 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, switch (type) { case REG_SZ: case REG_EXPAND_SZ: - val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8, + val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, (void *)data.data, data.length, (void **)&val.data); -- cgit From 39ee38d9c1aabf4db065b433d067d0da053d7d61 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 6 Dec 2007 17:52:23 +0100 Subject: r26316: Use contexts for conversion functions. (This used to be commit f6420d933b5b011d428974f3a2a57edf19e6f482) --- source4/lib/registry/ldb.c | 4 ++-- source4/lib/registry/patchfile_preg.c | 2 +- source4/lib/registry/tests/generic.c | 6 +++--- source4/lib/registry/util.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 6ce422049b..0e556da9e2 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -54,7 +54,7 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, { case REG_SZ: case REG_EXPAND_SZ: - data->length = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, + data->length = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF8, CH_UTF16, val->data, val->length, (void **)&data->data); break; @@ -85,7 +85,7 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, switch (type) { case REG_SZ: case REG_EXPAND_SZ: - val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, + val.length = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF16, CH_UNIX, (void *)data.data, data.length, (void **)&val.data); diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c index 90a4f2529a..6af239fc21 100644 --- a/source4/lib/registry/patchfile_preg.c +++ b/source4/lib/registry/patchfile_preg.c @@ -36,7 +36,7 @@ static WERROR preg_read_utf16(int fd, char *c) if (read(fd, &v, 2) < 2) { return WERR_GENERAL_FAILURE; } - push_codepoint(c, v); + push_codepoint(global_smb_iconv_convenience, c, v); return WERR_OK; } diff --git a/source4/lib/registry/tests/generic.c b/source4/lib/registry/tests/generic.c index 13e27cd80b..1acb6342e7 100644 --- a/source4/lib/registry/tests/generic.c +++ b/source4/lib/registry/tests/generic.c @@ -52,7 +52,7 @@ static bool test_reg_val_data_string_dword(struct torture_context *ctx) static bool test_reg_val_data_string_sz(struct torture_context *ctx) { DATA_BLOB db; - db.length = convert_string_talloc(ctx, CH_UNIX, CH_UTF16, + db.length = convert_string_talloc(ctx, global_smb_iconv_convenience, CH_UNIX, CH_UTF16, "bla", 3, (void **)&db.data); torture_assert_str_equal(ctx, "bla", reg_val_data_string(ctx, REG_SZ, db), @@ -87,7 +87,7 @@ static bool test_reg_val_data_string_empty(struct torture_context *ctx) static bool test_reg_val_description(struct torture_context *ctx) { DATA_BLOB data; - data.length = convert_string_talloc(ctx, CH_UNIX, CH_UTF16, + data.length = convert_string_talloc(ctx, global_smb_iconv_convenience, CH_UNIX, CH_UTF16, "stationary traveller", strlen("stationary traveller"), (void **)&data.data); @@ -101,7 +101,7 @@ static bool test_reg_val_description(struct torture_context *ctx) static bool test_reg_val_description_nullname(struct torture_context *ctx) { DATA_BLOB data; - data.length = convert_string_talloc(ctx, CH_UNIX, CH_UTF16, + data.length = convert_string_talloc(ctx, global_smb_iconv_convenience, CH_UNIX, CH_UTF16, "west berlin", strlen("west berlin"), (void **)&data.data); diff --git a/source4/lib/registry/util.c b/source4/lib/registry/util.c index ca3e3dd619..f75fc835b5 100644 --- a/source4/lib/registry/util.c +++ b/source4/lib/registry/util.c @@ -61,7 +61,7 @@ _PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, switch (type) { case REG_EXPAND_SZ: case REG_SZ: - convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, + convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF16, CH_UNIX, data.data, data.length, (void **)&ret); return ret; @@ -117,7 +117,7 @@ _PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, { case REG_SZ: case REG_EXPAND_SZ: - data->length = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, + data->length = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UNIX, CH_UTF16, data_str, strlen(data_str), (void **)&data->data); break; -- cgit From 4c4323009fa83f00ed319de59a3aad48fcd65994 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Dec 2007 02:37:04 +0100 Subject: r26327: Explicit loadparm_context for RPC client functions. (This used to be commit eeb2251d22b3d6e0379444a73af69d1014692b07) --- source4/lib/registry/registry.h | 1 + source4/lib/registry/rpc.c | 3 ++- source4/lib/registry/tools/regdiff.c | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index c53e3dfbe5..edd6c6713f 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -186,6 +186,7 @@ WERROR reg_open_samba(TALLOC_CTX *mem_ctx, WERROR reg_open_remote(struct registry_context **ctx, struct auth_session_info *session_info, struct cli_credentials *credentials, + struct loadparm_context *lp_ctx, const char *location, struct event_context *ev); WERROR reg_open_wine(struct registry_context **ctx, const char *path); diff --git a/source4/lib/registry/rpc.c b/source4/lib/registry/rpc.c index c694223909..ac0eecd0ac 100644 --- a/source4/lib/registry/rpc.c +++ b/source4/lib/registry/rpc.c @@ -375,6 +375,7 @@ static struct registry_operations reg_backend_rpc = { _PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, struct auth_session_info *session_info, struct cli_credentials *credentials, + struct loadparm_context *lp_ctx, const char *location, struct event_context *ev) { NTSTATUS status; @@ -393,7 +394,7 @@ _PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, status = dcerpc_pipe_connect(*ctx /* TALLOC_CTX */, &p, location, &ndr_table_winreg, - credentials, ev); + credentials, ev, lp_ctx); rctx->pipe = p; if(NT_STATUS_IS_ERR(status)) { diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 1996861a2a..ea4b754fe7 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -44,7 +44,7 @@ static struct registry_context *open_backend(poptContext pc, error = reg_open_samba(NULL, &ctx, lp_ctx, NULL, cmdline_credentials); break; case REG_REMOTE: - error = reg_open_remote(&ctx, NULL, cmdline_credentials, + error = reg_open_remote(&ctx, NULL, cmdline_credentials, lp_ctx, remote_host, NULL); break; case REG_NULL: -- cgit From bca631be1f4cefeec3d64cd552ec6d9ee9cc1971 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Dec 2007 03:01:41 +0100 Subject: r26329: Fix more loadparm_context references. Only about a 100 left now. (This used to be commit ddf233346d848e91bc6a6a572f0f6120540503b7) --- source4/lib/registry/tools/common.c | 3 ++- source4/lib/registry/tools/regpatch.c | 2 +- source4/lib/registry/tools/regshell.c | 2 +- source4/lib/registry/tools/regtree.c | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/common.c b/source4/lib/registry/tools/common.c index 6d766fd25c..c9293cd310 100644 --- a/source4/lib/registry/tools/common.c +++ b/source4/lib/registry/tools/common.c @@ -24,12 +24,13 @@ #include "lib/registry/tools/common.h" struct registry_context *reg_common_open_remote(const char *remote, + struct loadparm_context *lp_ctx, struct cli_credentials *creds) { struct registry_context *h; WERROR error; - error = reg_open_remote(&h, NULL, creds, remote, NULL); + error = reg_open_remote(&h, NULL, creds, lp_ctx, remote, NULL); if (!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open remote registry at %s:%s \n", diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 2f2cf789a9..441138832e 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -49,7 +49,7 @@ int main(int argc, char **argv) } if (remote) { - h = reg_common_open_remote (remote, cmdline_credentials); + h = reg_common_open_remote (remote, global_loadparm, cmdline_credentials); } else { h = reg_common_open_local (cmdline_credentials, global_loadparm); } diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 9b582c3c02..7169d7c9f8 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -497,7 +497,7 @@ int main(int argc, char **argv) ctx = talloc_zero(NULL, struct regshell_context); if (remote != NULL) { - ctx->registry = reg_common_open_remote(remote, + ctx->registry = reg_common_open_remote(remote, global_loadparm, cmdline_credentials); } else if (file != NULL) { ctx->current = reg_common_open_file(file, cmdline_credentials); diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index f95fc1968d..6c21f2cbad 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -129,7 +129,7 @@ int main(int argc, char **argv) } if (remote != NULL) { - h = reg_common_open_remote(remote, cmdline_credentials); + h = reg_common_open_remote(remote, global_loadparm, cmdline_credentials); } else if (file != NULL) { start_key = reg_common_open_file(file, cmdline_credentials); } else { -- cgit From b65dba2245bf382c47d65c95ac9b1efa43918fc0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 04:33:16 +0100 Subject: r26355: Eliminate global_loadparm in more places. (This used to be commit 5d589a0d94bd76a9b4c9fc748854e8098ea43c4d) --- source4/lib/registry/tools/regdiff.c | 4 ++-- source4/lib/registry/tools/regpatch.c | 4 ++-- source4/lib/registry/tools/regshell.c | 4 ++-- source4/lib/registry/tools/regtree.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index ea4b754fe7..406eaeea3d 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -116,11 +116,11 @@ int main(int argc, const char **argv) } - h1 = open_backend(pc, global_loadparm, backend1, remote1); + h1 = open_backend(pc, cmdline_lp_ctx, backend1, remote1); if (h1 == NULL) return 1; - h2 = open_backend(pc, global_loadparm, backend2, remote2); + h2 = open_backend(pc, cmdline_lp_ctx, backend2, remote2); if (h2 == NULL) return 1; diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 441138832e..ddbedce18a 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -49,9 +49,9 @@ int main(int argc, char **argv) } if (remote) { - h = reg_common_open_remote (remote, global_loadparm, cmdline_credentials); + h = reg_common_open_remote (remote, cmdline_lp_ctx, cmdline_credentials); } else { - h = reg_common_open_local (cmdline_credentials, global_loadparm); + h = reg_common_open_local (cmdline_credentials, cmdline_lp_ctx); } if (h == NULL) diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 7169d7c9f8..2c692952fb 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -497,7 +497,7 @@ int main(int argc, char **argv) ctx = talloc_zero(NULL, struct regshell_context); if (remote != NULL) { - ctx->registry = reg_common_open_remote(remote, global_loadparm, + ctx->registry = reg_common_open_remote(remote, cmdline_lp_ctx, cmdline_credentials); } else if (file != NULL) { ctx->current = reg_common_open_file(file, cmdline_credentials); @@ -506,7 +506,7 @@ int main(int argc, char **argv) ctx->registry = ctx->current->context; ctx->path = talloc_strdup(ctx, ""); } else { - ctx->registry = reg_common_open_local(cmdline_credentials, global_loadparm); + ctx->registry = reg_common_open_local(cmdline_credentials, cmdline_lp_ctx); } if (ctx->registry == NULL) diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 6c21f2cbad..b267e11b43 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -129,11 +129,11 @@ int main(int argc, char **argv) } if (remote != NULL) { - h = reg_common_open_remote(remote, global_loadparm, cmdline_credentials); + h = reg_common_open_remote(remote, cmdline_lp_ctx, cmdline_credentials); } else if (file != NULL) { start_key = reg_common_open_file(file, cmdline_credentials); } else { - h = reg_common_open_local(cmdline_credentials, global_loadparm); + h = reg_common_open_local(cmdline_credentials, cmdline_lp_ctx); } if (h == NULL && start_key == NULL) -- cgit From a46d8933d679846a5316529e3bed7ef369adc6cb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 10:29:35 +0100 Subject: r26372: Add include for external users. (This used to be commit 621feaa3d5c5dc6ca5078c2d8f32cc54235b7515) --- source4/lib/registry/hive.h | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/hive.h b/source4/lib/registry/hive.h index 2f783dd15d..d8e20d4aa2 100644 --- a/source4/lib/registry/hive.h +++ b/source4/lib/registry/hive.h @@ -22,6 +22,7 @@ #define __REGISTRY_HIVE_H__ #include +#include "libcli/util/werror.h" #include "librpc/gen_ndr/security.h" #include "libcli/util/ntstatus.h" -- cgit From 68dc2dc526e146dd0ac68d5d68eb55b601282caf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 11 Dec 2007 14:31:01 +0100 Subject: r26399: Use -O option for SWIG (less evil generated code). (This used to be commit 3378b6a559272cb702b52966692bf423f67a2b41) --- source4/lib/registry/registry.py | 43 +++++++++++++--------------- source4/lib/registry/registry_wrap.c | 55 ++++++++++++++++++++++++++---------- 2 files changed, 60 insertions(+), 38 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.py b/source4/lib/registry/registry.py index b61d713df8..4e3d48a18c 100644 --- a/source4/lib/registry/registry.py +++ b/source4/lib/registry/registry.py @@ -2,7 +2,6 @@ # Version 1.3.33 # # Don't modify this file, modify the SWIG interface instead. -# This file is compatible with both classic and new-style classes. import _registry import new @@ -48,45 +47,43 @@ except AttributeError: del types +def _swig_setattr_nondynamic_method(set): + def set_attr(self,name,value): + if (name == "thisown"): return self.this.own(value) + if hasattr(self,name) or (name == "this"): + set(self,name,value) + else: + raise AttributeError("You cannot add attributes to %s" % self) + return set_attr + + import credentials reg_get_predef_name = _registry.reg_get_predef_name str_regtype = _registry.str_regtype Registry = _registry.Registry -class reg(_object): - __swig_setmethods__ = {} - __setattr__ = lambda self, name, value: _swig_setattr(self, reg, name, value) - __swig_getmethods__ = {} - __getattr__ = lambda self, name: _swig_getattr(self, reg, name) +class reg(object): + thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') __repr__ = _swig_repr __swig_destroy__ = _registry.delete_reg - __del__ = lambda self : None; - def get_predefined_key_by_name(*args, **kwargs): return _registry.reg_get_predefined_key_by_name(*args, **kwargs) - def get_predefined_key(*args, **kwargs): return _registry.reg_get_predefined_key(*args, **kwargs) - def apply_patchfile(*args, **kwargs): return _registry.reg_apply_patchfile(*args, **kwargs) - def mount_hive(*args, **kwargs): return _registry.reg_mount_hive(*args, **kwargs) def mount(self, path, hkey_id, elements=[]): self.mount_hive(Hive(path), hkey_id, elements) def __init__(self, *args, **kwargs): - this = _registry.new_reg(*args, **kwargs) - try: self.this.append(this) - except: self.this = this + _registry.reg_swiginit(self,_registry.new_reg(*args, **kwargs)) +reg.get_predefined_key_by_name = new_instancemethod(_registry.reg_get_predefined_key_by_name,None,reg) +reg.get_predefined_key = new_instancemethod(_registry.reg_get_predefined_key,None,reg) +reg.apply_patchfile = new_instancemethod(_registry.reg_apply_patchfile,None,reg) +reg.mount_hive = new_instancemethod(_registry.reg_mount_hive,None,reg) reg_swigregister = _registry.reg_swigregister reg_swigregister(reg) Hive = _registry.Hive -class hive(_object): - __swig_setmethods__ = {} - __setattr__ = lambda self, name, value: _swig_setattr(self, hive, name, value) - __swig_getmethods__ = {} - __getattr__ = lambda self, name: _swig_getattr(self, hive, name) +class hive(object): + thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') __repr__ = _swig_repr __swig_destroy__ = _registry.delete_hive - __del__ = lambda self : None; def __init__(self, *args, **kwargs): - this = _registry.new_hive(*args, **kwargs) - try: self.this.append(this) - except: self.this = this + _registry.hive_swiginit(self,_registry.new_hive(*args, **kwargs)) hive_swigregister = _registry.hive_swigregister hive_swigregister(hive) diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index 3ab0af10b5..15c27a8f6c 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -9,7 +9,7 @@ * ----------------------------------------------------------------------------- */ #define SWIGPYTHON -#define SWIG_PYTHON_DIRECTOR_NO_VTABLE +#define SWIG_PYTHON_NO_BUILD_NONE /* ----------------------------------------------------------------------------- * This section contains generic SWIG labels for method/variable * declarations/attributes, and other compiler dependent labels. @@ -2487,6 +2487,19 @@ static swig_module_info swig_module = {swig_types, 19, 0, 0, 0, 0}; # error "This python version requires swig to be run with the '-classic' option" # endif #endif +#if (PY_VERSION_HEX <= 0x02020000) +# error "This python version requires swig to be run with the '-nomodern' option" +#endif +#if (PY_VERSION_HEX <= 0x02020000) +# error "This python version requires swig to be run with the '-nomodernargs' option" +#endif +#ifndef METH_O +# error "This python version requires swig to be run with the '-nofastunpack' option" +#endif +#ifdef SWIG_TypeQuery +# undef SWIG_TypeQuery +#endif +#define SWIG_TypeQuery SWIG_Python_TypeQuery /*----------------------------------------------- @(target):= _registry.so @@ -2954,10 +2967,11 @@ SWIGINTERN PyObject *_wrap_delete_reg(PyObject *SWIGUNUSEDPARM(self), PyObject * reg *arg1 = (reg *) 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:delete_reg",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, SWIG_POINTER_DISOWN | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_registry_context, SWIG_POINTER_DISOWN | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_reg" "', argument " "1"" of type '" "reg *""'"); } @@ -3204,7 +3218,7 @@ SWIGINTERN PyObject *_wrap_new_reg(PyObject *SWIGUNUSEDPARM(self), PyObject *arg PyObject *resultobj = 0; reg *result = 0 ; - if (!PyArg_ParseTuple(args,(char *)":new_reg")) SWIG_fail; + if (!SWIG_Python_UnpackTuple(args,"new_reg",0,0,0)) SWIG_fail; result = (reg *)(reg *) calloc(1, sizeof(reg)); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_registry_context, SWIG_POINTER_NEW | 0 ); return resultobj; @@ -3215,11 +3229,15 @@ fail: SWIGINTERN PyObject *reg_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; - if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; SWIG_TypeNewClientData(SWIGTYPE_p_registry_context, SWIG_NewClientData(obj)); return SWIG_Py_Void(); } +SWIGINTERN PyObject *reg_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + SWIGINTERN PyObject *_wrap_Hive(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; @@ -3301,10 +3319,11 @@ SWIGINTERN PyObject *_wrap_delete_hive(PyObject *SWIGUNUSEDPARM(self), PyObject hive *arg1 = (hive *) 0 ; void *argp1 = 0 ; int res1 = 0 ; - PyObject * obj0 = 0 ; + PyObject *swig_obj[1] ; - if (!PyArg_ParseTuple(args,(char *)"O:delete_hive",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_hive_key, SWIG_POINTER_DISOWN | 0 ); + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_hive_key, SWIG_POINTER_DISOWN | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_hive" "', argument " "1"" of type '" "hive *""'"); } @@ -3322,7 +3341,7 @@ SWIGINTERN PyObject *_wrap_new_hive(PyObject *SWIGUNUSEDPARM(self), PyObject *ar PyObject *resultobj = 0; hive *result = 0 ; - if (!PyArg_ParseTuple(args,(char *)":new_hive")) SWIG_fail; + if (!SWIG_Python_UnpackTuple(args,"new_hive",0,0,0)) SWIG_fail; result = (hive *)(hive *) calloc(1, sizeof(hive)); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_hive_key, SWIG_POINTER_NEW | 0 ); return resultobj; @@ -3333,11 +3352,15 @@ fail: SWIGINTERN PyObject *hive_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; - if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL; + if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; SWIG_TypeNewClientData(SWIGTYPE_p_hive_key, SWIG_NewClientData(obj)); return SWIG_Py_Void(); } +SWIGINTERN PyObject *hive_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; @@ -3414,17 +3437,19 @@ static PyMethodDef SwigMethods[] = { { (char *)"reg_get_predef_name", (PyCFunction) _wrap_reg_get_predef_name, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"str_regtype", (PyCFunction) _wrap_str_regtype, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"Registry", (PyCFunction) _wrap_Registry, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"delete_reg", _wrap_delete_reg, METH_VARARGS, NULL}, + { (char *)"delete_reg", (PyCFunction)_wrap_delete_reg, METH_O, NULL}, { (char *)"reg_get_predefined_key_by_name", (PyCFunction) _wrap_reg_get_predefined_key_by_name, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"reg_get_predefined_key", (PyCFunction) _wrap_reg_get_predefined_key, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"reg_apply_patchfile", (PyCFunction) _wrap_reg_apply_patchfile, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"reg_mount_hive", (PyCFunction) _wrap_reg_mount_hive, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"new_reg", _wrap_new_reg, METH_VARARGS, NULL}, + { (char *)"new_reg", (PyCFunction)_wrap_new_reg, METH_NOARGS, NULL}, { (char *)"reg_swigregister", reg_swigregister, METH_VARARGS, NULL}, + { (char *)"reg_swiginit", reg_swiginit, METH_VARARGS, NULL}, { (char *)"Hive", (PyCFunction) _wrap_Hive, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"delete_hive", _wrap_delete_hive, METH_VARARGS, NULL}, - { (char *)"new_hive", _wrap_new_hive, METH_VARARGS, NULL}, + { (char *)"delete_hive", (PyCFunction)_wrap_delete_hive, METH_O, NULL}, + { (char *)"new_hive", (PyCFunction)_wrap_new_hive, METH_NOARGS, NULL}, { (char *)"hive_swigregister", hive_swigregister, METH_VARARGS, NULL}, + { (char *)"hive_swiginit", hive_swiginit, METH_VARARGS, NULL}, { (char *)"open_samba", (PyCFunction) _wrap_open_samba, METH_VARARGS | METH_KEYWORDS, NULL}, { NULL, NULL, 0, NULL } }; -- cgit From 46b54defe9ae60646ba0a85dc67a1dcf65b0ed83 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Tue, 11 Dec 2007 23:00:30 +0100 Subject: r26407: Janitorial: Remove a pstring and compiler warnings. (This used to be commit bdc482033546e3986bf8c8b65dbf11c54dc57b8e) --- source4/lib/registry/patchfile_preg.c | 73 ++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 36 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c index 6af239fc21..47bd160c54 100644 --- a/source4/lib/registry/patchfile_preg.c +++ b/source4/lib/registry/patchfile_preg.c @@ -23,7 +23,6 @@ #include "lib/registry/registry.h" #include "lib/registry/patchfile.h" #include "system/filesys.h" -#include "pstring.h" struct preg_data { int fd; @@ -43,13 +42,11 @@ static WERROR preg_read_utf16(int fd, char *c) /* FIXME These functions need to be implemented */ static WERROR reg_preg_diff_add_key(void *_data, const char *key_name) { - struct preg_data *data = (struct preg_data *)_data; return WERR_OK; } static WERROR reg_preg_diff_del_key(void *_data, const char *key_name) { - struct preg_data *data = (struct preg_data *)_data; return WERR_OK; } @@ -57,20 +54,17 @@ static WERROR reg_preg_diff_set_value(void *_data, const char *key_name, const char *value_name, uint32_t value_type, DATA_BLOB value_data) { - struct preg_data *data = (struct preg_data *)_data; return WERR_OK; } static WERROR reg_preg_diff_del_value(void *_data, const char *key_name, const char *value_name) { - struct preg_data *data = (struct preg_data *)_data; return WERR_OK; } static WERROR reg_preg_diff_del_all_values(void *_data, const char *key_name) { - struct preg_data *data = (struct preg_data *)_data; return WERR_OK; } @@ -135,22 +129,29 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, char hdr[4]; uint32_t version; } preg_header; - pstring buf; - char *buf_ptr = buf; + char *buf; + size_t buf_size = 1024; + char *buf_ptr; TALLOC_CTX *mem_ctx = talloc_init("reg_preg_diff_load"); + WERROR ret = WERR_OK; + DATA_BLOB data = {NULL, 0}; + char *key = NULL; + char *value_name = NULL; + buf = talloc_array(mem_ctx, char, buf_size); + buf_ptr = buf; /* Read first 8 bytes (the header) */ if (read(fd, &preg_header, 8) != 8) { DEBUG(0, ("Could not read PReg file: %s\n", strerror(errno))); - close(fd); - return WERR_GENERAL_FAILURE; + ret = WERR_GENERAL_FAILURE; + goto cleanup; } if (strncmp(preg_header.hdr, "PReg", 4) != 0) { DEBUG(0, ("This file is not a valid preg registry file\n")); - close(fd); - return WERR_GENERAL_FAILURE; + ret = WERR_GENERAL_FAILURE; + goto cleanup; } if (preg_header.version > 1) { DEBUG(0, ("Warning: file format version is higher than expected.\n")); @@ -158,23 +159,21 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, /* Read the entries */ while(1) { - char *key, *value_name; uint32_t value_type, length; - DATA_BLOB data; if (!W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr))) { break; } if (*buf_ptr != '[') { DEBUG(0, ("Error in PReg file.\n")); - close(fd); - return WERR_GENERAL_FAILURE; + ret = WERR_GENERAL_FAILURE; + goto cleanup; } /* Get the path */ buf_ptr = buf; while (W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && - *buf_ptr != ';' && buf_ptr-buf < sizeof(buf)) { + *buf_ptr != ';' && buf_ptr-buf < buf_size) { buf_ptr++; } key = talloc_asprintf(mem_ctx, "\\%s", buf); @@ -182,7 +181,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, /* Get the name */ buf_ptr = buf; while (W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && - *buf_ptr != ';' && buf_ptr-buf < sizeof(buf)) { + *buf_ptr != ';' && buf_ptr-buf < buf_size) { buf_ptr++; } value_name = talloc_strdup(mem_ctx, buf); @@ -190,45 +189,45 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, /* Get the type */ if (read(fd, &value_type, 4) < 4) { DEBUG(0, ("Error while reading PReg\n")); - close(fd); - return WERR_GENERAL_FAILURE; + ret = WERR_GENERAL_FAILURE; + goto cleanup; } /* Read past delimiter */ buf_ptr = buf; if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && - *buf_ptr == ';') && buf_ptr-buf < sizeof(buf)) { + *buf_ptr == ';') && buf_ptr-buf < buf_size) { DEBUG(0, ("Error in PReg file.\n")); - close(fd); - return WERR_GENERAL_FAILURE; + ret = WERR_GENERAL_FAILURE; + goto cleanup; } /* Get data length */ if (read(fd, &length, 4) < 4) { DEBUG(0, ("Error while reading PReg\n")); - close(fd); - return WERR_GENERAL_FAILURE; + ret = WERR_GENERAL_FAILURE; + goto cleanup; } /* Read past delimiter */ buf_ptr = buf; if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && - *buf_ptr == ';') && buf_ptr-buf < sizeof(buf)) { + *buf_ptr == ';') && buf_ptr-buf < buf_size) { DEBUG(0, ("Error in PReg file.\n")); - close(fd); - return WERR_GENERAL_FAILURE; + ret = WERR_GENERAL_FAILURE; + goto cleanup; } /* Get the data */ buf_ptr = buf; - if (length < sizeof(buf) && + if (length < buf_size && read(fd, buf_ptr, length) != length) { DEBUG(0, ("Error while reading PReg\n")); - close(fd); - return WERR_GENERAL_FAILURE; + ret = WERR_GENERAL_FAILURE; + goto cleanup; } data = data_blob_talloc(mem_ctx, buf, length); /* Check if delimiter is in place (whine if it isn't) */ buf_ptr = buf; if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && - *buf_ptr == ']') && buf_ptr-buf < sizeof(buf)) { + *buf_ptr == ']') && buf_ptr-buf < buf_size) { DEBUG(0, ("Warning: Missing ']' in PReg file, expected ']', got '%c' 0x%x.\n", *buf_ptr, *buf_ptr)); } @@ -277,10 +276,12 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, callbacks->set_value(callback_data, key, value_name, value_type, data); } - talloc_free(key); - talloc_free(value_name); - talloc_free(data.data); } +cleanup: close(fd); - return WERR_OK; + talloc_free(data.data); + talloc_free(key); + talloc_free(value_name); + talloc_free(buf); + return ret; } -- cgit From a5b8999f23d56b4a19b87fc17b22c96f88e487e8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 12:19:33 +0100 Subject: r26427: Avoid global_smb_iconv_convenience. (This used to be commit bf072c6fb37b3e6a71c0c747b9fbeaa01480229e) --- source4/lib/registry/tests/generic.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/generic.c b/source4/lib/registry/tests/generic.c index 1acb6342e7..25a89793bd 100644 --- a/source4/lib/registry/tests/generic.c +++ b/source4/lib/registry/tests/generic.c @@ -23,6 +23,7 @@ #include "lib/registry/registry.h" #include "torture/torture.h" #include "librpc/gen_ndr/winreg.h" +#include "param/param.h" struct torture_suite *torture_registry_hive(TALLOC_CTX *mem_ctx); struct torture_suite *torture_registry_registry(TALLOC_CTX *mem_ctx); @@ -52,7 +53,7 @@ static bool test_reg_val_data_string_dword(struct torture_context *ctx) static bool test_reg_val_data_string_sz(struct torture_context *ctx) { DATA_BLOB db; - db.length = convert_string_talloc(ctx, global_smb_iconv_convenience, CH_UNIX, CH_UTF16, + db.length = convert_string_talloc(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UNIX, CH_UTF16, "bla", 3, (void **)&db.data); torture_assert_str_equal(ctx, "bla", reg_val_data_string(ctx, REG_SZ, db), @@ -87,7 +88,7 @@ static bool test_reg_val_data_string_empty(struct torture_context *ctx) static bool test_reg_val_description(struct torture_context *ctx) { DATA_BLOB data; - data.length = convert_string_talloc(ctx, global_smb_iconv_convenience, CH_UNIX, CH_UTF16, + data.length = convert_string_talloc(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UNIX, CH_UTF16, "stationary traveller", strlen("stationary traveller"), (void **)&data.data); @@ -101,7 +102,7 @@ static bool test_reg_val_description(struct torture_context *ctx) static bool test_reg_val_description_nullname(struct torture_context *ctx) { DATA_BLOB data; - data.length = convert_string_talloc(ctx, global_smb_iconv_convenience, CH_UNIX, CH_UTF16, + data.length = convert_string_talloc(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UNIX, CH_UTF16, "west berlin", strlen("west berlin"), (void **)&data.data); -- cgit From d891c0c74a03d797aed1c5ac0329fd9d1d78da63 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:09 +0100 Subject: r26429: Avoid use of global_smb_iconv_convenience. (This used to be commit d37136b7abfbba75ef2e5ab855eb3382b9648b8c) --- source4/lib/registry/ldb.c | 4 ++-- source4/lib/registry/patchfile_preg.c | 3 ++- source4/lib/registry/util.c | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 0e556da9e2..11fa066a35 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -54,7 +54,7 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, { case REG_SZ: case REG_EXPAND_SZ: - data->length = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF8, CH_UTF16, + data->length = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF8, CH_UTF16, val->data, val->length, (void **)&data->data); break; @@ -85,7 +85,7 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, switch (type) { case REG_SZ: case REG_EXPAND_SZ: - val.length = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF16, CH_UNIX, + val.length = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, (void *)data.data, data.length, (void **)&val.data); diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c index 47bd160c54..9cc9a5dec2 100644 --- a/source4/lib/registry/patchfile_preg.c +++ b/source4/lib/registry/patchfile_preg.c @@ -23,6 +23,7 @@ #include "lib/registry/registry.h" #include "lib/registry/patchfile.h" #include "system/filesys.h" +#include "param/param.h" struct preg_data { int fd; @@ -35,7 +36,7 @@ static WERROR preg_read_utf16(int fd, char *c) if (read(fd, &v, 2) < 2) { return WERR_GENERAL_FAILURE; } - push_codepoint(global_smb_iconv_convenience, c, v); + push_codepoint(lp_iconv_convenience(global_loadparm), c, v); return WERR_OK; } diff --git a/source4/lib/registry/util.c b/source4/lib/registry/util.c index f75fc835b5..a251ae49a5 100644 --- a/source4/lib/registry/util.c +++ b/source4/lib/registry/util.c @@ -20,6 +20,7 @@ #include "includes.h" #include "lib/registry/registry.h" #include "librpc/gen_ndr/winreg.h" +#include "param/param.h" /** * @file @@ -61,7 +62,7 @@ _PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, switch (type) { case REG_EXPAND_SZ: case REG_SZ: - convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF16, CH_UNIX, + convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, data.data, data.length, (void **)&ret); return ret; @@ -117,7 +118,7 @@ _PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, { case REG_SZ: case REG_EXPAND_SZ: - data->length = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UNIX, CH_UTF16, + data->length = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UNIX, CH_UTF16, data_str, strlen(data_str), (void **)&data->data); break; -- cgit From 5e00673a4063c9a51580a36ba1f824bd8ea0de66 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:47 +0100 Subject: r26438: Store iconv convenience in tdr push contexts. (This used to be commit dffef3162778aebe2f8d77e2da60b22adb7d60ef) --- source4/lib/registry/regf.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 3ae299b3ef..2485d2899c 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -24,6 +24,7 @@ #include "lib/registry/tdr_regf.h" #include "librpc/gen_ndr/ndr_security.h" #include "librpc/gen_ndr/winreg.h" +#include "param/param.h" static struct hive_operations reg_backend_regf; @@ -47,6 +48,7 @@ struct regf_data { int fd; struct hbin_block **hbins; struct regf_hdr *header; + struct smb_iconv_convenience *iconv_convenience; }; static WERROR regf_save_hbin(struct regf_data *data); @@ -263,7 +265,7 @@ static uint32_t hbin_store (struct regf_data *data, DATA_BLOB blob) static uint32_t hbin_store_tdr(struct regf_data *data, tdr_push_fn_t push_fn, void *p) { - struct tdr_push *push = talloc_zero(data, struct tdr_push); + struct tdr_push *push = tdr_push_init(data, data->iconv_convenience); uint32_t ret; if (NT_STATUS_IS_ERR(push_fn(push, p))) { @@ -390,7 +392,7 @@ static uint32_t hbin_store_tdr_resize(struct regf_data *regf, tdr_push_fn_t push_fn, uint32_t orig_offset, void *p) { - struct tdr_push *push = talloc_zero(regf, struct tdr_push); + struct tdr_push *push = tdr_push_init(regf, regf->iconv_convenience); uint32_t ret; if (NT_STATUS_IS_ERR(push_fn(push, p))) { @@ -1788,7 +1790,7 @@ static WERROR regf_set_value(struct hive_key *key, const char *name, static WERROR regf_save_hbin(struct regf_data *regf) { - struct tdr_push *push = talloc_zero(regf, struct tdr_push); + struct tdr_push *push = tdr_push_init(regf, regf->iconv_convenience); int i; W_ERROR_HAVE_NO_MEMORY(push); @@ -1806,7 +1808,7 @@ static WERROR regf_save_hbin(struct regf_data *regf) regf->header->chksum = regf_hdr_checksum(push->data.data); talloc_free(push); - if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, + if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, regf->iconv_convenience, (tdr_push_fn_t)tdr_push_regf_hdr, regf->header))) { DEBUG(0, ("Error writing registry file header\n")); @@ -1819,7 +1821,7 @@ static WERROR regf_save_hbin(struct regf_data *regf) } for (i = 0; regf->hbins[i]; i++) { - if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, + if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, regf->iconv_convenience, (tdr_push_fn_t)tdr_push_hbin_block, regf->hbins[i]))) { DEBUG(0, ("Error writing HBIN block\n")); @@ -1842,6 +1844,8 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location, regf = (struct regf_data *)talloc_zero(NULL, struct regf_data); + regf->iconv_convenience = lp_iconv_convenience(global_loadparm); + W_ERROR_HAVE_NO_MEMORY(regf); DEBUG(5, ("Attempting to create registry file\n")); @@ -1927,6 +1931,8 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, regf = (struct regf_data *)talloc_zero(NULL, struct regf_data); + regf->iconv_convenience = lp_iconv_convenience(global_loadparm); + W_ERROR_HAVE_NO_MEMORY(regf); DEBUG(5, ("Attempting to load registry file\n")); -- cgit From 27b21a386ebeed66dd804a8b2e2256b739e32543 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:51 +0100 Subject: r26439: Require tdr_pull users to specify a smb_iconv convenience context. (This used to be commit 76fd57be292fb19ae4ede38977732847e6ed8eff) --- source4/lib/registry/regf.c | 200 +++++++++++++++++++++++++------------------- 1 file changed, 112 insertions(+), 88 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 2485d2899c..8eb5760f56 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -133,21 +133,22 @@ static DATA_BLOB hbin_get(const struct regf_data *data, uint32_t offset) static bool hbin_get_tdr(struct regf_data *regf, uint32_t offset, TALLOC_CTX *ctx, tdr_pull_fn_t pull_fn, void *p) { - struct tdr_pull pull; + struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience); - ZERO_STRUCT(pull); - - pull.data = hbin_get(regf, offset); - if (!pull.data.data) { + pull->data = hbin_get(regf, offset); + if (!pull->data.data) { DEBUG(1, ("Unable to get data at 0x%04x\n", offset)); + talloc_free(pull); return false; } - if (NT_STATUS_IS_ERR(pull_fn(&pull, ctx, p))) { + if (NT_STATUS_IS_ERR(pull_fn(pull, ctx, p))) { DEBUG(1, ("Error parsing record at 0x%04x using tdr\n", offset)); + talloc_free(pull); return false; } + talloc_free(pull); return true; } @@ -594,16 +595,17 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx, if (!strncmp((char *)data.data, "li", 2)) { struct li_block li; - struct tdr_pull pull; + struct tdr_pull *pull = tdr_pull_init(private_data->hive, private_data->hive->iconv_convenience); DEBUG(10, ("Subkeys in LI list\n")); - ZERO_STRUCT(pull); - pull.data = data; + pull->data = data; - if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { + if (NT_STATUS_IS_ERR(tdr_pull_li_block(pull, nk, &li))) { DEBUG(0, ("Error parsing LI list\n")); + talloc_free(pull); return WERR_GENERAL_FAILURE; } + talloc_free(pull); SMB_ASSERT(!strncmp(li.header, "li", 2)); if (li.key_count != nk->num_subkeys) { @@ -614,16 +616,17 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx, } else if (!strncmp((char *)data.data, "lf", 2)) { struct lf_block lf; - struct tdr_pull pull; + struct tdr_pull *pull = tdr_pull_init(private_data->hive, private_data->hive->iconv_convenience); DEBUG(10, ("Subkeys in LF list\n")); - ZERO_STRUCT(pull); - pull.data = data; + pull->data = data; - if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, nk, &lf))) { + if (NT_STATUS_IS_ERR(tdr_pull_lf_block(pull, nk, &lf))) { DEBUG(0, ("Error parsing LF list\n")); + talloc_free(pull); return WERR_GENERAL_FAILURE; } + talloc_free(pull); SMB_ASSERT(!strncmp(lf.header, "lf", 2)); if (lf.key_count != nk->num_subkeys) { @@ -634,16 +637,17 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx, key_off = lf.hr[idx].nk_offset; } else if (!strncmp((char *)data.data, "lh", 2)) { struct lh_block lh; - struct tdr_pull pull; + struct tdr_pull *pull = tdr_pull_init(private_data->hive, private_data->hive->iconv_convenience); DEBUG(10, ("Subkeys in LH list\n")); - ZERO_STRUCT(pull); - pull.data = data; + pull->data = data; - if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(pull, nk, &lh))) { DEBUG(0, ("Error parsing LH list\n")); + talloc_free(pull); return WERR_GENERAL_FAILURE; } + talloc_free(pull); SMB_ASSERT(!strncmp(lh.header, "lh", 2)); if (lh.key_count != nk->num_subkeys) { @@ -653,16 +657,16 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx, key_off = lh.hr[idx].nk_offset; } else if (!strncmp((char *)data.data, "ri", 2)) { struct ri_block ri; - struct tdr_pull pull; + struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience); uint16_t i; uint16_t sublist_count = 0; DEBUG(10, ("Subkeys in RI list\n")); - ZERO_STRUCT(pull); - pull.data = data; + pull->data = data; - if (NT_STATUS_IS_ERR(tdr_pull_ri_block(&pull, nk, &ri))) { + if (NT_STATUS_IS_ERR(tdr_pull_ri_block(pull, nk, &ri))) { DEBUG(0, ("Error parsing RI list\n")); + talloc_free(pull); return WERR_GENERAL_FAILURE; } SMB_ASSERT(!strncmp(ri.header, "ri", 2)); @@ -674,21 +678,22 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx, list_data = hbin_get(private_data->hive, ri.offset[i]); if (!list_data.data) { DEBUG(0, ("Error getting RI list.")); + talloc_free(pull); return WERR_GENERAL_FAILURE; } - ZERO_STRUCT(pull); - pull.data = list_data; + pull->data = list_data; if (!strncmp((char *)list_data.data, "li", 2)) { struct li_block li; DEBUG(10, ("Subkeys in RI->LI list\n")); - if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, + if (NT_STATUS_IS_ERR(tdr_pull_li_block(pull, nk, &li))) { DEBUG(0, ("Error parsing LI list from RI\n")); + talloc_free(pull); return WERR_GENERAL_FAILURE; } SMB_ASSERT(!strncmp(li.header, "li", 2)); @@ -706,10 +711,11 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx, DEBUG(10, ("Subkeys in RI->LH list\n")); - if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(pull, nk, &lh))) { DEBUG(0, ("Error parsing LH list from RI\n")); + talloc_free(pull); return WERR_GENERAL_FAILURE; } SMB_ASSERT(!strncmp(lh.header, "lh", 2)); @@ -724,11 +730,14 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx, break; } else { DEBUG(0,("Unknown sublist in ri block\n")); + talloc_free(pull); return WERR_GENERAL_FAILURE; } } + talloc_free(pull); + if (idx > sublist_count) { return WERR_NO_MORE_ITEMS; @@ -771,7 +780,7 @@ static WERROR regf_match_subkey_by_name(TALLOC_CTX *ctx, { DATA_BLOB subkey_data; struct nk_block subkey; - struct tdr_pull pull; + struct tdr_pull *pull; const struct regf_key_data *private_data = (const struct regf_key_data *)key; @@ -781,13 +790,16 @@ static WERROR regf_match_subkey_by_name(TALLOC_CTX *ctx, return WERR_GENERAL_FAILURE; } - ZERO_STRUCT(pull); - pull.data = subkey_data; + pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience); + + pull->data = subkey_data; - if (NT_STATUS_IS_ERR(tdr_pull_nk_block(&pull, ctx, &subkey))) { + if (NT_STATUS_IS_ERR(tdr_pull_nk_block(pull, ctx, &subkey))) { DEBUG(0, ("Error parsing NK structure.\n")); + talloc_free(pull); return WERR_GENERAL_FAILURE; } + talloc_free(pull); if (strncmp(subkey.header, "nk", 2)) { DEBUG(0, ("Not an NK structure.\n")); @@ -821,17 +833,18 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, if (!strncmp((char *)data.data, "li", 2)) { struct li_block li; - struct tdr_pull pull; + struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience); uint16_t i; DEBUG(10, ("Subkeys in LI list\n")); - ZERO_STRUCT(pull); - pull.data = data; + pull->data = data; - if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { + if (NT_STATUS_IS_ERR(tdr_pull_li_block(pull, nk, &li))) { DEBUG(0, ("Error parsing LI list\n")); + talloc_free(pull); return WERR_GENERAL_FAILURE; } + talloc_free(pull); SMB_ASSERT(!strncmp(li.header, "li", 2)); if (li.key_count != nk->num_subkeys) { @@ -851,17 +864,18 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, return WERR_NOT_FOUND; } else if (!strncmp((char *)data.data, "lf", 2)) { struct lf_block lf; - struct tdr_pull pull; + struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience); uint16_t i; DEBUG(10, ("Subkeys in LF list\n")); - ZERO_STRUCT(pull); - pull.data = data; + pull->data = data; - if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, nk, &lf))) { + if (NT_STATUS_IS_ERR(tdr_pull_lf_block(pull, nk, &lf))) { DEBUG(0, ("Error parsing LF list\n")); + talloc_free(pull); return WERR_GENERAL_FAILURE; } + talloc_free(pull); SMB_ASSERT(!strncmp(lf.header, "lf", 2)); if (lf.key_count != nk->num_subkeys) { @@ -885,18 +899,19 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, return WERR_NOT_FOUND; } else if (!strncmp((char *)data.data, "lh", 2)) { struct lh_block lh; - struct tdr_pull pull; + struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience); uint16_t i; uint32_t hash; DEBUG(10, ("Subkeys in LH list\n")); - ZERO_STRUCT(pull); - pull.data = data; + pull->data = data; - if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(pull, nk, &lh))) { DEBUG(0, ("Error parsing LH list\n")); + talloc_free(pull); return WERR_GENERAL_FAILURE; } + talloc_free(pull); SMB_ASSERT(!strncmp(lh.header, "lh", 2)); if (lh.key_count != nk->num_subkeys) { @@ -921,15 +936,15 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, return WERR_NOT_FOUND; } else if (!strncmp((char *)data.data, "ri", 2)) { struct ri_block ri; - struct tdr_pull pull; + struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience); uint16_t i, j; DEBUG(10, ("Subkeys in RI list\n")); - ZERO_STRUCT(pull); - pull.data = data; + pull->data = data; - if (NT_STATUS_IS_ERR(tdr_pull_ri_block(&pull, nk, &ri))) { + if (NT_STATUS_IS_ERR(tdr_pull_ri_block(pull, nk, &ri))) { DEBUG(0, ("Error parsing RI list\n")); + talloc_free(pull); return WERR_GENERAL_FAILURE; } SMB_ASSERT(!strncmp(ri.header, "ri", 2)); @@ -941,19 +956,20 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, list_data = hbin_get(private_data->hive, ri.offset[i]); if (list_data.data == NULL) { DEBUG(0, ("Error getting RI list.")); + talloc_free(pull); return WERR_GENERAL_FAILURE; } - ZERO_STRUCT(pull); - pull.data = list_data; + pull->data = list_data; if (!strncmp((char *)list_data.data, "li", 2)) { struct li_block li; - if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, + if (NT_STATUS_IS_ERR(tdr_pull_li_block(pull, nk, &li))) { DEBUG(0, ("Error parsing LI list from RI\n")); + talloc_free(pull); return WERR_GENERAL_FAILURE; } SMB_ASSERT(!strncmp(li.header, "li", 2)); @@ -970,10 +986,11 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, struct lh_block lh; uint32_t hash; - if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(pull, nk, &lh))) { DEBUG(0, ("Error parsing LH list from RI\n")); + talloc_free(pull); return WERR_GENERAL_FAILURE; } SMB_ASSERT(!strncmp(lh.header, "lh", 2)); @@ -994,6 +1011,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, if (key_off) break; } + talloc_free(pull); if (!key_off) return WERR_NOT_FOUND; } else { @@ -1260,16 +1278,17 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, } if (!strncmp((char *)data.data, "li", 2)) { - struct tdr_pull pull; + struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience); struct li_block li; - ZERO_STRUCT(pull); - pull.data = data; + pull->data = data; - if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, regf, &li))) { + if (NT_STATUS_IS_ERR(tdr_pull_li_block(pull, regf, &li))) { DEBUG(0, ("Error parsing LI list\n")); + talloc_free(pull); return WERR_BADFILE; } + talloc_free(pull); if (strncmp(li.header, "li", 2) != 0) { abort(); @@ -1288,16 +1307,17 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, talloc_free(li.nk_offset); } else if (!strncmp((char *)data.data, "lf", 2)) { - struct tdr_pull pull; + struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience); struct lf_block lf; - ZERO_STRUCT(pull); - pull.data = data; + pull->data = data; - if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, regf, &lf))) { + if (NT_STATUS_IS_ERR(tdr_pull_lf_block(pull, regf, &lf))) { DEBUG(0, ("Error parsing LF list\n")); + talloc_free(pull); return WERR_BADFILE; } + talloc_free(pull); SMB_ASSERT(!strncmp(lf.header, "lf", 2)); lf.hr = talloc_realloc(regf, lf.hr, struct hash_record, @@ -1313,16 +1333,17 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, talloc_free(lf.hr); } else if (!strncmp((char *)data.data, "lh", 2)) { - struct tdr_pull pull; + struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience); struct lh_block lh; - ZERO_STRUCT(pull); - pull.data = data; + pull->data = data; - if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, regf, &lh))) { + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(pull, regf, &lh))) { DEBUG(0, ("Error parsing LH list\n")); + talloc_free(pull); return WERR_BADFILE; } + talloc_free(pull); SMB_ASSERT(!strncmp(lh.header, "lh", 2)); lh.hr = talloc_realloc(regf, lh.hr, struct lh_hash, @@ -1361,19 +1382,20 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, if (strncmp((char *)data.data, "li", 2) == 0) { struct li_block li; - struct tdr_pull pull; + struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience); uint16_t i; bool found_offset = false; DEBUG(10, ("Subkeys in LI list\n")); - ZERO_STRUCT(pull); - pull.data = data; + pull->data = data; - if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, regf, &li))) { + if (NT_STATUS_IS_ERR(tdr_pull_li_block(pull, regf, &li))) { DEBUG(0, ("Error parsing LI list\n")); + talloc_free(pull); return WERR_BADFILE; } + talloc_free(pull); SMB_ASSERT(!strncmp(li.header, "li", 2)); @@ -1404,19 +1426,20 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, list_offset, &li); } else if (strncmp((char *)data.data, "lf", 2) == 0) { struct lf_block lf; - struct tdr_pull pull; + struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience); uint16_t i; bool found_offset = false; DEBUG(10, ("Subkeys in LF list\n")); - ZERO_STRUCT(pull); - pull.data = data; + pull->data = data; - if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, regf, &lf))) { + if (NT_STATUS_IS_ERR(tdr_pull_lf_block(pull, regf, &lf))) { DEBUG(0, ("Error parsing LF list\n")); + talloc_free(pull); return WERR_BADFILE; } + talloc_free(pull); SMB_ASSERT(!strncmp(lf.header, "lf", 2)); @@ -1449,19 +1472,20 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, list_offset, &lf); } else if (strncmp((char *)data.data, "lh", 2) == 0) { struct lh_block lh; - struct tdr_pull pull; + struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience); uint16_t i; bool found_offset = false; DEBUG(10, ("Subkeys in LH list\n")); - ZERO_STRUCT(pull); - pull.data = data; + pull->data = data; - if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, regf, &lh))) { + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(pull, regf, &lh))) { DEBUG(0, ("Error parsing LF list\n")); + talloc_free(pull); return WERR_BADFILE; } + talloc_free(pull); SMB_ASSERT(!strncmp(lh.header, "lh", 2)); @@ -1837,7 +1861,6 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location, { struct regf_data *regf; struct regf_hdr *regf_hdr; - struct tdr_pull pull; int i; struct nk_block nk; WERROR error; @@ -1874,8 +1897,6 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location, regf->header = regf_hdr; - pull.offset = 0x1000; - i = 0; /* Create all hbin blocks */ regf->hbins = talloc_array(regf, struct hbin_block *, 1); @@ -1926,7 +1947,7 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, { struct regf_data *regf; struct regf_hdr *regf_hdr; - struct tdr_pull pull; + struct tdr_pull *pull; int i; regf = (struct regf_data *)talloc_zero(NULL, struct regf_data); @@ -1947,10 +1968,11 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, return WERR_GENERAL_FAILURE; } - ZERO_STRUCT(pull); - pull.data.data = (uint8_t*)fd_load(regf->fd, &pull.data.length, regf); + pull = tdr_pull_init(regf, regf->iconv_convenience); + + pull->data.data = (uint8_t*)fd_load(regf->fd, &pull->data.length, regf); - if (pull.data.data == NULL) { + if (pull->data.data == NULL) { DEBUG(0, ("Error reading data\n")); talloc_free(regf); return WERR_GENERAL_FAILURE; @@ -1959,7 +1981,7 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, regf_hdr = talloc(regf, struct regf_hdr); W_ERROR_HAVE_NO_MEMORY(regf_hdr); - if (NT_STATUS_IS_ERR(tdr_pull_regf_hdr(&pull, regf_hdr, regf_hdr))) { + if (NT_STATUS_IS_ERR(tdr_pull_regf_hdr(pull, regf_hdr, regf_hdr))) { talloc_free(regf); return WERR_GENERAL_FAILURE; } @@ -1974,15 +1996,15 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, } /* Validate the header ... */ - if (regf_hdr_checksum(pull.data.data) != regf_hdr->chksum) { + if (regf_hdr_checksum(pull->data.data) != regf_hdr->chksum) { DEBUG(0, ("Registry file checksum error: %s: %d,%d\n", location, regf_hdr->chksum, - regf_hdr_checksum(pull.data.data))); + regf_hdr_checksum(pull->data.data))); talloc_free(regf); return WERR_GENERAL_FAILURE; } - pull.offset = 0x1000; + pull->offset = 0x1000; i = 0; /* Read in all hbin blocks */ @@ -1991,14 +2013,14 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, regf->hbins[0] = NULL; - while (pull.offset < pull.data.length && - pull.offset <= regf->header->last_block) { + while (pull->offset < pull->data.length && + pull->offset <= regf->header->last_block) { struct hbin_block *hbin = talloc(regf->hbins, struct hbin_block); W_ERROR_HAVE_NO_MEMORY(hbin); - if (NT_STATUS_IS_ERR(tdr_pull_hbin_block(&pull, hbin, hbin))) { + if (NT_STATUS_IS_ERR(tdr_pull_hbin_block(pull, hbin, hbin))) { DEBUG(0, ("[%d] Error parsing HBIN block\n", i)); talloc_free(regf); return WERR_FOOBAR; @@ -2018,6 +2040,8 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, regf->hbins[i] = NULL; } + talloc_free(pull); + DEBUG(1, ("%d HBIN blocks read\n", i)); *key = (struct hive_key *)regf_get_key(parent_ctx, regf, -- cgit From 96a200511e884a88dcf48fa5b313b2cddb2df566 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 14 Dec 2007 00:27:31 +0100 Subject: r26443: Remove global_loadparm instances. (This used to be commit 8242c696235d1bfb402b5c276a57f36d93610545) --- source4/lib/registry/hive.c | 5 +++-- source4/lib/registry/hive.h | 5 ++++- source4/lib/registry/ldb.c | 1 + source4/lib/registry/regf.c | 6 +++--- source4/lib/registry/samba.c | 4 ++-- source4/lib/registry/tests/hive.c | 2 +- source4/lib/registry/tests/registry.c | 2 +- source4/lib/registry/tools/common.c | 3 ++- source4/lib/registry/tools/regshell.c | 2 +- source4/lib/registry/tools/regtree.c | 2 +- 10 files changed, 19 insertions(+), 13 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/hive.c b/source4/lib/registry/hive.c index 16534aac9c..64bee8251b 100644 --- a/source4/lib/registry/hive.c +++ b/source4/lib/registry/hive.c @@ -27,6 +27,7 @@ _PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, + struct loadparm_context *lp_ctx, struct hive_key **root) { int fd, num; @@ -51,11 +52,11 @@ _PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, if (!strncmp(peek, "regf", 4)) { close(fd); - return reg_open_regf_file(parent_ctx, location, root); + return reg_open_regf_file(parent_ctx, location, lp_ctx, root); } else if (!strncmp(peek, "TDB file", 8)) { close(fd); return reg_open_ldb_file(parent_ctx, location, session_info, - credentials, root); + credentials, lp_ctx, root); } return WERR_BADFILE; diff --git a/source4/lib/registry/hive.h b/source4/lib/registry/hive.h index d8e20d4aa2..37e5493da8 100644 --- a/source4/lib/registry/hive.h +++ b/source4/lib/registry/hive.h @@ -144,6 +144,7 @@ struct auth_session_info; WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, + struct loadparm_context *lp_ctx, struct hive_key **root); WERROR hive_key_get_info(TALLOC_CTX *mem_ctx, const struct hive_key *key, const char **classname, uint32_t *num_subkeys, @@ -183,10 +184,12 @@ WERROR hive_key_flush(struct hive_key *key); WERROR reg_open_directory(TALLOC_CTX *parent_ctx, const char *location, struct hive_key **key); WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, - const char *location, struct hive_key **key); + const char *location, struct loadparm_context *lp_ctx, + struct hive_key **key); WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, + struct loadparm_context *lp_ctx, struct hive_key **k); diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 11fa066a35..873e291d5b 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -337,6 +337,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, + struct loadparm_context *lp_ctx, struct hive_key **k) { struct ldb_key_data *kd; diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 8eb5760f56..210b4c9ada 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -1942,8 +1942,8 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location, return WERR_OK; } -WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, - const char *location, struct hive_key **key) +WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, const char *location, + struct loadparm_context *lp_ctx, struct hive_key **key) { struct regf_data *regf; struct regf_hdr *regf_hdr; @@ -1952,7 +1952,7 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, regf = (struct regf_data *)talloc_zero(NULL, struct regf_data); - regf->iconv_convenience = lp_iconv_convenience(global_loadparm); + regf->iconv_convenience = lp_iconv_convenience(lp_ctx); W_ERROR_HAVE_NO_MEMORY(regf); diff --git a/source4/lib/registry/samba.c b/source4/lib/registry/samba.c index a5a60ba610..02f3363bab 100644 --- a/source4/lib/registry/samba.c +++ b/source4/lib/registry/samba.c @@ -40,11 +40,11 @@ static WERROR mount_samba_hive(struct registry_context *ctx, lp_private_dir(lp_ctx), name); - error = reg_open_hive(ctx, location, auth_info, creds, &hive); + error = reg_open_hive(ctx, location, auth_info, creds, lp_ctx, &hive); if (W_ERROR_EQUAL(error, WERR_NOT_FOUND)) error = reg_open_ldb_file(ctx, location, auth_info, - creds, &hive); + creds, lp_ctx, &hive); if (!W_ERROR_IS_OK(error)) return error; diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index 2a0f04eb54..04a91d42fa 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -323,7 +323,7 @@ static bool hive_setup_ldb(struct torture_context *tctx, void **data) rmdir(dirname); - error = reg_open_ldb_file(tctx, dirname, NULL, NULL, &key); + error = reg_open_ldb_file(tctx, dirname, NULL, NULL, tctx->lp_ctx, &key); if (!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to initialize ldb hive\n"); return false; diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index f0035071f2..8cb0433084 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -547,7 +547,7 @@ static bool setup_local_registry(struct torture_context *tctx, void **data) torture_assert_ntstatus_ok(tctx, status, "Creating temp dir failed"); filename = talloc_asprintf(tctx, "%s/classes_root.ldb", tempdir); - error = reg_open_ldb_file(tctx, filename, NULL, NULL, &hive_key); + error = reg_open_ldb_file(tctx, filename, NULL, NULL, tctx->lp_ctx, &hive_key); torture_assert_werr_ok(tctx, error, "Opening classes_root file failed"); error = reg_mount_hive(rctx, hive_key, HKEY_CLASSES_ROOT, NULL); diff --git a/source4/lib/registry/tools/common.c b/source4/lib/registry/tools/common.c index c9293cd310..29e96475e6 100644 --- a/source4/lib/registry/tools/common.c +++ b/source4/lib/registry/tools/common.c @@ -42,13 +42,14 @@ struct registry_context *reg_common_open_remote(const char *remote, } struct registry_key *reg_common_open_file(const char *path, + struct loadparm_context *lp_ctx, struct cli_credentials *creds) { struct hive_key *hive_root; struct registry_context *h; WERROR error; - error = reg_open_hive(NULL, path, NULL, creds, &hive_root); + error = reg_open_hive(NULL, path, NULL, creds, lp_ctx, &hive_root); if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open '%s': %s \n", diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 2c692952fb..1c5157e937 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -500,7 +500,7 @@ int main(int argc, char **argv) ctx->registry = reg_common_open_remote(remote, cmdline_lp_ctx, cmdline_credentials); } else if (file != NULL) { - ctx->current = reg_common_open_file(file, cmdline_credentials); + ctx->current = reg_common_open_file(file, cmdline_lp_ctx, cmdline_credentials); if (ctx->current == NULL) return 1; ctx->registry = ctx->current->context; diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index b267e11b43..0f47d8f8dd 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -131,7 +131,7 @@ int main(int argc, char **argv) if (remote != NULL) { h = reg_common_open_remote(remote, cmdline_lp_ctx, cmdline_credentials); } else if (file != NULL) { - start_key = reg_common_open_file(file, cmdline_credentials); + start_key = reg_common_open_file(file, cmdline_lp_ctx, cmdline_credentials); } else { h = reg_common_open_local(cmdline_credentials, cmdline_lp_ctx); } -- cgit From 864218b6beebaeb337f14398f0544340ad30dd58 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 14 Dec 2007 01:26:25 +0100 Subject: r26448: Add basic tests for param python module. (This used to be commit ccfab20dcc2d7059c402c03be244b759d59c4b81) --- source4/lib/registry/registry.i | 3 ++ source4/lib/registry/registry.py | 1 + source4/lib/registry/registry_wrap.c | 101 +++++++++++++++++++++++++---------- 3 files changed, 78 insertions(+), 27 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i index 330f0856e1..ef823dddbd 100644 --- a/source4/lib/registry/registry.i +++ b/source4/lib/registry/registry.i @@ -25,6 +25,7 @@ #include "includes.h" #include "registry.h" +#include "param/param.h" typedef struct registry_context reg; typedef struct hive_key hive; @@ -39,6 +40,7 @@ typedef struct hive_key hive; %import "../../lib/talloc/talloc.i" %import "../../auth/credentials/credentials.i" %import "../../libcli/util/errors.i" +%import "../../param/param.i" /* Utility functions */ @@ -123,6 +125,7 @@ typedef struct registry_context { WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, + struct loadparm_context *lp_ctx, struct hive_key **root); typedef struct hive_key { diff --git a/source4/lib/registry/registry.py b/source4/lib/registry/registry.py index 4e3d48a18c..451b650d62 100644 --- a/source4/lib/registry/registry.py +++ b/source4/lib/registry/registry.py @@ -58,6 +58,7 @@ def _swig_setattr_nondynamic_method(set): import credentials +import param reg_get_predef_name = _registry.reg_get_predef_name str_regtype = _registry.str_regtype Registry = _registry.Registry diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index 15c27a8f6c..4f74072dc1 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -2463,20 +2463,23 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) #define SWIGTYPE_p_hive_key swig_types[4] #define SWIGTYPE_p_int swig_types[5] #define SWIGTYPE_p_loadparm_context swig_types[6] -#define SWIGTYPE_p_long_long swig_types[7] -#define SWIGTYPE_p_p_char swig_types[8] -#define SWIGTYPE_p_p_hive_key swig_types[9] -#define SWIGTYPE_p_p_registry_context swig_types[10] -#define SWIGTYPE_p_p_registry_key swig_types[11] -#define SWIGTYPE_p_registry_context swig_types[12] -#define SWIGTYPE_p_short swig_types[13] -#define SWIGTYPE_p_signed_char swig_types[14] -#define SWIGTYPE_p_unsigned_char swig_types[15] -#define SWIGTYPE_p_unsigned_int swig_types[16] -#define SWIGTYPE_p_unsigned_long_long swig_types[17] -#define SWIGTYPE_p_unsigned_short swig_types[18] -static swig_type_info *swig_types[20]; -static swig_module_info swig_module = {swig_types, 19, 0, 0, 0, 0}; +#define SWIGTYPE_p_loadparm_service swig_types[7] +#define SWIGTYPE_p_long_long swig_types[8] +#define SWIGTYPE_p_p_char swig_types[9] +#define SWIGTYPE_p_p_hive_key swig_types[10] +#define SWIGTYPE_p_p_registry_context swig_types[11] +#define SWIGTYPE_p_p_registry_key swig_types[12] +#define SWIGTYPE_p_param_context swig_types[13] +#define SWIGTYPE_p_param_section swig_types[14] +#define SWIGTYPE_p_registry_context swig_types[15] +#define SWIGTYPE_p_short swig_types[16] +#define SWIGTYPE_p_signed_char swig_types[17] +#define SWIGTYPE_p_unsigned_char swig_types[18] +#define SWIGTYPE_p_unsigned_int swig_types[19] +#define SWIGTYPE_p_unsigned_long_long swig_types[20] +#define SWIGTYPE_p_unsigned_short swig_types[21] +static swig_type_info *swig_types[23]; +static swig_module_info swig_module = {swig_types, 22, 0, 0, 0, 0}; #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) @@ -2522,6 +2525,7 @@ static swig_module_info swig_module = {swig_types, 19, 0, 0, 0, 0}; #include "includes.h" #include "registry.h" +#include "param/param.h" typedef struct registry_context reg; typedef struct hive_key hive; @@ -3244,7 +3248,8 @@ SWIGINTERN PyObject *_wrap_Hive(PyObject *SWIGUNUSEDPARM(self), PyObject *args, char *arg2 = (char *) 0 ; struct auth_session_info *arg3 = (struct auth_session_info *) 0 ; struct cli_credentials *arg4 = (struct cli_credentials *) 0 ; - struct hive_key **arg5 = (struct hive_key **) 0 ; + struct loadparm_context *arg5 = (struct loadparm_context *) 0 ; + struct hive_key **arg6 = (struct hive_key **) 0 ; WERROR result; int res2 ; char *buf2 = 0 ; @@ -3253,12 +3258,15 @@ SWIGINTERN PyObject *_wrap_Hive(PyObject *SWIGUNUSEDPARM(self), PyObject *args, int res3 = 0 ; void *argp4 = 0 ; int res4 = 0 ; - struct hive_key *tmp5 ; + void *argp5 = 0 ; + int res5 = 0 ; + struct hive_key *tmp6 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; + PyObject * obj3 = 0 ; char * kwnames[] = { - (char *) "location",(char *) "session_info",(char *) "credentials", NULL + (char *) "location",(char *) "session_info",(char *) "credentials",(char *) "lp_ctx", NULL }; { @@ -3267,13 +3275,16 @@ SWIGINTERN PyObject *_wrap_Hive(PyObject *SWIGUNUSEDPARM(self), PyObject *args, { arg4 = NULL; } + { + arg5 = loadparm_init(NULL); + } { arg1 = NULL; } { - arg5 = &tmp5; + arg6 = &tmp6; } - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OO:Hive",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OOO:Hive",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); if (!SWIG_IsOK(res2)) { SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Hive" "', argument " "2"" of type '" "char const *""'"); @@ -3293,7 +3304,14 @@ SWIGINTERN PyObject *_wrap_Hive(PyObject *SWIGUNUSEDPARM(self), PyObject *args, } arg4 = (struct cli_credentials *)(argp4); } - result = reg_open_hive(arg1,(char const *)arg2,arg3,arg4,arg5); + if (obj3) { + res5 = SWIG_ConvertPtr(obj3, &argp5,SWIGTYPE_p_loadparm_context, 0 | 0 ); + if (!SWIG_IsOK(res5)) { + SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "Hive" "', argument " "5"" of type '" "struct loadparm_context *""'"); + } + arg5 = (struct loadparm_context *)(argp5); + } + result = reg_open_hive(arg1,(char const *)arg2,arg3,arg4,arg5,arg6); { if (!W_ERROR_IS_OK(result)) { PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); @@ -3304,12 +3322,18 @@ SWIGINTERN PyObject *_wrap_Hive(PyObject *SWIGUNUSEDPARM(self), PyObject *args, } { Py_XDECREF(resultobj); - resultobj = SWIG_NewPointerObj(*arg5, SWIGTYPE_p_hive_key, 0); + resultobj = SWIG_NewPointerObj(*arg6, SWIGTYPE_p_hive_key, 0); } if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + { + talloc_free(arg5); + } return resultobj; fail: if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + { + talloc_free(arg5); + } return NULL; } @@ -3383,6 +3407,9 @@ SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject * (char *) "lp_ctx",(char *) "session_info",(char *) "credentials", NULL }; + { + arg3 = loadparm_init(NULL); + } { arg4 = NULL; } @@ -3395,12 +3422,14 @@ SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject * { arg2 = &tmp2; } - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OO:open_samba",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; - res3 = SWIG_ConvertPtr(obj0, &argp3,SWIGTYPE_p_loadparm_context, 0 | 0 ); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "open_samba" "', argument " "3"" of type '" "struct loadparm_context *""'"); + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|OOO:open_samba",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; + if (obj0) { + res3 = SWIG_ConvertPtr(obj0, &argp3,SWIGTYPE_p_loadparm_context, 0 | 0 ); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "open_samba" "', argument " "3"" of type '" "struct loadparm_context *""'"); + } + arg3 = (struct loadparm_context *)(argp3); } - arg3 = (struct loadparm_context *)(argp3); if (obj1) { res4 = SWIG_ConvertPtr(obj1, &argp4,SWIGTYPE_p_auth_session_info, 0 | 0 ); if (!SWIG_IsOK(res4)) { @@ -3427,8 +3456,14 @@ SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject * { resultobj = SWIG_NewPointerObj(*arg2, SWIGTYPE_p_registry_context, 0); } + { + talloc_free(arg3); + } return resultobj; fail: + { + talloc_free(arg3); + } return NULL; } @@ -3463,12 +3498,15 @@ static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_cli_credentials = {"_p_cli_credentials", "struct cli_credentials *|cli_credentials *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_hive_key = {"_p_hive_key", "struct hive_key *|hive *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_loadparm_context = {"_p_loadparm_context", "struct loadparm_context *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_loadparm_context = {"_p_loadparm_context", "struct loadparm_context *|loadparm_context *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_loadparm_service = {"_p_loadparm_service", "struct loadparm_service *|loadparm_service *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_p_hive_key = {"_p_p_hive_key", "struct hive_key **", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_p_registry_context = {"_p_p_registry_context", "struct registry_context **", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_p_registry_key = {"_p_p_registry_key", "struct registry_key **", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_param_context = {"_p_param_context", "struct param_context *|param *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_param_section = {"_p_param_section", "struct param_section *|param_section *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_registry_context = {"_p_registry_context", "struct registry_context *|reg *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0}; @@ -3485,11 +3523,14 @@ static swig_type_info *swig_type_initial[] = { &_swigt__p_hive_key, &_swigt__p_int, &_swigt__p_loadparm_context, + &_swigt__p_loadparm_service, &_swigt__p_long_long, &_swigt__p_p_char, &_swigt__p_p_hive_key, &_swigt__p_p_registry_context, &_swigt__p_p_registry_key, + &_swigt__p_param_context, + &_swigt__p_param_section, &_swigt__p_registry_context, &_swigt__p_short, &_swigt__p_signed_char, @@ -3506,11 +3547,14 @@ static swig_cast_info _swigc__p_cli_credentials[] = { {&_swigt__p_cli_credentia static swig_cast_info _swigc__p_hive_key[] = { {&_swigt__p_hive_key, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_loadparm_context[] = { {&_swigt__p_loadparm_context, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_loadparm_service[] = { {&_swigt__p_loadparm_service, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_p_char[] = { {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_p_hive_key[] = { {&_swigt__p_p_hive_key, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_p_registry_context[] = { {&_swigt__p_p_registry_context, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_p_registry_key[] = { {&_swigt__p_p_registry_key, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_param_context[] = { {&_swigt__p_param_context, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_param_section[] = { {&_swigt__p_param_section, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_registry_context[] = { {&_swigt__p_registry_context, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_short[] = { {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_signed_char[] = { {&_swigt__p_signed_char, 0, 0, 0},{0, 0, 0, 0}}; @@ -3527,11 +3571,14 @@ static swig_cast_info *swig_cast_initial[] = { _swigc__p_hive_key, _swigc__p_int, _swigc__p_loadparm_context, + _swigc__p_loadparm_service, _swigc__p_long_long, _swigc__p_p_char, _swigc__p_p_hive_key, _swigc__p_p_registry_context, _swigc__p_p_registry_key, + _swigc__p_param_context, + _swigc__p_param_section, _swigc__p_registry_context, _swigc__p_short, _swigc__p_signed_char, -- cgit From 45015eda2421253f858f0a4500a57c2855f9686c Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Fri, 14 Dec 2007 10:38:26 +0100 Subject: r26451: Janitorial: fix warnings in lib/registry/ This does not fix the discarded qualifier warnings in tests, as the test data is currently passed as const. Jelmer wants to provide a test function that passes non-const test data, thus allowing for a cleaner way to fix those warnings. (This used to be commit 46dfa63d4f7381c5c6ce3f4b8b0bd9aa9e16950c) --- source4/lib/registry/dir.c | 2 +- source4/lib/registry/hive.h | 2 +- source4/lib/registry/interface.c | 2 +- source4/lib/registry/ldb.c | 2 +- source4/lib/registry/local.c | 8 ++++---- source4/lib/registry/regf.c | 8 +++----- source4/lib/registry/registry.h | 4 ++-- source4/lib/registry/rpc.c | 2 +- source4/lib/registry/tests/hive.c | 6 +++--- source4/lib/registry/tests/registry.c | 2 +- 10 files changed, 18 insertions(+), 20 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/dir.c b/source4/lib/registry/dir.c index 532770bcaf..2f00d2fea0 100644 --- a/source4/lib/registry/dir.c +++ b/source4/lib/registry/dir.c @@ -272,7 +272,7 @@ static WERROR reg_dir_get_value(TALLOC_CTX *mem_ctx, } static WERROR reg_dir_enum_value(TALLOC_CTX *mem_ctx, - const struct hive_key *key, int idx, + struct hive_key *key, int idx, const char **name, uint32_t *type, DATA_BLOB *data) { diff --git a/source4/lib/registry/hive.h b/source4/lib/registry/hive.h index 37e5493da8..ffb92f8e79 100644 --- a/source4/lib/registry/hive.h +++ b/source4/lib/registry/hive.h @@ -82,7 +82,7 @@ struct hive_operations { * Retrieve a registry value with a specific index. */ WERROR (*enum_value) (TALLOC_CTX *mem_ctx, - const struct hive_key *key, int idx, + struct hive_key *key, int idx, const char **name, uint32_t *type, DATA_BLOB *data); diff --git a/source4/lib/registry/interface.c b/source4/lib/registry/interface.c index 8f60a55ae9..b914fbab30 100644 --- a/source4/lib/registry/interface.c +++ b/source4/lib/registry/interface.c @@ -74,7 +74,7 @@ _PUBLIC_ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, } /** Get predefined key by id. */ -_PUBLIC_ WERROR reg_get_predefined_key(const struct registry_context *ctx, +_PUBLIC_ WERROR reg_get_predefined_key(struct registry_context *ctx, uint32_t hkey, struct registry_key **key) { return ctx->ops->get_predefined_key(ctx, hkey, key); diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 873e291d5b..78acc3150b 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -249,7 +249,7 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, return WERR_OK; } -static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct hive_key *k, +static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct hive_key *k, int idx, const char **name, uint32_t *data_type, DATA_BLOB *data) { diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index b54f0cf30a..5789a94a6d 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -126,7 +126,7 @@ static WERROR local_open_key(TALLOC_CTX *mem_ctx, return WERR_OK; } -WERROR local_get_predefined_key(const struct registry_context *ctx, +WERROR local_get_predefined_key(struct registry_context *ctx, uint32_t key_id, struct registry_key **key) { struct registry_local *rctx = talloc_get_type(ctx, @@ -168,7 +168,7 @@ static WERROR local_create_key(TALLOC_CTX *mem_ctx, struct security_descriptor *security, struct registry_key **key) { - const struct local_key *local_parent; + struct local_key *local_parent; struct hive_key *hivekey; const char **elements; int i; @@ -177,11 +177,11 @@ static WERROR local_create_key(TALLOC_CTX *mem_ctx, last_part = strrchr(name, '\\'); if (last_part == NULL) { last_part = name; - local_parent = (const struct local_key *)parent_key; + local_parent = (struct local_key *)parent_key; } else { W_ERROR_NOT_OK_RETURN(reg_open_key(mem_ctx, parent_key, talloc_strndup(mem_ctx, name, last_part-name), - &local_parent)); + (struct registry_key **)&local_parent)); last_part++; } diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 210b4c9ada..28bd0ad461 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -488,7 +488,7 @@ static struct regf_key_data *regf_get_key(TALLOC_CTX *ctx, } -static WERROR regf_get_value(TALLOC_CTX *ctx, const struct hive_key *key, +static WERROR regf_get_value(TALLOC_CTX *ctx, struct hive_key *key, int idx, const char **name, uint32_t *data_type, DATA_BLOB *data) { @@ -1529,8 +1529,7 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, static WERROR regf_del_value (struct hive_key *key, const char *name) { - const struct regf_key_data *private_data = - (const struct regf_key_data *)key; + struct regf_key_data *private_data = (struct regf_key_data *)key; struct regf_data *regf = private_data->hive; struct nk_block *nk = private_data->nk; struct vk_block vk; @@ -1703,8 +1702,7 @@ static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent, static WERROR regf_set_value(struct hive_key *key, const char *name, uint32_t type, const DATA_BLOB data) { - const struct regf_key_data *private_data = - (const struct regf_key_data *)key; + struct regf_key_data *private_data = (struct regf_key_data *)key; struct regf_data *regf = private_data->hive; struct nk_block *nk = private_data->nk; struct vk_block vk; diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index edd6c6713f..a02acbea1e 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -94,7 +94,7 @@ struct registry_operations { WERROR (*flush_key) (struct registry_key *key); - WERROR (*get_predefined_key) (const struct registry_context *ctx, + WERROR (*get_predefined_key) (struct registry_context *ctx, uint32_t key_id, struct registry_key **key); @@ -195,7 +195,7 @@ const char *reg_get_predef_name(uint32_t hkey); WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, const char *name, struct registry_key **key); -WERROR reg_get_predefined_key(const struct registry_context *ctx, +WERROR reg_get_predefined_key(struct registry_context *ctx, uint32_t hkey, struct registry_key **key); diff --git a/source4/lib/registry/rpc.c b/source4/lib/registry/rpc.c index ac0eecd0ac..7f800b786e 100644 --- a/source4/lib/registry/rpc.c +++ b/source4/lib/registry/rpc.c @@ -91,7 +91,7 @@ static struct { static WERROR rpc_query_key(const struct registry_key *k); -static WERROR rpc_get_predefined_key(const struct registry_context *ctx, +static WERROR rpc_get_predefined_key(struct registry_context *ctx, uint32_t hkey_type, struct registry_key **k) { diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index 04a91d42fa..fdb7282395 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -290,7 +290,7 @@ static bool hive_setup_dir(struct torture_context *tctx, void **data) { struct hive_key *key; WERROR error; - const char *dirname; + char *dirname; NTSTATUS status; status = torture_temp_dir(tctx, "hive-dir", &dirname); @@ -314,7 +314,7 @@ static bool hive_setup_ldb(struct torture_context *tctx, void **data) { struct hive_key *key; WERROR error; - const char *dirname; + char *dirname; NTSTATUS status; status = torture_temp_dir(tctx, "hive-ldb", &dirname); @@ -338,7 +338,7 @@ static bool hive_setup_regf(struct torture_context *tctx, void **data) { struct hive_key *key; WERROR error; - const char *dirname; + char *dirname; NTSTATUS status; status = torture_temp_dir(tctx, "hive-dir", &dirname); diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 8cb0433084..6c520f54ed 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -535,7 +535,7 @@ static bool setup_local_registry(struct torture_context *tctx, void **data) { struct registry_context *rctx; WERROR error; - const char *tempdir; + char *tempdir; NTSTATUS status; struct hive_key *hive_key; const char *filename; -- cgit From 43ac3d9b44b98d44db9b1550c47e8f96a410d1e9 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Fri, 14 Dec 2007 14:04:56 +0100 Subject: r26453: Janitorial: Don't use a static char[] in smb_readline_replacement. Fix up callers to free the memory returned, as that is needed if we use the original readline function as well. (This used to be commit c81ead1c38f417d442157b21d0d389f6a540c6f9) --- source4/lib/registry/tools/regshell.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 1c5157e937..329d6ab670 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -546,12 +546,16 @@ int main(int argc, char **argv) via readline :-( */ line = smb_readline(prompt, NULL, reg_completion); - if (line == NULL) + if (line == NULL) { + free(prompt); break; + } if (line[0] != '\n') { ret = W_ERROR_IS_OK(process_cmd(ctx, line)); } + free(line); + free(prompt); } talloc_free(ctx); -- cgit From df8c7da800f75ff45fb48de59d7ce3f0667d375f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 14 Dec 2007 14:28:07 +0100 Subject: r26454: Add simple SWIG macro for wrapping talloced types. (This used to be commit 760fcc8bfa2a7cd7641465cb3bae889e9e0fbc75) --- source4/lib/registry/registry.i | 8 ++-- source4/lib/registry/registry.py | 4 +- source4/lib/registry/registry_wrap.c | 92 +++++++++++++++--------------------- 3 files changed, 45 insertions(+), 59 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i index ef823dddbd..c5b4eed968 100644 --- a/source4/lib/registry/registry.i +++ b/source4/lib/registry/registry.i @@ -88,10 +88,11 @@ WERROR reg_open_local(TALLOC_CTX *parent_ctx, struct registry_context **ctx, free((char **) $1); } +%talloctype(reg); + typedef struct registry_context { %extend { - ~reg() { talloc_free($self); } WERROR get_predefined_key_by_name(const char *name, struct registry_key **key); @@ -128,10 +129,9 @@ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, struct loadparm_context *lp_ctx, struct hive_key **root); +%talloctype(hive); + typedef struct hive_key { - %extend { - ~hive() { talloc_free($self); } - } } hive; %rename(open_samba) reg_open_samba; diff --git a/source4/lib/registry/registry.py b/source4/lib/registry/registry.py index 451b650d62..0097949896 100644 --- a/source4/lib/registry/registry.py +++ b/source4/lib/registry/registry.py @@ -65,12 +65,12 @@ Registry = _registry.Registry class reg(object): thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') __repr__ = _swig_repr - __swig_destroy__ = _registry.delete_reg def mount(self, path, hkey_id, elements=[]): self.mount_hive(Hive(path), hkey_id, elements) def __init__(self, *args, **kwargs): _registry.reg_swiginit(self,_registry.new_reg(*args, **kwargs)) + __swig_destroy__ = _registry.delete_reg reg.get_predefined_key_by_name = new_instancemethod(_registry.reg_get_predefined_key_by_name,None,reg) reg.get_predefined_key = new_instancemethod(_registry.reg_get_predefined_key,None,reg) reg.apply_patchfile = new_instancemethod(_registry.reg_apply_patchfile,None,reg) @@ -82,9 +82,9 @@ Hive = _registry.Hive class hive(object): thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') __repr__ = _swig_repr - __swig_destroy__ = _registry.delete_hive def __init__(self, *args, **kwargs): _registry.hive_swiginit(self,_registry.new_hive(*args, **kwargs)) + __swig_destroy__ = _registry.delete_hive hive_swigregister = _registry.hive_swigregister hive_swigregister(hive) diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index 4f74072dc1..21cc4896f6 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -2772,7 +2772,6 @@ SWIG_AsVal_int (PyObject * obj, int *val) return res; } -SWIGINTERN void delete_reg(reg *self){ talloc_free(self); } SWIGINTERN int SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) @@ -2831,7 +2830,6 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) SWIGINTERN WERROR reg_apply_patchfile(reg *self,char const *filename){ return reg_diff_apply(filename, self); } -SWIGINTERN void delete_hive(hive *self){ talloc_free(self); } #define SWIG_From_long PyInt_FromLong @@ -2966,29 +2964,6 @@ fail: } -SWIGINTERN PyObject *_wrap_delete_reg(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - reg *arg1 = (reg *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_registry_context, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_reg" "', argument " "1"" of type '" "reg *""'"); - } - arg1 = (reg *)(argp1); - delete_reg(arg1); - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - SWIGINTERN PyObject *_wrap_reg_get_predefined_key_by_name(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; reg *arg1 = (reg *) 0 ; @@ -3231,6 +3206,29 @@ fail: } +SWIGINTERN PyObject *_wrap_delete_reg(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + reg *arg1 = (reg *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_registry_context, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_reg" "', argument " "1"" of type '" "reg *""'"); + } + arg1 = (reg *)(argp1); + free((char *) arg1); + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *reg_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; @@ -3325,15 +3323,22 @@ SWIGINTERN PyObject *_wrap_Hive(PyObject *SWIGUNUSEDPARM(self), PyObject *args, resultobj = SWIG_NewPointerObj(*arg6, SWIGTYPE_p_hive_key, 0); } if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - { - talloc_free(arg5); - } return resultobj; fail: if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - { - talloc_free(arg5); - } + return NULL; +} + + +SWIGINTERN PyObject *_wrap_new_hive(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + hive *result = 0 ; + + if (!SWIG_Python_UnpackTuple(args,"new_hive",0,0,0)) SWIG_fail; + result = (hive *)(hive *) calloc(1, sizeof(hive)); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_hive_key, SWIG_POINTER_NEW | 0 ); + return resultobj; +fail: return NULL; } @@ -3352,7 +3357,7 @@ SWIGINTERN PyObject *_wrap_delete_hive(PyObject *SWIGUNUSEDPARM(self), PyObject SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_hive" "', argument " "1"" of type '" "hive *""'"); } arg1 = (hive *)(argp1); - delete_hive(arg1); + free((char *) arg1); resultobj = SWIG_Py_Void(); return resultobj; @@ -3361,19 +3366,6 @@ fail: } -SWIGINTERN PyObject *_wrap_new_hive(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - hive *result = 0 ; - - if (!SWIG_Python_UnpackTuple(args,"new_hive",0,0,0)) SWIG_fail; - result = (hive *)(hive *) calloc(1, sizeof(hive)); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_hive_key, SWIG_POINTER_NEW | 0 ); - return resultobj; -fail: - return NULL; -} - - SWIGINTERN PyObject *hive_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; @@ -3456,14 +3448,8 @@ SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject * { resultobj = SWIG_NewPointerObj(*arg2, SWIGTYPE_p_registry_context, 0); } - { - talloc_free(arg3); - } return resultobj; fail: - { - talloc_free(arg3); - } return NULL; } @@ -3472,17 +3458,17 @@ static PyMethodDef SwigMethods[] = { { (char *)"reg_get_predef_name", (PyCFunction) _wrap_reg_get_predef_name, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"str_regtype", (PyCFunction) _wrap_str_regtype, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"Registry", (PyCFunction) _wrap_Registry, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"delete_reg", (PyCFunction)_wrap_delete_reg, METH_O, NULL}, { (char *)"reg_get_predefined_key_by_name", (PyCFunction) _wrap_reg_get_predefined_key_by_name, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"reg_get_predefined_key", (PyCFunction) _wrap_reg_get_predefined_key, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"reg_apply_patchfile", (PyCFunction) _wrap_reg_apply_patchfile, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"reg_mount_hive", (PyCFunction) _wrap_reg_mount_hive, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"new_reg", (PyCFunction)_wrap_new_reg, METH_NOARGS, NULL}, + { (char *)"delete_reg", (PyCFunction)_wrap_delete_reg, METH_O, NULL}, { (char *)"reg_swigregister", reg_swigregister, METH_VARARGS, NULL}, { (char *)"reg_swiginit", reg_swiginit, METH_VARARGS, NULL}, { (char *)"Hive", (PyCFunction) _wrap_Hive, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"delete_hive", (PyCFunction)_wrap_delete_hive, METH_O, NULL}, { (char *)"new_hive", (PyCFunction)_wrap_new_hive, METH_NOARGS, NULL}, + { (char *)"delete_hive", (PyCFunction)_wrap_delete_hive, METH_O, NULL}, { (char *)"hive_swigregister", hive_swigregister, METH_VARARGS, NULL}, { (char *)"hive_swiginit", hive_swiginit, METH_VARARGS, NULL}, { (char *)"open_samba", (PyCFunction) _wrap_open_samba, METH_VARARGS | METH_KEYWORDS, NULL}, -- cgit From 12a513b47b1a1f2adeb2cb2a10ac36d02dd44065 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 23:16:16 +0100 Subject: r26518: Fix provision of registry using Python. (This used to be commit 12eb38e553993b2726a803af4ae9c05229d6ebe4) --- source4/lib/registry/ldb.c | 2 +- source4/lib/registry/local.c | 2 +- source4/lib/registry/registry.i | 5 ----- source4/lib/registry/registry.py | 3 --- source4/lib/registry/registry_wrap.c | 25 +++++++++++++++---------- 5 files changed, 17 insertions(+), 20 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 78acc3150b..c9697ddb4c 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -346,7 +346,7 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, if (location == NULL) return WERR_INVALID_PARAM; - wrap = ldb_wrap_connect(parent_ctx, global_loadparm, + wrap = ldb_wrap_connect(parent_ctx, lp_ctx, location, session_info, credentials, 0, NULL); if (wrap == NULL) { diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index 5789a94a6d..1ed4f0262e 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -321,7 +321,7 @@ WERROR reg_mount_hive(struct registry_context *rctx, mp->path.predefined_key = key_id; mp->prev = mp->next = NULL; mp->key = hive_key; - if (elements != NULL) { + if (elements != NULL && str_list_length(elements) != 0) { mp->path.elements = talloc_array(mp, const char *, str_list_length(elements)); for (i = 0; elements[i] != NULL; i++) { diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i index c5b4eed968..784462c368 100644 --- a/source4/lib/registry/registry.i +++ b/source4/lib/registry/registry.i @@ -105,11 +105,6 @@ typedef struct registry_context { WERROR mount_hive(struct hive_key *hive_key, uint32_t hkey_id, const char **elements=NULL); } - - %pythoncode { - def mount(self, path, hkey_id, elements=[]): - self.mount_hive(Hive(path), hkey_id, elements) - } } reg; /* Hives */ diff --git a/source4/lib/registry/registry.py b/source4/lib/registry/registry.py index 0097949896..67607cd7ac 100644 --- a/source4/lib/registry/registry.py +++ b/source4/lib/registry/registry.py @@ -65,9 +65,6 @@ Registry = _registry.Registry class reg(object): thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') __repr__ = _swig_repr - def mount(self, path, hkey_id, elements=[]): - self.mount_hive(Hive(path), hkey_id, elements) - def __init__(self, *args, **kwargs): _registry.reg_swiginit(self,_registry.new_reg(*args, **kwargs)) __swig_destroy__ = _registry.delete_reg diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index 21cc4896f6..e4e1502404 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -2470,16 +2470,17 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) #define SWIGTYPE_p_p_registry_context swig_types[11] #define SWIGTYPE_p_p_registry_key swig_types[12] #define SWIGTYPE_p_param_context swig_types[13] -#define SWIGTYPE_p_param_section swig_types[14] -#define SWIGTYPE_p_registry_context swig_types[15] -#define SWIGTYPE_p_short swig_types[16] -#define SWIGTYPE_p_signed_char swig_types[17] -#define SWIGTYPE_p_unsigned_char swig_types[18] -#define SWIGTYPE_p_unsigned_int swig_types[19] -#define SWIGTYPE_p_unsigned_long_long swig_types[20] -#define SWIGTYPE_p_unsigned_short swig_types[21] -static swig_type_info *swig_types[23]; -static swig_module_info swig_module = {swig_types, 22, 0, 0, 0, 0}; +#define SWIGTYPE_p_param_opt swig_types[14] +#define SWIGTYPE_p_param_section swig_types[15] +#define SWIGTYPE_p_registry_context swig_types[16] +#define SWIGTYPE_p_short swig_types[17] +#define SWIGTYPE_p_signed_char swig_types[18] +#define SWIGTYPE_p_unsigned_char swig_types[19] +#define SWIGTYPE_p_unsigned_int swig_types[20] +#define SWIGTYPE_p_unsigned_long_long swig_types[21] +#define SWIGTYPE_p_unsigned_short swig_types[22] +static swig_type_info *swig_types[24]; +static swig_module_info swig_module = {swig_types, 23, 0, 0, 0, 0}; #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) @@ -3492,6 +3493,7 @@ static swig_type_info _swigt__p_p_hive_key = {"_p_p_hive_key", "struct hive_key static swig_type_info _swigt__p_p_registry_context = {"_p_p_registry_context", "struct registry_context **", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_p_registry_key = {"_p_p_registry_key", "struct registry_key **", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_param_context = {"_p_param_context", "struct param_context *|param *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_param_opt = {"_p_param_opt", "struct param_opt *|param_opt *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_param_section = {"_p_param_section", "struct param_section *|param_section *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_registry_context = {"_p_registry_context", "struct registry_context *|reg *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0}; @@ -3516,6 +3518,7 @@ static swig_type_info *swig_type_initial[] = { &_swigt__p_p_registry_context, &_swigt__p_p_registry_key, &_swigt__p_param_context, + &_swigt__p_param_opt, &_swigt__p_param_section, &_swigt__p_registry_context, &_swigt__p_short, @@ -3540,6 +3543,7 @@ static swig_cast_info _swigc__p_p_hive_key[] = { {&_swigt__p_p_hive_key, 0, 0, static swig_cast_info _swigc__p_p_registry_context[] = { {&_swigt__p_p_registry_context, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_p_registry_key[] = { {&_swigt__p_p_registry_key, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_param_context[] = { {&_swigt__p_param_context, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_param_opt[] = { {&_swigt__p_param_opt, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_param_section[] = { {&_swigt__p_param_section, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_registry_context[] = { {&_swigt__p_registry_context, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_short[] = { {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}}; @@ -3564,6 +3568,7 @@ static swig_cast_info *swig_cast_initial[] = { _swigc__p_p_registry_context, _swigc__p_p_registry_key, _swigc__p_param_context, + _swigc__p_param_opt, _swigc__p_param_section, _swigc__p_registry_context, _swigc__p_short, -- cgit From 63f53094efa29b76eb4136cddf19d9c5d325fc5f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 18 Dec 2007 02:21:14 +0100 Subject: r26520: More Python updates. (This used to be commit a8b1fe15ac853082961132ede061fe1556ae29f7) --- source4/lib/registry/registry.i | 12 ++++ source4/lib/registry/registry_wrap.c | 114 +++++++++++++++++++++++++++++------ 2 files changed, 108 insertions(+), 18 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i index 784462c368..1819e7df80 100644 --- a/source4/lib/registry/registry.i +++ b/source4/lib/registry/registry.i @@ -104,6 +104,18 @@ typedef struct registry_context { WERROR mount_hive(struct hive_key *hive_key, uint32_t hkey_id, const char **elements=NULL); + + WERROR mount_hive(struct hive_key *hive_key, const char *predef_name) + { + int i; + for (i = 0; reg_predefined_keys[i].name; i++) { + if (!strcasecmp(reg_predefined_keys[i].name, predef_name)) + return reg_mount_hive($self, hive_key, + reg_predefined_keys[i].handle, NULL); + } + return WERR_INVALID_NAME; + } + } } reg; diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index e4e1502404..fcbd2ea165 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -2831,6 +2831,15 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) SWIGINTERN WERROR reg_apply_patchfile(reg *self,char const *filename){ return reg_diff_apply(filename, self); } +SWIGINTERN WERROR reg_mount_hive__SWIG_1(reg *self,struct hive_key *hive_key,char const *predef_name){ + int i; + for (i = 0; reg_predefined_keys[i].name; i++) { + if (!strcasecmp(reg_predefined_keys[i].name, predef_name)) + return reg_mount_hive(self, hive_key, + reg_predefined_keys[i].handle, NULL); + } + return WERR_INVALID_NAME; + } #define SWIG_From_long PyInt_FromLong @@ -3112,7 +3121,7 @@ fail: } -SWIGINTERN PyObject *_wrap_reg_mount_hive(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { +SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_0(PyObject *SWIGUNUSEDPARM(self), int nobjs, PyObject **swig_obj) { PyObject *resultobj = 0; reg *arg1 = (reg *) 0 ; struct hive_key *arg2 = (struct hive_key *) 0 ; @@ -3125,41 +3134,34 @@ SWIGINTERN PyObject *_wrap_reg_mount_hive(PyObject *SWIGUNUSEDPARM(self), PyObje int res2 = 0 ; unsigned int val3 ; int ecode3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "hive_key",(char *) "hkey_id",(char *) "elements", NULL - }; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO|O:reg_mount_hive",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); + if ((nobjs < 3) || (nobjs > 4)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_mount_hive" "', argument " "1"" of type '" "reg *""'"); } arg1 = (reg *)(argp1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_hive_key, 0 | 0 ); + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_hive_key, 0 | 0 ); if (!SWIG_IsOK(res2)) { SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "reg_mount_hive" "', argument " "2"" of type '" "struct hive_key *""'"); } arg2 = (struct hive_key *)(argp2); - ecode3 = SWIG_AsVal_unsigned_SS_int(obj2, &val3); + ecode3 = SWIG_AsVal_unsigned_SS_int(swig_obj[2], &val3); if (!SWIG_IsOK(ecode3)) { SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "reg_mount_hive" "', argument " "3"" of type '" "uint32_t""'"); } arg3 = (uint32_t)(val3); - if (obj3) { + if (swig_obj[3]) { { /* Check if is a list */ - if (PyList_Check(obj3)) { - int size = PyList_Size(obj3); + if (PyList_Check(swig_obj[3])) { + int size = PyList_Size(swig_obj[3]); int i = 0; arg4 = (char **) malloc((size+1)*sizeof(const char *)); for (i = 0; i < size; i++) { - PyObject *o = PyList_GetItem(obj3,i); + PyObject *o = PyList_GetItem(swig_obj[3],i); if (PyString_Check(o)) - arg4[i] = PyString_AsString(PyList_GetItem(obj3,i)); + arg4[i] = PyString_AsString(PyList_GetItem(swig_obj[3],i)); else { PyErr_SetString(PyExc_TypeError,"list must contain strings"); free(arg4); @@ -3194,6 +3196,82 @@ fail: } +SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_1(PyObject *SWIGUNUSEDPARM(self), int nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + reg *arg1 = (reg *) 0 ; + struct hive_key *arg2 = (struct hive_key *) 0 ; + char *arg3 = (char *) 0 ; + WERROR result; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + int res3 ; + char *buf3 = 0 ; + int alloc3 = 0 ; + + if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_mount_hive" "', argument " "1"" of type '" "reg *""'"); + } + arg1 = (reg *)(argp1); + res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_hive_key, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "reg_mount_hive" "', argument " "2"" of type '" "struct hive_key *""'"); + } + arg2 = (struct hive_key *)(argp2); + res3 = SWIG_AsCharPtrAndSize(swig_obj[2], &buf3, NULL, &alloc3); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "reg_mount_hive" "', argument " "3"" of type '" "char const *""'"); + } + arg3 = (char *)(buf3); + result = reg_mount_hive__SWIG_1(arg1,arg2,(char const *)arg3); + { + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); + return resultobj; +fail: + if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_reg_mount_hive(PyObject *self, PyObject *args) { + int argc; + PyObject *argv[5]; + + if (!(argc = SWIG_Python_UnpackTuple(args,"reg_mount_hive",0,4,argv))) SWIG_fail; + --argc; + if ((argc >= 3) && (argc <= 4)) { + int _v = 0; + { + { + int res = SWIG_AsVal_unsigned_SS_int(argv[2], NULL); + _v = SWIG_CheckState(res); + } + } + if (!_v) goto check_1; + return _wrap_reg_mount_hive__SWIG_0(self, argc, argv); + } +check_1: + + if (argc == 3) { + return _wrap_reg_mount_hive__SWIG_1(self, argc, argv); + } + +fail: + SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'reg_mount_hive'.\n Possible C/C++ prototypes are:\n"" mount_hive(reg *,struct hive_key *,uint32_t,char const **)\n"" mount_hive(reg *,struct hive_key *,char const *)\n"); + return NULL; +} + + SWIGINTERN PyObject *_wrap_new_reg(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; reg *result = 0 ; @@ -3462,7 +3540,7 @@ static PyMethodDef SwigMethods[] = { { (char *)"reg_get_predefined_key_by_name", (PyCFunction) _wrap_reg_get_predefined_key_by_name, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"reg_get_predefined_key", (PyCFunction) _wrap_reg_get_predefined_key, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"reg_apply_patchfile", (PyCFunction) _wrap_reg_apply_patchfile, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"reg_mount_hive", (PyCFunction) _wrap_reg_mount_hive, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"reg_mount_hive", _wrap_reg_mount_hive, METH_VARARGS, NULL}, { (char *)"new_reg", (PyCFunction)_wrap_new_reg, METH_NOARGS, NULL}, { (char *)"delete_reg", (PyCFunction)_wrap_delete_reg, METH_O, NULL}, { (char *)"reg_swigregister", reg_swigregister, METH_VARARGS, NULL}, -- cgit From 670918f916cb881d4cc591516c70bafe4e39ba45 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 Dec 2007 05:02:48 -0600 Subject: r26563: Fix reg_diff_apply argument order. (This used to be commit cfffd0357ee4c4bb3f3c9adb051eeee1bbac526a) --- source4/lib/registry/patchfile.c | 3 +-- source4/lib/registry/patchfile.h | 3 +-- source4/lib/registry/registry.i | 6 +----- source4/lib/registry/tools/regpatch.c | 2 +- 4 files changed, 4 insertions(+), 10 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index e5d9a26618..8a417d5935 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -432,8 +432,7 @@ static WERROR reg_diff_apply_del_all_values(void *_ctx, const char *key_name) /** * Apply diff to a registry context */ -_PUBLIC_ WERROR reg_diff_apply(const char *filename, - struct registry_context *ctx) +_PUBLIC_ WERROR reg_diff_apply(struct registry_context *ctx, const char *filename) { struct reg_diff_callbacks callbacks; diff --git a/source4/lib/registry/patchfile.h b/source4/lib/registry/patchfile.h index 4c0599b2f3..08a977d9cd 100644 --- a/source4/lib/registry/patchfile.h +++ b/source4/lib/registry/patchfile.h @@ -36,8 +36,7 @@ struct reg_diff_callbacks { WERROR (*done) (void *callback_data); }; -WERROR reg_diff_apply (const char *filename, - struct registry_context *ctx); +WERROR reg_diff_apply(struct registry_context *ctx, const char *filename); WERROR reg_generate_diff(struct registry_context *ctx1, struct registry_context *ctx2, diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i index 1819e7df80..407599ec08 100644 --- a/source4/lib/registry/registry.i +++ b/source4/lib/registry/registry.i @@ -97,11 +97,7 @@ typedef struct registry_context { struct registry_key **key); WERROR get_predefined_key(uint32_t hkey_id, struct registry_key **key); - WERROR apply_patchfile(const char *filename) - { - return reg_diff_apply(filename, $self); - } - + WERROR apply_patchfile(const char *filename); WERROR mount_hive(struct hive_key *hive_key, uint32_t hkey_id, const char **elements=NULL); diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index ddbedce18a..71837d1807 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -65,7 +65,7 @@ int main(int argc, char **argv) poptFreeContext(pc); - reg_diff_apply(patch, h); + reg_diff_apply(h, patch); return 0; } -- cgit From 09f820f0bd1a9fc7ffd171418ceb0e19df8e2e43 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 Dec 2007 05:02:57 -0600 Subject: r26564: More python bindings for registry code. (This used to be commit f40fad9827d0e9567224bc1e64ea91e610a07a3f) --- source4/lib/registry/hive.c | 2 +- source4/lib/registry/hive.h | 2 +- source4/lib/registry/local.c | 2 +- source4/lib/registry/registry.i | 22 ++- source4/lib/registry/registry.py | 16 +- source4/lib/registry/registry_wrap.c | 291 +++++++++++++++++++++++++---------- source4/lib/registry/tests/hive.c | 4 +- 7 files changed, 238 insertions(+), 101 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/hive.c b/source4/lib/registry/hive.c index 64bee8251b..6a1623338d 100644 --- a/source4/lib/registry/hive.c +++ b/source4/lib/registry/hive.c @@ -138,7 +138,7 @@ WERROR hive_get_value_by_index(TALLOC_CTX *mem_ctx, } -WERROR hive_del_value(struct hive_key *key, const char *name) +WERROR hive_key_del_value(struct hive_key *key, const char *name) { if (key->ops->delete_value == NULL) return WERR_NOT_SUPPORTED; diff --git a/source4/lib/registry/hive.h b/source4/lib/registry/hive.h index ffb92f8e79..e82177d8b8 100644 --- a/source4/lib/registry/hive.h +++ b/source4/lib/registry/hive.h @@ -175,7 +175,7 @@ WERROR hive_get_value_by_index(TALLOC_CTX *mem_ctx, const char **name, uint32_t *type, DATA_BLOB *data); -WERROR hive_del_value(struct hive_key *key, const char *name); +WERROR hive_key_del_value(struct hive_key *key, const char *name); WERROR hive_key_flush(struct hive_key *key); diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index 1ed4f0262e..06c9031055 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -251,7 +251,7 @@ static WERROR local_delete_value(struct registry_key *key, const char *name) { const struct local_key *local = (const struct local_key *)key; - return hive_del_value(local->hive_key, name); + return hive_key_del_value(local->hive_key, name); } static WERROR local_flush_key(struct registry_key *key) diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i index 407599ec08..315afb0c31 100644 --- a/source4/lib/registry/registry.i +++ b/source4/lib/registry/registry.i @@ -28,7 +28,7 @@ #include "param/param.h" typedef struct registry_context reg; -typedef struct hive_key hive; +typedef struct hive_key hive_key; %} /* FIXME: This should be in another file */ @@ -96,11 +96,16 @@ typedef struct registry_context { WERROR get_predefined_key_by_name(const char *name, struct registry_key **key); + WERROR key_del_abs(const char *path); WERROR get_predefined_key(uint32_t hkey_id, struct registry_key **key); - WERROR apply_patchfile(const char *filename); + WERROR diff_apply(const char *filename); + WERROR generate_diff(struct registry_context *ctx2, const struct reg_diff_callbacks *callbacks, + void *callback_data); + WERROR mount_hive(struct hive_key *hive_key, uint32_t hkey_id, const char **elements=NULL); + struct registry_key *import_hive_key(struct hive_key *hive, uint32_t predef_key, const char **elements); WERROR mount_hive(struct hive_key *hive_key, const char *predef_name) { int i; @@ -110,7 +115,7 @@ typedef struct registry_context { reg_predefined_keys[i].handle, NULL); } return WERR_INVALID_NAME; - } + } } } reg; @@ -125,17 +130,22 @@ typedef struct registry_context { $result = SWIG_NewPointerObj(*$1, SWIGTYPE_p_hive_key, 0); } -%rename(Hive) reg_open_hive; +%rename(hive_key) reg_open_hive; WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, struct loadparm_context *lp_ctx, struct hive_key **root); -%talloctype(hive); +%talloctype(hive_key); typedef struct hive_key { -} hive; + %extend { + WERROR del(const char *name); + WERROR flush(void); + WERROR del_value(const char *name); + } +} hive_key; %rename(open_samba) reg_open_samba; diff --git a/source4/lib/registry/registry.py b/source4/lib/registry/registry.py index 67607cd7ac..ff5653e915 100644 --- a/source4/lib/registry/registry.py +++ b/source4/lib/registry/registry.py @@ -69,22 +69,16 @@ class reg(object): _registry.reg_swiginit(self,_registry.new_reg(*args, **kwargs)) __swig_destroy__ = _registry.delete_reg reg.get_predefined_key_by_name = new_instancemethod(_registry.reg_get_predefined_key_by_name,None,reg) +reg.key_del_abs = new_instancemethod(_registry.reg_key_del_abs,None,reg) reg.get_predefined_key = new_instancemethod(_registry.reg_get_predefined_key,None,reg) -reg.apply_patchfile = new_instancemethod(_registry.reg_apply_patchfile,None,reg) +reg.diff_apply = new_instancemethod(_registry.reg_diff_apply,None,reg) +reg.generate_diff = new_instancemethod(_registry.reg_generate_diff,None,reg) +reg.import_hive_key = new_instancemethod(_registry.reg_import_hive_key,None,reg) reg.mount_hive = new_instancemethod(_registry.reg_mount_hive,None,reg) reg_swigregister = _registry.reg_swigregister reg_swigregister(reg) -Hive = _registry.Hive -class hive(object): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - __repr__ = _swig_repr - def __init__(self, *args, **kwargs): - _registry.hive_swiginit(self,_registry.new_hive(*args, **kwargs)) - __swig_destroy__ = _registry.delete_hive -hive_swigregister = _registry.hive_swigregister -hive_swigregister(hive) - +hive_key = _registry.hive_key open_samba = _registry.open_samba HKEY_CLASSES_ROOT = _registry.HKEY_CLASSES_ROOT HKEY_CURRENT_USER = _registry.HKEY_CURRENT_USER diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index fcbd2ea165..ab6c2fb5e9 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -2472,15 +2472,17 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) #define SWIGTYPE_p_param_context swig_types[13] #define SWIGTYPE_p_param_opt swig_types[14] #define SWIGTYPE_p_param_section swig_types[15] -#define SWIGTYPE_p_registry_context swig_types[16] -#define SWIGTYPE_p_short swig_types[17] -#define SWIGTYPE_p_signed_char swig_types[18] -#define SWIGTYPE_p_unsigned_char swig_types[19] -#define SWIGTYPE_p_unsigned_int swig_types[20] -#define SWIGTYPE_p_unsigned_long_long swig_types[21] -#define SWIGTYPE_p_unsigned_short swig_types[22] -static swig_type_info *swig_types[24]; -static swig_module_info swig_module = {swig_types, 23, 0, 0, 0, 0}; +#define SWIGTYPE_p_reg_diff_callbacks swig_types[16] +#define SWIGTYPE_p_registry_context swig_types[17] +#define SWIGTYPE_p_registry_key swig_types[18] +#define SWIGTYPE_p_short swig_types[19] +#define SWIGTYPE_p_signed_char swig_types[20] +#define SWIGTYPE_p_unsigned_char swig_types[21] +#define SWIGTYPE_p_unsigned_int swig_types[22] +#define SWIGTYPE_p_unsigned_long_long swig_types[23] +#define SWIGTYPE_p_unsigned_short swig_types[24] +static swig_type_info *swig_types[26]; +static swig_module_info swig_module = {swig_types, 25, 0, 0, 0, 0}; #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) @@ -2529,7 +2531,7 @@ static swig_module_info swig_module = {swig_types, 23, 0, 0, 0, 0}; #include "param/param.h" typedef struct registry_context reg; -typedef struct hive_key hive; +typedef struct hive_key hive_key; #include @@ -2828,9 +2830,6 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) -SWIGINTERN WERROR reg_apply_patchfile(reg *self,char const *filename){ - return reg_diff_apply(filename, self); - } SWIGINTERN WERROR reg_mount_hive__SWIG_1(reg *self,struct hive_key *hive_key,char const *predef_name){ int i; for (i = 0; reg_predefined_keys[i].name; i++) { @@ -2839,7 +2838,7 @@ SWIGINTERN WERROR reg_mount_hive__SWIG_1(reg *self,struct hive_key *hive_key,cha reg_predefined_keys[i].handle, NULL); } return WERR_INVALID_NAME; - } + } #define SWIG_From_long PyInt_FromLong @@ -3027,6 +3026,50 @@ fail: } +SWIGINTERN PyObject *_wrap_reg_key_del_abs(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + reg *arg1 = (reg *) 0 ; + char *arg2 = (char *) 0 ; + WERROR result; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "path", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:reg_key_del_abs",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_key_del_abs" "', argument " "1"" of type '" "reg *""'"); + } + arg1 = (reg *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "reg_key_del_abs" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = (char *)(buf2); + result = reg_key_del_abs(arg1,(char const *)arg2); + { + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + SWIGINTERN PyObject *_wrap_reg_get_predefined_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; reg *arg1 = (reg *) 0 ; @@ -3077,7 +3120,7 @@ fail: } -SWIGINTERN PyObject *_wrap_reg_apply_patchfile(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { +SWIGINTERN PyObject *_wrap_reg_diff_apply(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; reg *arg1 = (reg *) 0 ; char *arg2 = (char *) 0 ; @@ -3093,18 +3136,18 @@ SWIGINTERN PyObject *_wrap_reg_apply_patchfile(PyObject *SWIGUNUSEDPARM(self), P (char *) "self",(char *) "filename", NULL }; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:reg_apply_patchfile",kwnames,&obj0,&obj1)) SWIG_fail; + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:reg_diff_apply",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_apply_patchfile" "', argument " "1"" of type '" "reg *""'"); + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_diff_apply" "', argument " "1"" of type '" "reg *""'"); } arg1 = (reg *)(argp1); res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "reg_apply_patchfile" "', argument " "2"" of type '" "char const *""'"); + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "reg_diff_apply" "', argument " "2"" of type '" "char const *""'"); } arg2 = (char *)(buf2); - result = reg_apply_patchfile(arg1,(char const *)arg2); + result = reg_diff_apply(arg1,(char const *)arg2); { if (!W_ERROR_IS_OK(result)) { PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); @@ -3121,6 +3164,63 @@ fail: } +SWIGINTERN PyObject *_wrap_reg_generate_diff(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + reg *arg1 = (reg *) 0 ; + struct registry_context *arg2 = (struct registry_context *) 0 ; + struct reg_diff_callbacks *arg3 = (struct reg_diff_callbacks *) 0 ; + void *arg4 = (void *) 0 ; + WERROR result; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + void *argp3 = 0 ; + int res3 = 0 ; + int res4 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + PyObject * obj3 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "ctx2",(char *) "callbacks",(char *) "callback_data", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOOO:reg_generate_diff",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_generate_diff" "', argument " "1"" of type '" "reg *""'"); + } + arg1 = (reg *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_registry_context, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "reg_generate_diff" "', argument " "2"" of type '" "struct registry_context *""'"); + } + arg2 = (struct registry_context *)(argp2); + res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_reg_diff_callbacks, 0 | 0 ); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "reg_generate_diff" "', argument " "3"" of type '" "struct reg_diff_callbacks const *""'"); + } + arg3 = (struct reg_diff_callbacks *)(argp3); + res4 = SWIG_ConvertPtr(obj3,SWIG_as_voidptrptr(&arg4), 0, 0); + if (!SWIG_IsOK(res4)) { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "reg_generate_diff" "', argument " "4"" of type '" "void *""'"); + } + result = reg_generate_diff(arg1,arg2,(struct reg_diff_callbacks const *)arg3,arg4); + { + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_0(PyObject *SWIGUNUSEDPARM(self), int nobjs, PyObject **swig_obj) { PyObject *resultobj = 0; reg *arg1 = (reg *) 0 ; @@ -3196,6 +3296,79 @@ fail: } +SWIGINTERN PyObject *_wrap_reg_import_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + reg *arg1 = (reg *) 0 ; + struct hive_key *arg2 = (struct hive_key *) 0 ; + uint32_t arg3 ; + char **arg4 = (char **) 0 ; + struct registry_key *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + unsigned int val3 ; + int ecode3 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + PyObject * obj3 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "hive",(char *) "predef_key",(char *) "elements", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOOO:reg_import_hive_key",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_import_hive_key" "', argument " "1"" of type '" "reg *""'"); + } + arg1 = (reg *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_hive_key, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "reg_import_hive_key" "', argument " "2"" of type '" "struct hive_key *""'"); + } + arg2 = (struct hive_key *)(argp2); + ecode3 = SWIG_AsVal_unsigned_SS_int(obj2, &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "reg_import_hive_key" "', argument " "3"" of type '" "uint32_t""'"); + } + arg3 = (uint32_t)(val3); + { + /* Check if is a list */ + if (PyList_Check(obj3)) { + int size = PyList_Size(obj3); + int i = 0; + arg4 = (char **) malloc((size+1)*sizeof(const char *)); + for (i = 0; i < size; i++) { + PyObject *o = PyList_GetItem(obj3,i); + if (PyString_Check(o)) + arg4[i] = PyString_AsString(PyList_GetItem(obj3,i)); + else { + PyErr_SetString(PyExc_TypeError,"list must contain strings"); + free(arg4); + return NULL; + } + } + arg4[i] = 0; + } else { + PyErr_SetString(PyExc_TypeError,"not a list"); + return NULL; + } + } + result = (struct registry_key *)reg_import_hive_key(arg1,arg2,arg3,(char const **)arg4); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_registry_key, 0 | 0 ); + { + free((char **) arg4); + } + return resultobj; +fail: + { + free((char **) arg4); + } + return NULL; +} + + SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_1(PyObject *SWIGUNUSEDPARM(self), int nobjs, PyObject **swig_obj) { PyObject *resultobj = 0; reg *arg1 = (reg *) 0 ; @@ -3319,7 +3492,7 @@ SWIGINTERN PyObject *reg_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args return SWIG_Python_InitShadowInstance(args); } -SWIGINTERN PyObject *_wrap_Hive(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { +SWIGINTERN PyObject *_wrap_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; char *arg2 = (char *) 0 ; @@ -3361,30 +3534,30 @@ SWIGINTERN PyObject *_wrap_Hive(PyObject *SWIGUNUSEDPARM(self), PyObject *args, { arg6 = &tmp6; } - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OOO:Hive",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OOO:hive_key",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Hive" "', argument " "2"" of type '" "char const *""'"); + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "hive_key" "', argument " "2"" of type '" "char const *""'"); } arg2 = (char *)(buf2); if (obj1) { res3 = SWIG_ConvertPtr(obj1, &argp3,SWIGTYPE_p_auth_session_info, 0 | 0 ); if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "Hive" "', argument " "3"" of type '" "struct auth_session_info *""'"); + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "hive_key" "', argument " "3"" of type '" "struct auth_session_info *""'"); } arg3 = (struct auth_session_info *)(argp3); } if (obj2) { res4 = SWIG_ConvertPtr(obj2, &argp4,SWIGTYPE_p_cli_credentials, 0 | 0 ); if (!SWIG_IsOK(res4)) { - SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "Hive" "', argument " "4"" of type '" "struct cli_credentials *""'"); + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "hive_key" "', argument " "4"" of type '" "struct cli_credentials *""'"); } arg4 = (struct cli_credentials *)(argp4); } if (obj3) { res5 = SWIG_ConvertPtr(obj3, &argp5,SWIGTYPE_p_loadparm_context, 0 | 0 ); if (!SWIG_IsOK(res5)) { - SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "Hive" "', argument " "5"" of type '" "struct loadparm_context *""'"); + SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "hive_key" "', argument " "5"" of type '" "struct loadparm_context *""'"); } arg5 = (struct loadparm_context *)(argp5); } @@ -3409,53 +3582,6 @@ fail: } -SWIGINTERN PyObject *_wrap_new_hive(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - hive *result = 0 ; - - if (!SWIG_Python_UnpackTuple(args,"new_hive",0,0,0)) SWIG_fail; - result = (hive *)(hive *) calloc(1, sizeof(hive)); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_hive_key, SWIG_POINTER_NEW | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_delete_hive(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - hive *arg1 = (hive *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_hive_key, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_hive" "', argument " "1"" of type '" "hive *""'"); - } - arg1 = (hive *)(argp1); - free((char *) arg1); - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *hive_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *obj; - if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; - SWIG_TypeNewClientData(SWIGTYPE_p_hive_key, SWIG_NewClientData(obj)); - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject *hive_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - return SWIG_Python_InitShadowInstance(args); -} - SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; @@ -3538,18 +3664,17 @@ static PyMethodDef SwigMethods[] = { { (char *)"str_regtype", (PyCFunction) _wrap_str_regtype, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"Registry", (PyCFunction) _wrap_Registry, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"reg_get_predefined_key_by_name", (PyCFunction) _wrap_reg_get_predefined_key_by_name, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"reg_key_del_abs", (PyCFunction) _wrap_reg_key_del_abs, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"reg_get_predefined_key", (PyCFunction) _wrap_reg_get_predefined_key, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"reg_apply_patchfile", (PyCFunction) _wrap_reg_apply_patchfile, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"reg_diff_apply", (PyCFunction) _wrap_reg_diff_apply, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"reg_generate_diff", (PyCFunction) _wrap_reg_generate_diff, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"reg_import_hive_key", (PyCFunction) _wrap_reg_import_hive_key, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"reg_mount_hive", _wrap_reg_mount_hive, METH_VARARGS, NULL}, { (char *)"new_reg", (PyCFunction)_wrap_new_reg, METH_NOARGS, NULL}, { (char *)"delete_reg", (PyCFunction)_wrap_delete_reg, METH_O, NULL}, { (char *)"reg_swigregister", reg_swigregister, METH_VARARGS, NULL}, { (char *)"reg_swiginit", reg_swiginit, METH_VARARGS, NULL}, - { (char *)"Hive", (PyCFunction) _wrap_Hive, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"new_hive", (PyCFunction)_wrap_new_hive, METH_NOARGS, NULL}, - { (char *)"delete_hive", (PyCFunction)_wrap_delete_hive, METH_O, NULL}, - { (char *)"hive_swigregister", hive_swigregister, METH_VARARGS, NULL}, - { (char *)"hive_swiginit", hive_swiginit, METH_VARARGS, NULL}, + { (char *)"hive_key", (PyCFunction) _wrap_hive_key, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"open_samba", (PyCFunction) _wrap_open_samba, METH_VARARGS | METH_KEYWORDS, NULL}, { NULL, NULL, 0, NULL } }; @@ -3561,7 +3686,7 @@ static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0 static swig_type_info _swigt__p_auth_session_info = {"_p_auth_session_info", "struct auth_session_info *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_cli_credentials = {"_p_cli_credentials", "struct cli_credentials *|cli_credentials *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_hive_key = {"_p_hive_key", "struct hive_key *|hive *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_hive_key = {"_p_hive_key", "struct hive_key *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_loadparm_context = {"_p_loadparm_context", "struct loadparm_context *|loadparm_context *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_loadparm_service = {"_p_loadparm_service", "struct loadparm_service *|loadparm_service *", 0, 0, (void*)0, 0}; @@ -3573,7 +3698,9 @@ static swig_type_info _swigt__p_p_registry_key = {"_p_p_registry_key", "struct r static swig_type_info _swigt__p_param_context = {"_p_param_context", "struct param_context *|param *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_param_opt = {"_p_param_opt", "struct param_opt *|param_opt *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_param_section = {"_p_param_section", "struct param_section *|param_section *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_reg_diff_callbacks = {"_p_reg_diff_callbacks", "struct reg_diff_callbacks *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_registry_context = {"_p_registry_context", "struct registry_context *|reg *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_registry_key = {"_p_registry_key", "struct registry_key *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "unsigned char *|uint_least8_t *|uint_fast8_t *|uint8_t *", 0, 0, (void*)0, 0}; @@ -3598,7 +3725,9 @@ static swig_type_info *swig_type_initial[] = { &_swigt__p_param_context, &_swigt__p_param_opt, &_swigt__p_param_section, + &_swigt__p_reg_diff_callbacks, &_swigt__p_registry_context, + &_swigt__p_registry_key, &_swigt__p_short, &_swigt__p_signed_char, &_swigt__p_unsigned_char, @@ -3623,7 +3752,9 @@ static swig_cast_info _swigc__p_p_registry_key[] = { {&_swigt__p_p_registry_key static swig_cast_info _swigc__p_param_context[] = { {&_swigt__p_param_context, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_param_opt[] = { {&_swigt__p_param_opt, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_param_section[] = { {&_swigt__p_param_section, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_reg_diff_callbacks[] = { {&_swigt__p_reg_diff_callbacks, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_registry_context[] = { {&_swigt__p_registry_context, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_registry_key[] = { {&_swigt__p_registry_key, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_short[] = { {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_signed_char[] = { {&_swigt__p_signed_char, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}}; @@ -3648,7 +3779,9 @@ static swig_cast_info *swig_cast_initial[] = { _swigc__p_param_context, _swigc__p_param_opt, _swigc__p_param_section, + _swigc__p_reg_diff_callbacks, _swigc__p_registry_context, + _swigc__p_registry_key, _swigc__p_short, _swigc__p_signed_char, _swigc__p_unsigned_char, diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index fdb7282395..e3a301710f 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -211,13 +211,13 @@ static bool test_del_value(struct torture_context *tctx, const void *test_data) data_blob_talloc(mem_ctx, &data, sizeof(data))); torture_assert_werr_ok(tctx, error, "hive_set_value"); - error = hive_del_value(subkey, "Answer"); + error = hive_key_del_value(subkey, "Answer"); torture_assert_werr_ok(tctx, error, "deleting value"); error = hive_get_value(mem_ctx, subkey, "Answer", &type, &value); torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "getting value"); - error = hive_del_value(subkey, "Answer"); + error = hive_key_del_value(subkey, "Answer"); torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "deleting value"); -- cgit From 249cc734cebfef31320ec10b05dbfaaaa39682ca Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 Dec 2007 05:03:02 -0600 Subject: r26565: Fix python registry bindings. 'PROVISION_PYTHON=yes make test' works now. (This used to be commit 485d1fa3d17fe6cc7a0ecd80e8bac42d173bbb19) --- source4/lib/registry/hive.c | 2 +- source4/lib/registry/hive.h | 2 +- source4/lib/registry/local.c | 2 +- source4/lib/registry/registry.h | 3 - source4/lib/registry/registry.i | 16 +++ source4/lib/registry/registry.py | 3 + source4/lib/registry/registry_wrap.c | 189 +++++++++++++++++++++++++++++++++ source4/lib/registry/tests/bindings.py | 18 ++++ source4/lib/registry/tests/hive.c | 20 ++-- 9 files changed, 239 insertions(+), 16 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/hive.c b/source4/lib/registry/hive.c index 6a1623338d..d7d12076f3 100644 --- a/source4/lib/registry/hive.c +++ b/source4/lib/registry/hive.c @@ -107,7 +107,7 @@ WERROR hive_enum_key(TALLOC_CTX *mem_ctx, last_mod_time); } -WERROR hive_set_value(struct hive_key *key, const char *name, uint32_t type, +WERROR hive_key_set_value(struct hive_key *key, const char *name, uint32_t type, const DATA_BLOB data) { if (key->ops->set_value == NULL) diff --git a/source4/lib/registry/hive.h b/source4/lib/registry/hive.h index e82177d8b8..1e05f6b013 100644 --- a/source4/lib/registry/hive.h +++ b/source4/lib/registry/hive.h @@ -164,7 +164,7 @@ WERROR hive_enum_key(TALLOC_CTX *mem_ctx, const char **classname, NTTIME *last_mod_time); -WERROR hive_set_value(struct hive_key *key, const char *name, +WERROR hive_key_set_value(struct hive_key *key, const char *name, uint32_t type, const DATA_BLOB data); WERROR hive_get_value(TALLOC_CTX *mem_ctx, diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index 06c9031055..14b42797ba 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -216,7 +216,7 @@ static WERROR local_set_value(struct registry_key *key, const char *name, { struct local_key *local = (struct local_key *)key; - return hive_set_value(local->hive_key, name, type, data); + return hive_key_set_value(local->hive_key, name, type, data); } static WERROR local_get_value(TALLOC_CTX *mem_ctx, diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index a02acbea1e..7999719909 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -247,9 +247,6 @@ WERROR reg_create_key(TALLOC_CTX *mem_ctx, struct security_descriptor *security, struct registry_key **key); - - - /* Utility functions */ const char *str_regtype(int type); char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i index 315afb0c31..3fabba9a66 100644 --- a/source4/lib/registry/registry.i +++ b/source4/lib/registry/registry.i @@ -137,6 +137,21 @@ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, struct loadparm_context *lp_ctx, struct hive_key **root); +%rename(open_ldb) reg_open_ldb_file; +WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + struct loadparm_context *lp_ctx, + struct hive_key **k); + +%rename(create_dir) reg_create_directory; +WERROR reg_create_directory(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key); + +%rename(open_dir) reg_open_directory; +WERROR reg_open_directory(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key); + %talloctype(hive_key); typedef struct hive_key { @@ -144,6 +159,7 @@ typedef struct hive_key { WERROR del(const char *name); WERROR flush(void); WERROR del_value(const char *name); + WERROR set_value(const char *name, uint32_t type, const DATA_BLOB data); } } hive_key; diff --git a/source4/lib/registry/registry.py b/source4/lib/registry/registry.py index ff5653e915..bf8ac60498 100644 --- a/source4/lib/registry/registry.py +++ b/source4/lib/registry/registry.py @@ -79,6 +79,9 @@ reg_swigregister = _registry.reg_swigregister reg_swigregister(reg) hive_key = _registry.hive_key +open_ldb = _registry.open_ldb +create_dir = _registry.create_dir +open_dir = _registry.open_dir open_samba = _registry.open_samba HKEY_CLASSES_ROOT = _registry.HKEY_CLASSES_ROOT HKEY_CURRENT_USER = _registry.HKEY_CURRENT_USER diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index ab6c2fb5e9..c02f9cacc6 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -3582,6 +3582,192 @@ fail: } +SWIGINTERN PyObject *_wrap_open_ldb(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; + char *arg2 = (char *) 0 ; + struct auth_session_info *arg3 = (struct auth_session_info *) 0 ; + struct cli_credentials *arg4 = (struct cli_credentials *) 0 ; + struct loadparm_context *arg5 = (struct loadparm_context *) 0 ; + struct hive_key **arg6 = (struct hive_key **) 0 ; + WERROR result; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + void *argp3 = 0 ; + int res3 = 0 ; + void *argp4 = 0 ; + int res4 = 0 ; + void *argp5 = 0 ; + int res5 = 0 ; + struct hive_key *tmp6 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + PyObject * obj3 = 0 ; + char * kwnames[] = { + (char *) "location",(char *) "session_info",(char *) "credentials",(char *) "lp_ctx", NULL + }; + + { + arg3 = NULL; + } + { + arg4 = NULL; + } + { + arg5 = loadparm_init(NULL); + } + { + arg1 = NULL; + } + { + arg6 = &tmp6; + } + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OOO:open_ldb",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; + res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "open_ldb" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = (char *)(buf2); + if (obj1) { + res3 = SWIG_ConvertPtr(obj1, &argp3,SWIGTYPE_p_auth_session_info, 0 | 0 ); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "open_ldb" "', argument " "3"" of type '" "struct auth_session_info *""'"); + } + arg3 = (struct auth_session_info *)(argp3); + } + if (obj2) { + res4 = SWIG_ConvertPtr(obj2, &argp4,SWIGTYPE_p_cli_credentials, 0 | 0 ); + if (!SWIG_IsOK(res4)) { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "open_ldb" "', argument " "4"" of type '" "struct cli_credentials *""'"); + } + arg4 = (struct cli_credentials *)(argp4); + } + if (obj3) { + res5 = SWIG_ConvertPtr(obj3, &argp5,SWIGTYPE_p_loadparm_context, 0 | 0 ); + if (!SWIG_IsOK(res5)) { + SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "open_ldb" "', argument " "5"" of type '" "struct loadparm_context *""'"); + } + arg5 = (struct loadparm_context *)(argp5); + } + result = reg_open_ldb_file(arg1,(char const *)arg2,arg3,arg4,arg5,arg6); + { + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + { + Py_XDECREF(resultobj); + resultobj = SWIG_NewPointerObj(*arg6, SWIGTYPE_p_hive_key, 0); + } + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_create_dir(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; + char *arg2 = (char *) 0 ; + struct hive_key **arg3 = (struct hive_key **) 0 ; + WERROR result; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + struct hive_key *tmp3 ; + PyObject * obj0 = 0 ; + char * kwnames[] = { + (char *) "location", NULL + }; + + { + arg1 = NULL; + } + { + arg3 = &tmp3; + } + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:create_dir",kwnames,&obj0)) SWIG_fail; + res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "create_dir" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = (char *)(buf2); + result = reg_create_directory(arg1,(char const *)arg2,arg3); + { + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + { + Py_XDECREF(resultobj); + resultobj = SWIG_NewPointerObj(*arg3, SWIGTYPE_p_hive_key, 0); + } + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_open_dir(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; + char *arg2 = (char *) 0 ; + struct hive_key **arg3 = (struct hive_key **) 0 ; + WERROR result; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + struct hive_key *tmp3 ; + PyObject * obj0 = 0 ; + char * kwnames[] = { + (char *) "location", NULL + }; + + { + arg1 = NULL; + } + { + arg3 = &tmp3; + } + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:open_dir",kwnames,&obj0)) SWIG_fail; + res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "open_dir" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = (char *)(buf2); + result = reg_open_directory(arg1,(char const *)arg2,arg3); + { + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + { + Py_XDECREF(resultobj); + resultobj = SWIG_NewPointerObj(*arg3, SWIGTYPE_p_hive_key, 0); + } + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; @@ -3675,6 +3861,9 @@ static PyMethodDef SwigMethods[] = { { (char *)"reg_swigregister", reg_swigregister, METH_VARARGS, NULL}, { (char *)"reg_swiginit", reg_swiginit, METH_VARARGS, NULL}, { (char *)"hive_key", (PyCFunction) _wrap_hive_key, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"open_ldb", (PyCFunction) _wrap_open_ldb, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"create_dir", (PyCFunction) _wrap_create_dir, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"open_dir", (PyCFunction) _wrap_open_dir, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"open_samba", (PyCFunction) _wrap_open_samba, METH_VARARGS | METH_KEYWORDS, NULL}, { NULL, NULL, 0, NULL } }; diff --git a/source4/lib/registry/tests/bindings.py b/source4/lib/registry/tests/bindings.py index be87efe594..9f93ee9382 100644 --- a/source4/lib/registry/tests/bindings.py +++ b/source4/lib/registry/tests/bindings.py @@ -17,8 +17,10 @@ # along with this program. If not, see . # +import os import unittest import registry +import samba.tests class HelperTests(unittest.TestCase): def test_predef_to_name(self): @@ -29,6 +31,22 @@ class HelperTests(unittest.TestCase): self.assertEquals("REG_DWORD", registry.str_regtype(4)) + +class HiveTests(samba.tests.TestCaseInTempDir): + def setUp(self): + super(HiveTests, self).setUp() + self.hive = registry.open_ldb(os.path.join(self.tempdir, "ldb_new.ldb")) + + def test_ldb_new(self): + self.assertTrue(self.hive is not None) + + def test_flush(self): + self.hive.flush() + + def test_del_value(self): + self.hive.del_value("FOO") + + class RegistryTests(unittest.TestCase): def test_new(self): self.registry = registry.Registry() diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index e3a301710f..43ec9e4252 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -74,9 +74,9 @@ static bool test_keyinfo_nums(struct torture_context *tctx, NULL, &subkey); torture_assert_werr_ok(tctx, error, "hive_key_add_name"); - error = hive_set_value(root, "Answer", REG_DWORD, + error = hive_key_set_value(root, "Answer", REG_DWORD, data_blob_talloc(tctx, &data, sizeof(data))); - torture_assert_werr_ok(tctx, error, "hive_set_value"); + torture_assert_werr_ok(tctx, error, "hive_key_set_value"); /* This is a new backend. There should be no subkeys and no * values */ @@ -154,9 +154,9 @@ static bool test_set_value(struct torture_context *tctx, NULL, &subkey); torture_assert_werr_ok(tctx, error, "hive_key_add_name"); - error = hive_set_value(subkey, "Answer", REG_DWORD, + error = hive_key_set_value(subkey, "Answer", REG_DWORD, data_blob_talloc(mem_ctx, &data, sizeof(data))); - torture_assert_werr_ok(tctx, error, "hive_set_value"); + torture_assert_werr_ok(tctx, error, "hive_key_set_value"); return true; } @@ -179,9 +179,9 @@ static bool test_get_value(struct torture_context *tctx, const void *test_data) torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "getting missing value"); - error = hive_set_value(subkey, "Answer", REG_DWORD, + error = hive_key_set_value(subkey, "Answer", REG_DWORD, data_blob_talloc(mem_ctx, &data, sizeof(data))); - torture_assert_werr_ok(tctx, error, "hive_set_value"); + torture_assert_werr_ok(tctx, error, "hive_key_set_value"); error = hive_get_value(mem_ctx, subkey, "Answer", &type, &value); torture_assert_werr_ok(tctx, error, "getting value"); @@ -207,9 +207,9 @@ static bool test_del_value(struct torture_context *tctx, const void *test_data) NULL, &subkey); torture_assert_werr_ok(tctx, error, "hive_key_add_name"); - error = hive_set_value(subkey, "Answer", REG_DWORD, + error = hive_key_set_value(subkey, "Answer", REG_DWORD, data_blob_talloc(mem_ctx, &data, sizeof(data))); - torture_assert_werr_ok(tctx, error, "hive_set_value"); + torture_assert_werr_ok(tctx, error, "hive_key_set_value"); error = hive_key_del_value(subkey, "Answer"); torture_assert_werr_ok(tctx, error, "deleting value"); @@ -240,9 +240,9 @@ static bool test_list_values(struct torture_context *tctx, NULL, &subkey); torture_assert_werr_ok(tctx, error, "hive_key_add_name"); - error = hive_set_value(subkey, "Answer", REG_DWORD, + error = hive_key_set_value(subkey, "Answer", REG_DWORD, data_blob_talloc(mem_ctx, &data, sizeof(data))); - torture_assert_werr_ok(tctx, error, "hive_set_value"); + torture_assert_werr_ok(tctx, error, "hive_key_set_value"); error = hive_get_value_by_index(mem_ctx, subkey, 0, &name, &type, &value); -- cgit From aa0a06f13c44e0eca0b3f2f0c34f0f7995b87159 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 Dec 2007 19:19:41 -0600 Subject: r26570: - Trim size of the swig-generated Python bindings by removing a bunch of {}'s. - Start working on Python equivalents for various EJS tests. - Fix regression in argument order for reg_diff_apply() in EJS bindings. (This used to be commit c550c03372cb260b78f6a6c132e70571bc4cb852) --- source4/lib/registry/registry.i | 14 +- source4/lib/registry/registry_wrap.c | 367 +++++++++++++-------------------- source4/lib/registry/tests/bindings.py | 8 +- 3 files changed, 160 insertions(+), 229 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i index 3fabba9a66..6f46e081c2 100644 --- a/source4/lib/registry/registry.i +++ b/source4/lib/registry/registry.i @@ -32,7 +32,7 @@ typedef struct hive_key hive_key; %} /* FIXME: This should be in another file */ -%typemap(default) struct auth_session_info * { +%typemap(default,noblock=1) struct auth_session_info * { $1 = NULL; } @@ -48,11 +48,11 @@ const char *reg_get_predef_name(uint32_t hkey); const char *str_regtype(int type); /* Registry contexts */ -%typemap(in,numinputs=0) struct registry_context ** (struct registry_context *tmp) { +%typemap(in,noblock=1,numinputs=0) struct registry_context ** (struct registry_context *tmp) { $1 = &tmp; } -%typemap(argout) struct registry_context ** { +%typemap(argout,noblock=1) struct registry_context ** { $result = SWIG_NewPointerObj(*$1, SWIGTYPE_p_registry_context, 0); } @@ -61,7 +61,7 @@ WERROR reg_open_local(TALLOC_CTX *parent_ctx, struct registry_context **ctx, struct auth_session_info *session_info, struct cli_credentials *credentials); -%typemap(in) const char ** { +%typemap(in,noblock=1) const char ** { /* Check if is a list */ if (PyList_Check($input)) { int size = PyList_Size($input); @@ -84,7 +84,7 @@ WERROR reg_open_local(TALLOC_CTX *parent_ctx, struct registry_context **ctx, } } -%typemap(freearg) const char ** { +%typemap(freearg,noblock=1) const char ** { free((char **) $1); } @@ -121,11 +121,11 @@ typedef struct registry_context { } reg; /* Hives */ -%typemap(in,numinputs=0) struct hive_key ** (struct hive_key *tmp) { +%typemap(in,noblock=1,numinputs=0) struct hive_key ** (struct hive_key *tmp) { $1 = &tmp; } -%typemap(argout) struct hive_key ** { +%typemap(argout,noblock=1) struct hive_key ** { Py_XDECREF($result); $result = SWIG_NewPointerObj(*$1, SWIGTYPE_p_hive_key, 0); } diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index c02f9cacc6..cabdfad887 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -2928,18 +2928,12 @@ SWIGINTERN PyObject *_wrap_Registry(PyObject *SWIGUNUSEDPARM(self), PyObject *ar (char *) "session_info",(char *) "credentials", NULL }; - { - arg3 = NULL; - } + arg3 = NULL; { arg4 = NULL; } - { - arg1 = NULL; - } - { - arg2 = &tmp2; - } + arg1 = NULL; + arg2 = &tmp2; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|OO:Registry",kwnames,&obj0,&obj1)) SWIG_fail; if (obj0) { res3 = SWIG_ConvertPtr(obj0, &argp3,SWIGTYPE_p_auth_session_info, 0 | 0 ); @@ -2956,17 +2950,14 @@ SWIGINTERN PyObject *_wrap_Registry(PyObject *SWIGUNUSEDPARM(self), PyObject *ar arg4 = (struct cli_credentials *)(argp4); } result = reg_open_local(arg1,arg2,arg3,arg4); - { - if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } - } - { - resultobj = SWIG_NewPointerObj(*arg2, SWIGTYPE_p_registry_context, 0); - } + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; + } + resultobj = SWIG_NewPointerObj(*arg2, SWIGTYPE_p_registry_context, 0); return resultobj; fail: return NULL; @@ -3010,13 +3001,12 @@ SWIGINTERN PyObject *_wrap_reg_get_predefined_key_by_name(PyObject *SWIGUNUSEDPA } arg3 = (struct registry_key **)(argp3); result = reg_get_predefined_key_by_name(arg1,(char const *)arg2,arg3); - { - if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; } if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); return resultobj; @@ -3054,13 +3044,12 @@ SWIGINTERN PyObject *_wrap_reg_key_del_abs(PyObject *SWIGUNUSEDPARM(self), PyObj } arg2 = (char *)(buf2); result = reg_key_del_abs(arg1,(char const *)arg2); - { - if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; } if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); return resultobj; @@ -3106,13 +3095,12 @@ SWIGINTERN PyObject *_wrap_reg_get_predefined_key(PyObject *SWIGUNUSEDPARM(self) } arg3 = (struct registry_key **)(argp3); result = reg_get_predefined_key(arg1,arg2,arg3); - { - if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; } return resultobj; fail: @@ -3148,13 +3136,12 @@ SWIGINTERN PyObject *_wrap_reg_diff_apply(PyObject *SWIGUNUSEDPARM(self), PyObje } arg2 = (char *)(buf2); result = reg_diff_apply(arg1,(char const *)arg2); - { - if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; } if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); return resultobj; @@ -3207,13 +3194,12 @@ SWIGINTERN PyObject *_wrap_reg_generate_diff(PyObject *SWIGUNUSEDPARM(self), PyO SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "reg_generate_diff" "', argument " "4"" of type '" "void *""'"); } result = reg_generate_diff(arg1,arg2,(struct reg_diff_callbacks const *)arg3,arg4); - { - if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; } return resultobj; fail: @@ -3252,46 +3238,39 @@ SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_0(PyObject *SWIGUNUSEDPARM(self) } arg3 = (uint32_t)(val3); if (swig_obj[3]) { - { - /* Check if is a list */ - if (PyList_Check(swig_obj[3])) { - int size = PyList_Size(swig_obj[3]); - int i = 0; - arg4 = (char **) malloc((size+1)*sizeof(const char *)); - for (i = 0; i < size; i++) { - PyObject *o = PyList_GetItem(swig_obj[3],i); - if (PyString_Check(o)) - arg4[i] = PyString_AsString(PyList_GetItem(swig_obj[3],i)); - else { - PyErr_SetString(PyExc_TypeError,"list must contain strings"); - free(arg4); - return NULL; - } + /* Check if is a list */ + if (PyList_Check(swig_obj[3])) { + int size = PyList_Size(swig_obj[3]); + int i = 0; + arg4 = (char **) malloc((size+1)*sizeof(const char *)); + for (i = 0; i < size; i++) { + PyObject *o = PyList_GetItem(swig_obj[3],i); + if (PyString_Check(o)) + arg4[i] = PyString_AsString(PyList_GetItem(swig_obj[3],i)); + else { + PyErr_SetString(PyExc_TypeError,"list must contain strings"); + free(arg4); + return NULL; } - arg4[i] = 0; - } else { - PyErr_SetString(PyExc_TypeError,"not a list"); - return NULL; } + arg4[i] = 0; + } else { + PyErr_SetString(PyExc_TypeError,"not a list"); + return NULL; } } result = reg_mount_hive(arg1,arg2,arg3,(char const **)arg4); - { - if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } - } - { - free((char **) arg4); - } + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; + } + free((char **) arg4); return resultobj; fail: - { - free((char **) arg4); - } + free((char **) arg4); return NULL; } @@ -3333,38 +3312,32 @@ SWIGINTERN PyObject *_wrap_reg_import_hive_key(PyObject *SWIGUNUSEDPARM(self), P SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "reg_import_hive_key" "', argument " "3"" of type '" "uint32_t""'"); } arg3 = (uint32_t)(val3); - { - /* Check if is a list */ - if (PyList_Check(obj3)) { - int size = PyList_Size(obj3); - int i = 0; - arg4 = (char **) malloc((size+1)*sizeof(const char *)); - for (i = 0; i < size; i++) { - PyObject *o = PyList_GetItem(obj3,i); - if (PyString_Check(o)) - arg4[i] = PyString_AsString(PyList_GetItem(obj3,i)); - else { - PyErr_SetString(PyExc_TypeError,"list must contain strings"); - free(arg4); - return NULL; - } + /* Check if is a list */ + if (PyList_Check(obj3)) { + int size = PyList_Size(obj3); + int i = 0; + arg4 = (char **) malloc((size+1)*sizeof(const char *)); + for (i = 0; i < size; i++) { + PyObject *o = PyList_GetItem(obj3,i); + if (PyString_Check(o)) + arg4[i] = PyString_AsString(PyList_GetItem(obj3,i)); + else { + PyErr_SetString(PyExc_TypeError,"list must contain strings"); + free(arg4); + return NULL; } - arg4[i] = 0; - } else { - PyErr_SetString(PyExc_TypeError,"not a list"); - return NULL; } + arg4[i] = 0; + } else { + PyErr_SetString(PyExc_TypeError,"not a list"); + return NULL; } result = (struct registry_key *)reg_import_hive_key(arg1,arg2,arg3,(char const **)arg4); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_registry_key, 0 | 0 ); - { - free((char **) arg4); - } + free((char **) arg4); return resultobj; fail: - { - free((char **) arg4); - } + free((char **) arg4); return NULL; } @@ -3400,13 +3373,12 @@ SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_1(PyObject *SWIGUNUSEDPARM(self) } arg3 = (char *)(buf3); result = reg_mount_hive__SWIG_1(arg1,arg2,(char const *)arg3); - { - if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; } if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); return resultobj; @@ -3519,21 +3491,15 @@ SWIGINTERN PyObject *_wrap_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *ar (char *) "location",(char *) "session_info",(char *) "credentials",(char *) "lp_ctx", NULL }; - { - arg3 = NULL; - } + arg3 = NULL; { arg4 = NULL; } { arg5 = loadparm_init(NULL); } - { - arg1 = NULL; - } - { - arg6 = &tmp6; - } + arg1 = NULL; + arg6 = &tmp6; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OOO:hive_key",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); if (!SWIG_IsOK(res2)) { @@ -3562,18 +3528,15 @@ SWIGINTERN PyObject *_wrap_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *ar arg5 = (struct loadparm_context *)(argp5); } result = reg_open_hive(arg1,(char const *)arg2,arg3,arg4,arg5,arg6); - { - if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } - } - { - Py_XDECREF(resultobj); - resultobj = SWIG_NewPointerObj(*arg6, SWIGTYPE_p_hive_key, 0); - } + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; + } + Py_XDECREF(resultobj); + resultobj = SWIG_NewPointerObj(*arg6, SWIGTYPE_p_hive_key, 0); if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); return resultobj; fail: @@ -3609,21 +3572,15 @@ SWIGINTERN PyObject *_wrap_open_ldb(PyObject *SWIGUNUSEDPARM(self), PyObject *ar (char *) "location",(char *) "session_info",(char *) "credentials",(char *) "lp_ctx", NULL }; - { - arg3 = NULL; - } + arg3 = NULL; { arg4 = NULL; } { arg5 = loadparm_init(NULL); } - { - arg1 = NULL; - } - { - arg6 = &tmp6; - } + arg1 = NULL; + arg6 = &tmp6; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OOO:open_ldb",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); if (!SWIG_IsOK(res2)) { @@ -3652,18 +3609,15 @@ SWIGINTERN PyObject *_wrap_open_ldb(PyObject *SWIGUNUSEDPARM(self), PyObject *ar arg5 = (struct loadparm_context *)(argp5); } result = reg_open_ldb_file(arg1,(char const *)arg2,arg3,arg4,arg5,arg6); - { - if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } - } - { - Py_XDECREF(resultobj); - resultobj = SWIG_NewPointerObj(*arg6, SWIGTYPE_p_hive_key, 0); - } + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; + } + Py_XDECREF(resultobj); + resultobj = SWIG_NewPointerObj(*arg6, SWIGTYPE_p_hive_key, 0); if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); return resultobj; fail: @@ -3687,12 +3641,8 @@ SWIGINTERN PyObject *_wrap_create_dir(PyObject *SWIGUNUSEDPARM(self), PyObject * (char *) "location", NULL }; - { - arg1 = NULL; - } - { - arg3 = &tmp3; - } + arg1 = NULL; + arg3 = &tmp3; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:create_dir",kwnames,&obj0)) SWIG_fail; res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); if (!SWIG_IsOK(res2)) { @@ -3700,18 +3650,15 @@ SWIGINTERN PyObject *_wrap_create_dir(PyObject *SWIGUNUSEDPARM(self), PyObject * } arg2 = (char *)(buf2); result = reg_create_directory(arg1,(char const *)arg2,arg3); - { - if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } - } - { - Py_XDECREF(resultobj); - resultobj = SWIG_NewPointerObj(*arg3, SWIGTYPE_p_hive_key, 0); - } + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; + } + Py_XDECREF(resultobj); + resultobj = SWIG_NewPointerObj(*arg3, SWIGTYPE_p_hive_key, 0); if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); return resultobj; fail: @@ -3735,12 +3682,8 @@ SWIGINTERN PyObject *_wrap_open_dir(PyObject *SWIGUNUSEDPARM(self), PyObject *ar (char *) "location", NULL }; - { - arg1 = NULL; - } - { - arg3 = &tmp3; - } + arg1 = NULL; + arg3 = &tmp3; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:open_dir",kwnames,&obj0)) SWIG_fail; res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); if (!SWIG_IsOK(res2)) { @@ -3748,18 +3691,15 @@ SWIGINTERN PyObject *_wrap_open_dir(PyObject *SWIGUNUSEDPARM(self), PyObject *ar } arg2 = (char *)(buf2); result = reg_open_directory(arg1,(char const *)arg2,arg3); - { - if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } - } - { - Py_XDECREF(resultobj); - resultobj = SWIG_NewPointerObj(*arg3, SWIGTYPE_p_hive_key, 0); - } + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; + } + Py_XDECREF(resultobj); + resultobj = SWIG_NewPointerObj(*arg3, SWIGTYPE_p_hive_key, 0); if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); return resultobj; fail: @@ -3793,18 +3733,12 @@ SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject * { arg3 = loadparm_init(NULL); } - { - arg4 = NULL; - } + arg4 = NULL; { arg5 = NULL; } - { - arg1 = NULL; - } - { - arg2 = &tmp2; - } + arg1 = NULL; + arg2 = &tmp2; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|OOO:open_samba",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; if (obj0) { res3 = SWIG_ConvertPtr(obj0, &argp3,SWIGTYPE_p_loadparm_context, 0 | 0 ); @@ -3828,17 +3762,14 @@ SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject * arg5 = (struct cli_credentials *)(argp5); } result = reg_open_samba(arg1,arg2,arg3,arg4,arg5); - { - if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } - } - { - resultobj = SWIG_NewPointerObj(*arg2, SWIGTYPE_p_registry_context, 0); - } + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; + } + resultobj = SWIG_NewPointerObj(*arg2, SWIGTYPE_p_registry_context, 0); return resultobj; fail: return NULL; diff --git a/source4/lib/registry/tests/bindings.py b/source4/lib/registry/tests/bindings.py index 9f93ee9382..906deed7e9 100644 --- a/source4/lib/registry/tests/bindings.py +++ b/source4/lib/registry/tests/bindings.py @@ -40,11 +40,11 @@ class HiveTests(samba.tests.TestCaseInTempDir): def test_ldb_new(self): self.assertTrue(self.hive is not None) - def test_flush(self): - self.hive.flush() + #def test_flush(self): + # self.hive.flush() - def test_del_value(self): - self.hive.del_value("FOO") + #def test_del_value(self): + # self.hive.del_value("FOO") class RegistryTests(unittest.TestCase): -- cgit From 3ee442c54f658e0dc9541a492e46fd8f6bf3a7f4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 Dec 2007 20:22:46 -0600 Subject: r26571: Hide warnings about unused macros and casting qualifiers in autogenerated files. (This used to be commit cb76c60007ae1254181c09ba1ab09c419f500bc5) --- source4/lib/registry/registry_wrap.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index cabdfad887..00c7fc32b2 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -2929,9 +2929,7 @@ SWIGINTERN PyObject *_wrap_Registry(PyObject *SWIGUNUSEDPARM(self), PyObject *ar }; arg3 = NULL; - { - arg4 = NULL; - } + arg4 = NULL; arg1 = NULL; arg2 = &tmp2; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|OO:Registry",kwnames,&obj0,&obj1)) SWIG_fail; @@ -3492,12 +3490,8 @@ SWIGINTERN PyObject *_wrap_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *ar }; arg3 = NULL; - { - arg4 = NULL; - } - { - arg5 = loadparm_init(NULL); - } + arg4 = NULL; + arg5 = loadparm_init(NULL); arg1 = NULL; arg6 = &tmp6; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OOO:hive_key",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; @@ -3573,12 +3567,8 @@ SWIGINTERN PyObject *_wrap_open_ldb(PyObject *SWIGUNUSEDPARM(self), PyObject *ar }; arg3 = NULL; - { - arg4 = NULL; - } - { - arg5 = loadparm_init(NULL); - } + arg4 = NULL; + arg5 = loadparm_init(NULL); arg1 = NULL; arg6 = &tmp6; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OOO:open_ldb",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; @@ -3730,13 +3720,9 @@ SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject * (char *) "lp_ctx",(char *) "session_info",(char *) "credentials", NULL }; - { - arg3 = loadparm_init(NULL); - } + arg3 = loadparm_init(NULL); arg4 = NULL; - { - arg5 = NULL; - } + arg5 = NULL; arg1 = NULL; arg2 = &tmp2; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|OOO:open_samba",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; -- cgit From d0ba9f001474bfee9b1e8fb516effab736cd4050 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 Dec 2007 20:56:41 -0600 Subject: r26572: Fix warnings in the Python code. (This used to be commit 15038d9586d0b58f301ca8c39c21ef10c4283f28) --- source4/lib/registry/registry.i | 7 ++++--- source4/lib/registry/registry_wrap.c | 31 ++++++++++++++++--------------- 2 files changed, 20 insertions(+), 18 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i index 6f46e081c2..20ae671c75 100644 --- a/source4/lib/registry/registry.i +++ b/source4/lib/registry/registry.i @@ -26,6 +26,7 @@ #include "includes.h" #include "registry.h" #include "param/param.h" +#include "hive.h" typedef struct registry_context reg; typedef struct hive_key hive_key; @@ -102,16 +103,16 @@ typedef struct registry_context { WERROR generate_diff(struct registry_context *ctx2, const struct reg_diff_callbacks *callbacks, void *callback_data); - WERROR mount_hive(struct hive_key *hive_key, uint32_t hkey_id, + WERROR mount_hive(struct hive_key *key, uint32_t hkey_id, const char **elements=NULL); struct registry_key *import_hive_key(struct hive_key *hive, uint32_t predef_key, const char **elements); - WERROR mount_hive(struct hive_key *hive_key, const char *predef_name) + WERROR mount_hive(struct hive_key *key, const char *predef_name) { int i; for (i = 0; reg_predefined_keys[i].name; i++) { if (!strcasecmp(reg_predefined_keys[i].name, predef_name)) - return reg_mount_hive($self, hive_key, + return reg_mount_hive($self, key, reg_predefined_keys[i].handle, NULL); } return WERR_INVALID_NAME; diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index 00c7fc32b2..c5741b7e2c 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -2529,6 +2529,7 @@ static swig_module_info swig_module = {swig_types, 25, 0, 0, 0, 0}; #include "includes.h" #include "registry.h" #include "param/param.h" +#include "hive.h" typedef struct registry_context reg; typedef struct hive_key hive_key; @@ -2830,11 +2831,11 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) -SWIGINTERN WERROR reg_mount_hive__SWIG_1(reg *self,struct hive_key *hive_key,char const *predef_name){ +SWIGINTERN WERROR reg_mount_hive__SWIG_1(reg *self,struct hive_key *key,char const *predef_name){ int i; for (i = 0; reg_predefined_keys[i].name; i++) { if (!strcasecmp(reg_predefined_keys[i].name, predef_name)) - return reg_mount_hive(self, hive_key, + return reg_mount_hive(self, key, reg_predefined_keys[i].handle, NULL); } return WERR_INVALID_NAME; @@ -2949,7 +2950,7 @@ SWIGINTERN PyObject *_wrap_Registry(PyObject *SWIGUNUSEDPARM(self), PyObject *ar } result = reg_open_local(arg1,arg2,arg3,arg4); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3000,7 +3001,7 @@ SWIGINTERN PyObject *_wrap_reg_get_predefined_key_by_name(PyObject *SWIGUNUSEDPA arg3 = (struct registry_key **)(argp3); result = reg_get_predefined_key_by_name(arg1,(char const *)arg2,arg3); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3043,7 +3044,7 @@ SWIGINTERN PyObject *_wrap_reg_key_del_abs(PyObject *SWIGUNUSEDPARM(self), PyObj arg2 = (char *)(buf2); result = reg_key_del_abs(arg1,(char const *)arg2); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3094,7 +3095,7 @@ SWIGINTERN PyObject *_wrap_reg_get_predefined_key(PyObject *SWIGUNUSEDPARM(self) arg3 = (struct registry_key **)(argp3); result = reg_get_predefined_key(arg1,arg2,arg3); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3135,7 +3136,7 @@ SWIGINTERN PyObject *_wrap_reg_diff_apply(PyObject *SWIGUNUSEDPARM(self), PyObje arg2 = (char *)(buf2); result = reg_diff_apply(arg1,(char const *)arg2); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3193,7 +3194,7 @@ SWIGINTERN PyObject *_wrap_reg_generate_diff(PyObject *SWIGUNUSEDPARM(self), PyO } result = reg_generate_diff(arg1,arg2,(struct reg_diff_callbacks const *)arg3,arg4); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3259,7 +3260,7 @@ SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_0(PyObject *SWIGUNUSEDPARM(self) } result = reg_mount_hive(arg1,arg2,arg3,(char const **)arg4); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3372,7 +3373,7 @@ SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_1(PyObject *SWIGUNUSEDPARM(self) arg3 = (char *)(buf3); result = reg_mount_hive__SWIG_1(arg1,arg2,(char const *)arg3); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3523,7 +3524,7 @@ SWIGINTERN PyObject *_wrap_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *ar } result = reg_open_hive(arg1,(char const *)arg2,arg3,arg4,arg5,arg6); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3600,7 +3601,7 @@ SWIGINTERN PyObject *_wrap_open_ldb(PyObject *SWIGUNUSEDPARM(self), PyObject *ar } result = reg_open_ldb_file(arg1,(char const *)arg2,arg3,arg4,arg5,arg6); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3641,7 +3642,7 @@ SWIGINTERN PyObject *_wrap_create_dir(PyObject *SWIGUNUSEDPARM(self), PyObject * arg2 = (char *)(buf2); result = reg_create_directory(arg1,(char const *)arg2,arg3); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3682,7 +3683,7 @@ SWIGINTERN PyObject *_wrap_open_dir(PyObject *SWIGUNUSEDPARM(self), PyObject *ar arg2 = (char *)(buf2); result = reg_open_directory(arg1,(char const *)arg2,arg3); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3749,7 +3750,7 @@ SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject * } result = reg_open_samba(arg1,arg2,arg3,arg4,arg5); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { -- cgit From be33f4c611d37ebba59ff618033dc73601339ad1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 Dec 2007 23:54:30 -0600 Subject: r26576: Allow the static module loading code to be used for the Python modules. Simplify the way module initialization functions are handled. (This used to be commit ba8be2dfc0de4434c798663336b81f7f95cde520) --- source4/lib/registry/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index b289ff9afd..f1f50479cb 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -102,6 +102,6 @@ OBJ_FILES = \ tests/registry.o [PYTHON::swig_registry] -PUBLIC_DEPENDENCIES = registry LIBPYTHON +PUBLIC_DEPENDENCIES = registry SWIG_FILE = registry.i -- cgit From 3c744ddd2c33a9a06013f357261b8ea86804e8e8 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Mon, 24 Dec 2007 13:04:56 -0600 Subject: r26588: Janitorial: Rename torture_*_add_*test to torture_*_add_*test_const. Also rename the corresponding wrap_ functions. (This used to be commit e59c2eaf681f076d175b9779d1c27b5f74a57c96) --- source4/lib/registry/tests/hive.c | 40 +++++++++---------- source4/lib/registry/tests/registry.c | 73 ++++++++++++++++++----------------- 2 files changed, 57 insertions(+), 56 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index 43ec9e4252..dc59d0f9ca 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -264,26 +264,26 @@ static bool test_list_values(struct torture_context *tctx, static void tcase_add_tests(struct torture_tcase *tcase) { - torture_tcase_add_simple_test(tcase, "del_nonexistant_key", - test_del_nonexistant_key); - torture_tcase_add_simple_test(tcase, "add_subkey", - test_add_subkey); - torture_tcase_add_simple_test(tcase, "flush_key", - test_flush_key); - torture_tcase_add_simple_test(tcase, "get_info", - test_keyinfo_root); - torture_tcase_add_simple_test(tcase, "get_info_nums", - test_keyinfo_nums); - torture_tcase_add_simple_test(tcase, "set_value", - test_set_value); - torture_tcase_add_simple_test(tcase, "get_value", - test_get_value); - torture_tcase_add_simple_test(tcase, "list_values", - test_list_values); - torture_tcase_add_simple_test(tcase, "del_key", - test_del_key); - torture_tcase_add_simple_test(tcase, "del_value", - test_del_value); + torture_tcase_add_simple_test_const(tcase, "del_nonexistant_key", + test_del_nonexistant_key); + torture_tcase_add_simple_test_const(tcase, "add_subkey", + test_add_subkey); + torture_tcase_add_simple_test_const(tcase, "flush_key", + test_flush_key); + torture_tcase_add_simple_test_const(tcase, "get_info", + test_keyinfo_root); + torture_tcase_add_simple_test_const(tcase, "get_info_nums", + test_keyinfo_nums); + torture_tcase_add_simple_test_const(tcase, "set_value", + test_set_value); + torture_tcase_add_simple_test_const(tcase, "get_value", + test_get_value); + torture_tcase_add_simple_test_const(tcase, "list_values", + test_list_values); + torture_tcase_add_simple_test_const(tcase, "del_key", + test_del_key); + torture_tcase_add_simple_test_const(tcase, "del_value", + test_del_value); } static bool hive_setup_dir(struct torture_context *tctx, void **data) diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 6c520f54ed..7897909865 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -560,42 +560,43 @@ static bool setup_local_registry(struct torture_context *tctx, void **data) static void tcase_add_tests(struct torture_tcase *tcase) { - torture_tcase_add_simple_test(tcase, "list_subkeys", - test_list_subkeys); - torture_tcase_add_simple_test(tcase, "get_predefined_key", - test_get_predefined); - torture_tcase_add_simple_test(tcase, "get_predefined_key", - test_get_predefined_unknown); - torture_tcase_add_simple_test(tcase, "create_key", - test_create_subkey); - torture_tcase_add_simple_test(tcase, "create_key", - test_create_nested_subkey); - torture_tcase_add_simple_test(tcase, "key_add_abs", - test_key_add_abs); - torture_tcase_add_simple_test(tcase, "key_add_abs_top", - test_key_add_abs_top); - torture_tcase_add_simple_test(tcase, "set_value", - test_set_value); - torture_tcase_add_simple_test(tcase, "get_value", - test_get_value); - torture_tcase_add_simple_test(tcase, "list_values", - test_list_values); - torture_tcase_add_simple_test(tcase, "del_key", - test_del_key); - torture_tcase_add_simple_test(tcase, "del_value", - test_del_value); - torture_tcase_add_simple_test(tcase, "flush_key", - test_flush_key); - torture_tcase_add_simple_test(tcase, "query_key", - test_query_key); - torture_tcase_add_simple_test(tcase, "query_key_nums", - test_query_key_nums); - torture_tcase_add_simple_test(tcase, "test_predef_key_by_name", - test_predef_key_by_name); - torture_tcase_add_simple_test(tcase, "security", - test_security); - torture_tcase_add_simple_test(tcase, "test_predef_key_by_name_invalid", - test_predef_key_by_name_invalid); + torture_tcase_add_simple_test_const(tcase, "list_subkeys", + test_list_subkeys); + torture_tcase_add_simple_test_const(tcase, "get_predefined_key", + test_get_predefined); + torture_tcase_add_simple_test_const(tcase, "get_predefined_key", + test_get_predefined_unknown); + torture_tcase_add_simple_test_const(tcase, "create_key", + test_create_subkey); + torture_tcase_add_simple_test_const(tcase, "create_key", + test_create_nested_subkey); + torture_tcase_add_simple_test_const(tcase, "key_add_abs", + test_key_add_abs); + torture_tcase_add_simple_test_const(tcase, "key_add_abs_top", + test_key_add_abs_top); + torture_tcase_add_simple_test_const(tcase, "set_value", + test_set_value); + torture_tcase_add_simple_test_const(tcase, "get_value", + test_get_value); + torture_tcase_add_simple_test_const(tcase, "list_values", + test_list_values); + torture_tcase_add_simple_test_const(tcase, "del_key", + test_del_key); + torture_tcase_add_simple_test_const(tcase, "del_value", + test_del_value); + torture_tcase_add_simple_test_const(tcase, "flush_key", + test_flush_key); + torture_tcase_add_simple_test_const(tcase, "query_key", + test_query_key); + torture_tcase_add_simple_test_const(tcase, "query_key_nums", + test_query_key_nums); + torture_tcase_add_simple_test_const(tcase, "test_predef_key_by_name", + test_predef_key_by_name); + torture_tcase_add_simple_test_const(tcase, "security", + test_security); + torture_tcase_add_simple_test_const(tcase, + "test_predef_key_by_name_invalid", + test_predef_key_by_name_invalid); } struct torture_suite *torture_registry_registry(TALLOC_CTX *mem_ctx) -- cgit From a6caca9abcf4de57901ba8ecc610cf8c13cd2821 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Mon, 24 Dec 2007 13:06:57 -0600 Subject: r26589: torture: Add non-const version of torture_tcase_add_simple_test (This used to be commit 1ae9cde5105cc4349a44e6098e9393e06acaf95d) --- source4/lib/registry/tests/hive.c | 14 ++- source4/lib/registry/tests/registry.c | 170 +++++++++++++++------------------- 2 files changed, 79 insertions(+), 105 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index dc59d0f9ca..bc3c82552e 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -61,11 +61,10 @@ static bool test_keyinfo_root(struct torture_context *tctx, return true; } -static bool test_keyinfo_nums(struct torture_context *tctx, - const void *test_data) +static bool test_keyinfo_nums(struct torture_context *tctx, void *test_data) { uint32_t num_subkeys, num_values; - const struct hive_key *root = (const struct hive_key *)test_data; + struct hive_key *root = (struct hive_key *)test_data; WERROR error; struct hive_key *subkey; uint32_t data = 42; @@ -111,10 +110,9 @@ static bool test_add_subkey(struct torture_context *tctx, return true; } -static bool test_flush_key(struct torture_context *tctx, - const void *test_data) +static bool test_flush_key(struct torture_context *tctx, void *test_data) { - const struct hive_key *root = (const struct hive_key *)test_data; + struct hive_key *root = (struct hive_key *)test_data; torture_assert_werr_ok(tctx, hive_key_flush(root), "flush key"); @@ -268,11 +266,11 @@ static void tcase_add_tests(struct torture_tcase *tcase) test_del_nonexistant_key); torture_tcase_add_simple_test_const(tcase, "add_subkey", test_add_subkey); - torture_tcase_add_simple_test_const(tcase, "flush_key", + torture_tcase_add_simple_test(tcase, "flush_key", test_flush_key); torture_tcase_add_simple_test_const(tcase, "get_info", test_keyinfo_root); - torture_tcase_add_simple_test_const(tcase, "get_info_nums", + torture_tcase_add_simple_test(tcase, "get_info_nums", test_keyinfo_nums); torture_tcase_add_simple_test_const(tcase, "set_value", test_set_value); diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 7897909865..2133e72310 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -30,11 +30,9 @@ /** * Test obtaining a predefined key. */ -static bool test_get_predefined(struct torture_context *tctx, - const void *_data) +static bool test_get_predefined(struct torture_context *tctx, void *_data) { - const struct registry_context *rctx = - (const struct registry_context *)_data; + struct registry_context *rctx = (struct registry_context *)_data; struct registry_key *root; WERROR error; @@ -48,9 +46,9 @@ static bool test_get_predefined(struct torture_context *tctx, * Test obtaining a predefined key. */ static bool test_get_predefined_unknown(struct torture_context *tctx, - const void *_data) + void *_data) { - const struct registry_context *rctx = _data; + struct registry_context *rctx = _data; struct registry_key *root; WERROR error; @@ -60,11 +58,9 @@ static bool test_get_predefined_unknown(struct torture_context *tctx, return true; } -static bool test_predef_key_by_name(struct torture_context *tctx, - const void *_data) +static bool test_predef_key_by_name(struct torture_context *tctx, void *_data) { - const struct registry_context *rctx = - (const struct registry_context *)_data; + struct registry_context *rctx = (struct registry_context *)_data; struct registry_key *root; WERROR error; @@ -82,10 +78,9 @@ static bool test_predef_key_by_name(struct torture_context *tctx, } static bool test_predef_key_by_name_invalid(struct torture_context *tctx, - const void *_data) + void *_data) { - const struct registry_context *rctx = - (const struct registry_context *)_data; + struct registry_context *rctx = (struct registry_context *)_data; struct registry_key *root; WERROR error; @@ -98,11 +93,9 @@ static bool test_predef_key_by_name_invalid(struct torture_context *tctx, /** * Test creating a new subkey */ -static bool test_create_subkey(struct torture_context *tctx, - const void *_data) +static bool test_create_subkey(struct torture_context *tctx, void *_data) { - const struct registry_context *rctx = - (const struct registry_context *)_data; + struct registry_context *rctx = (struct registry_context *)_data; struct registry_key *root, *newkey; WERROR error; @@ -121,11 +114,9 @@ static bool test_create_subkey(struct torture_context *tctx, /** * Test creating a new nested subkey */ -static bool test_create_nested_subkey(struct torture_context *tctx, - const void *_data) +static bool test_create_nested_subkey(struct torture_context *tctx, void *_data) { - const struct registry_context *rctx = - (const struct registry_context *)_data; + struct registry_context *rctx = (struct registry_context *)_data; struct registry_key *root, *newkey1, *newkey2; WERROR error; @@ -149,11 +140,9 @@ static bool test_create_nested_subkey(struct torture_context *tctx, /** * Test creating a new subkey */ -static bool test_key_add_abs_top(struct torture_context *tctx, - const void *_data) +static bool test_key_add_abs_top(struct torture_context *tctx, void *_data) { - const struct registry_context *rctx = - (const struct registry_context *)_data; + struct registry_context *rctx = (struct registry_context *)_data; struct registry_key *root; WERROR error; @@ -168,12 +157,10 @@ static bool test_key_add_abs_top(struct torture_context *tctx, /** * Test creating a new subkey */ -static bool test_key_add_abs(struct torture_context *tctx, - const void *_data) +static bool test_key_add_abs(struct torture_context *tctx, void *_data) { WERROR error; - const struct registry_context *rctx = - (const struct registry_context *)_data; + struct registry_context *rctx = (struct registry_context *)_data; struct registry_key *root, *result1, *result2; error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT\\bloe", 0, NULL, @@ -198,10 +185,9 @@ static bool test_key_add_abs(struct torture_context *tctx, } -static bool test_del_key(struct torture_context *tctx, const void *_data) +static bool test_del_key(struct torture_context *tctx, void *_data) { - const struct registry_context *rctx = - (const struct registry_context *)_data; + struct registry_context *rctx = (struct registry_context *)_data; struct registry_key *root, *newkey; WERROR error; @@ -229,7 +215,7 @@ static bool test_del_key(struct torture_context *tctx, const void *_data) * creating a single key for testing purposes. */ static bool create_test_key(struct torture_context *tctx, - const struct registry_context *rctx, + struct registry_context *rctx, const char *name, struct registry_key **root, struct registry_key **subkey) @@ -247,10 +233,9 @@ static bool create_test_key(struct torture_context *tctx, } -static bool test_flush_key(struct torture_context *tctx, const void *_data) +static bool test_flush_key(struct torture_context *tctx, void *_data) { - const struct registry_context *rctx = - (const struct registry_context *)_data; + struct registry_context *rctx = (struct registry_context *)_data; struct registry_key *root, *subkey; WERROR error; @@ -266,10 +251,9 @@ static bool test_flush_key(struct torture_context *tctx, const void *_data) return true; } -static bool test_query_key(struct torture_context *tctx, const void *_data) +static bool test_query_key(struct torture_context *tctx, void *_data) { - const struct registry_context *rctx = - (const struct registry_context *)_data; + struct registry_context *rctx = (struct registry_context *)_data; struct registry_key *root, *subkey; WERROR error; NTTIME last_changed_time; @@ -291,10 +275,9 @@ static bool test_query_key(struct torture_context *tctx, const void *_data) return true; } -static bool test_query_key_nums(struct torture_context *tctx, const void *_data) +static bool test_query_key_nums(struct torture_context *tctx, void *_data) { - const struct registry_context *rctx = - (const struct registry_context *)_data; + struct registry_context *rctx = (struct registry_context *)_data; struct registry_key *root, *subkey1, *subkey2; WERROR error; uint32_t num_subkeys, num_values; @@ -326,10 +309,9 @@ static bool test_query_key_nums(struct torture_context *tctx, const void *_data) * the returned parameters for get_subkey_by_index are optional and * that enumerating the parents of a non-top-level node works. */ -static bool test_list_subkeys(struct torture_context *tctx, const void *_data) +static bool test_list_subkeys(struct torture_context *tctx, void *_data) { - const struct registry_context *rctx = - (const struct registry_context *)_data; + struct registry_context *rctx = (struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; NTTIME last_mod_time; @@ -366,10 +348,9 @@ static bool test_list_subkeys(struct torture_context *tctx, const void *_data) /** * Test setting a value */ -static bool test_set_value(struct torture_context *tctx, const void *_data) +static bool test_set_value(struct torture_context *tctx, void *_data) { - const struct registry_context *rctx = - (const struct registry_context *)_data; + struct registry_context *rctx = (struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; uint32_t data = 42; @@ -387,10 +368,9 @@ static bool test_set_value(struct torture_context *tctx, const void *_data) /** * Test getting/setting security descriptors */ -static bool test_security(struct torture_context *tctx, const void *_data) +static bool test_security(struct torture_context *tctx, void *_data) { - const struct registry_context *rctx = - (const struct registry_context *)_data; + struct registry_context *rctx = (struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; struct security_descriptor *osd, *nsd; @@ -422,10 +402,9 @@ static bool test_security(struct torture_context *tctx, const void *_data) /** * Test getting a value */ -static bool test_get_value(struct torture_context *tctx, const void *_data) +static bool test_get_value(struct torture_context *tctx, void *_data) { - const struct registry_context *rctx = - (const struct registry_context *)_data; + struct registry_context *rctx = (struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; DATA_BLOB data; @@ -459,10 +438,9 @@ static bool test_get_value(struct torture_context *tctx, const void *_data) /** * Test unsetting a value */ -static bool test_del_value(struct torture_context *tctx, const void *_data) +static bool test_del_value(struct torture_context *tctx, void *_data) { - const struct registry_context *rctx = - (const struct registry_context *)_data; + struct registry_context *rctx =(struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; DATA_BLOB data; @@ -495,10 +473,9 @@ static bool test_del_value(struct torture_context *tctx, const void *_data) /** * Test listing values */ -static bool test_list_values(struct torture_context *tctx, const void *_data) +static bool test_list_values(struct torture_context *tctx, void *_data) { - const struct registry_context *rctx = - (const struct registry_context *)_data; + struct registry_context *rctx = (struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; DATA_BLOB data; @@ -560,43 +537,42 @@ static bool setup_local_registry(struct torture_context *tctx, void **data) static void tcase_add_tests(struct torture_tcase *tcase) { - torture_tcase_add_simple_test_const(tcase, "list_subkeys", - test_list_subkeys); - torture_tcase_add_simple_test_const(tcase, "get_predefined_key", - test_get_predefined); - torture_tcase_add_simple_test_const(tcase, "get_predefined_key", - test_get_predefined_unknown); - torture_tcase_add_simple_test_const(tcase, "create_key", - test_create_subkey); - torture_tcase_add_simple_test_const(tcase, "create_key", - test_create_nested_subkey); - torture_tcase_add_simple_test_const(tcase, "key_add_abs", - test_key_add_abs); - torture_tcase_add_simple_test_const(tcase, "key_add_abs_top", - test_key_add_abs_top); - torture_tcase_add_simple_test_const(tcase, "set_value", - test_set_value); - torture_tcase_add_simple_test_const(tcase, "get_value", - test_get_value); - torture_tcase_add_simple_test_const(tcase, "list_values", - test_list_values); - torture_tcase_add_simple_test_const(tcase, "del_key", - test_del_key); - torture_tcase_add_simple_test_const(tcase, "del_value", - test_del_value); - torture_tcase_add_simple_test_const(tcase, "flush_key", - test_flush_key); - torture_tcase_add_simple_test_const(tcase, "query_key", - test_query_key); - torture_tcase_add_simple_test_const(tcase, "query_key_nums", - test_query_key_nums); - torture_tcase_add_simple_test_const(tcase, "test_predef_key_by_name", - test_predef_key_by_name); - torture_tcase_add_simple_test_const(tcase, "security", - test_security); - torture_tcase_add_simple_test_const(tcase, - "test_predef_key_by_name_invalid", - test_predef_key_by_name_invalid); + torture_tcase_add_simple_test(tcase, "list_subkeys", + test_list_subkeys); + torture_tcase_add_simple_test(tcase, "get_predefined_key", + test_get_predefined); + torture_tcase_add_simple_test(tcase, "get_predefined_key", + test_get_predefined_unknown); + torture_tcase_add_simple_test(tcase, "create_key", + test_create_subkey); + torture_tcase_add_simple_test(tcase, "create_key", + test_create_nested_subkey); + torture_tcase_add_simple_test(tcase, "key_add_abs", + test_key_add_abs); + torture_tcase_add_simple_test(tcase, "key_add_abs_top", + test_key_add_abs_top); + torture_tcase_add_simple_test(tcase, "set_value", + test_set_value); + torture_tcase_add_simple_test(tcase, "get_value", + test_get_value); + torture_tcase_add_simple_test(tcase, "list_values", + test_list_values); + torture_tcase_add_simple_test(tcase, "del_key", + test_del_key); + torture_tcase_add_simple_test(tcase, "del_value", + test_del_value); + torture_tcase_add_simple_test(tcase, "flush_key", + test_flush_key); + torture_tcase_add_simple_test(tcase, "query_key", + test_query_key); + torture_tcase_add_simple_test(tcase, "query_key_nums", + test_query_key_nums); + torture_tcase_add_simple_test(tcase, "test_predef_key_by_name", + test_predef_key_by_name); + torture_tcase_add_simple_test(tcase, "security", + test_security); + torture_tcase_add_simple_test(tcase,"test_predef_key_by_name_invalid", + test_predef_key_by_name_invalid); } struct torture_suite *torture_registry_registry(TALLOC_CTX *mem_ctx) -- cgit From 533cc583ed20efdfd6bee60f86d16fef3942898b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Dec 2007 16:36:44 -0600 Subject: r26596: Fixed upgrade.py. Added blackbox tests for provision and upgrade Python scripts. Clean up temporary files created by the Python tests. (This used to be commit 2227fb6df62240cae64d27a1920d878316f819fc) --- source4/lib/registry/tests/bindings.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/bindings.py b/source4/lib/registry/tests/bindings.py index 906deed7e9..314cf778a1 100644 --- a/source4/lib/registry/tests/bindings.py +++ b/source4/lib/registry/tests/bindings.py @@ -35,7 +35,12 @@ class HelperTests(unittest.TestCase): class HiveTests(samba.tests.TestCaseInTempDir): def setUp(self): super(HiveTests, self).setUp() - self.hive = registry.open_ldb(os.path.join(self.tempdir, "ldb_new.ldb")) + self.hive_path = os.path.join(self.tempdir, "ldb_new.ldb") + self.hive = registry.open_ldb(self.hive_path) + + def tearDown(self): + del self.hive + os.unlink(self.hive_path) def test_ldb_new(self): self.assertTrue(self.hive is not None) -- cgit From 251a4e07803d0fa95b1324d60133475ef8c41e79 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Dec 2007 16:37:02 -0600 Subject: r26600: Provide dir variable with current basedir in Makefile. (This used to be commit b06d3e1a52d6b71a1e3e7a9e0ecf69f3b899ae18) --- source4/lib/registry/config.mk | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index f1f50479cb..71c973f68d 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -3,16 +3,16 @@ PUBLIC_DEPENDENCIES = TDR OBJ_FILES = tdr_regf.o # Special support for external builddirs -lib/registry/regf.c: lib/registry/tdr_regf.c -$(srcdir)/lib/registry/regf.c: lib/registry/tdr_regf.c -lib/registry/tdr_regf.h: lib/registry/tdr_regf.c -lib/registry/tdr_regf.c: $(srcdir)/lib/registry/regf.idl +$(dir)/regf.c: $(dir)/tdr_regf.c +$(srcdir)/$(dir)/regf.c: $(dir)/tdr_regf.c +$(dir)/tdr_regf.h: $(dir)/tdr_regf.c +$(dir)/tdr_regf.c: $(srcdir)/$(dir)/regf.idl @CPP="$(CPP)" srcdir="$(srcdir)" $(PERL) $(srcdir)/pidl/pidl $(PIDL_ARGS) \ - --header --outputdir=lib/registry \ - --tdr-parser -- $(srcdir)/lib/registry/regf.idl + --header --outputdir=$(dir) \ + --tdr-parser -- $(srcdir)/$(dir)/regf.idl clean:: - @-rm -f lib/registry/regf.h lib/registry/tdr_regf* + @-rm -f $(dir)/regf.h $(dir)/tdr_regf* ################################################ # Start SUBSYSTEM registry -- cgit From aa79008d4b8741cab917a75d4a7e1f8d6a25e897 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Dec 2007 17:34:07 -0600 Subject: r26602: Revert my previous commit as it only works with GNU make. (This used to be commit ecd2d96c3173e4d2f77a1ca50f26a16ac7a313b1) --- source4/lib/registry/config.mk | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 71c973f68d..f1f50479cb 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -3,16 +3,16 @@ PUBLIC_DEPENDENCIES = TDR OBJ_FILES = tdr_regf.o # Special support for external builddirs -$(dir)/regf.c: $(dir)/tdr_regf.c -$(srcdir)/$(dir)/regf.c: $(dir)/tdr_regf.c -$(dir)/tdr_regf.h: $(dir)/tdr_regf.c -$(dir)/tdr_regf.c: $(srcdir)/$(dir)/regf.idl +lib/registry/regf.c: lib/registry/tdr_regf.c +$(srcdir)/lib/registry/regf.c: lib/registry/tdr_regf.c +lib/registry/tdr_regf.h: lib/registry/tdr_regf.c +lib/registry/tdr_regf.c: $(srcdir)/lib/registry/regf.idl @CPP="$(CPP)" srcdir="$(srcdir)" $(PERL) $(srcdir)/pidl/pidl $(PIDL_ARGS) \ - --header --outputdir=$(dir) \ - --tdr-parser -- $(srcdir)/$(dir)/regf.idl + --header --outputdir=lib/registry \ + --tdr-parser -- $(srcdir)/lib/registry/regf.idl clean:: - @-rm -f $(dir)/regf.h $(dir)/tdr_regf* + @-rm -f lib/registry/regf.h lib/registry/tdr_regf* ################################################ # Start SUBSYSTEM registry -- cgit From 86dc05e99f124db47f2743d1fc23117a7f5145ab Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 1 Jan 2008 22:05:05 -0600 Subject: r26638: libndr: Require explicitly specifying iconv_convenience for ndr_struct_push_blob(). (This used to be commit 61ad78ac98937ef7a9aa32075a91a1c95b7606b3) --- source4/lib/registry/regf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 28bd0ad461..7d2df182fe 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -1041,8 +1041,8 @@ static WERROR regf_set_sec_desc(struct hive_key *key, (tdr_pull_fn_t) tdr_pull_nk_block, &root); /* Push the security descriptor to a blob */ - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(&data, regf, sec_desc, - (ndr_push_flags_fn_t)ndr_push_security_descriptor))) { + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(&data, regf, NULL, + sec_desc, (ndr_push_flags_fn_t)ndr_push_security_descriptor))) { DEBUG(0, ("Unable to push security descriptor\n")); return WERR_GENERAL_FAILURE; } -- cgit From 7d5f0e0893d42b56145a3ffa34e3b4b9906cbd91 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 1 Jan 2008 22:05:13 -0600 Subject: r26639: librpc: Pass iconv convenience on from RPC connection to NDR library, so it can be overridden by OpenChange. (This used to be commit 2f29f80e07adef1f020173f2cd6d947d0ef505ce) --- source4/lib/registry/regf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 7d2df182fe..9264339a6c 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -1194,7 +1194,7 @@ static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, const struct hive_key *key, data.data = sk.sec_desc; data.length = sk.rec_size; - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_struct_blob(&data, ctx, *sd, + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_struct_blob(&data, ctx, NULL, *sd, (ndr_pull_flags_fn_t)ndr_pull_security_descriptor))) { DEBUG(0, ("Error parsing security descriptor\n")); return WERR_GENERAL_FAILURE; -- cgit From df70180c0ff55a526cec997b6a9fc550cf2719d6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Jan 2008 13:59:53 -0600 Subject: r26665: registry: Fix tests on bigendian machines. (This used to be commit bcd8f50f7952d1e502326f11ddfa8cfe8a982b1b) --- source4/lib/registry/tests/hive.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index bc3c82552e..36eea84d94 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -186,7 +186,9 @@ static bool test_get_value(struct torture_context *tctx, const void *test_data) torture_assert_int_equal(tctx, value.length, 4, "value length"); torture_assert_int_equal(tctx, type, REG_DWORD, "value type"); - torture_assert(tctx, memcmp(value.data, &data, 4) == 0, "value data"); + + torture_assert_int_equal(tctx, data, IVAL(value.data, 0), + "value data"); return true; } @@ -250,7 +252,9 @@ static bool test_list_values(struct torture_context *tctx, torture_assert_int_equal(tctx, value.length, 4, "value length"); torture_assert_int_equal(tctx, type, REG_DWORD, "value type"); - torture_assert(tctx, memcmp(value.data, &data, 4) == 0, "value data"); + + + torture_assert_int_equal(tctx, data, IVAL(value.data, 0), "value data"); error = hive_get_value_by_index(mem_ctx, subkey, 1, &name, &type, &value); -- cgit From 7f8276b06d5000d12c0d64167853a033b924af32 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 7 Jan 2008 14:11:25 -0600 Subject: r26688: Fix listing remote predefined keys and subkeys. This fixes bug 3431. (This used to be commit 846876ad32dc86fe7c367db084e76c670c61b389) --- source4/lib/registry/local.c | 4 +- source4/lib/registry/registry.h | 1 - source4/lib/registry/rpc.c | 89 ++++++++++++++++++++++++------------- source4/lib/registry/tools/common.c | 6 +-- 4 files changed, 64 insertions(+), 36 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index 14b42797ba..35724e7ea6 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -30,7 +30,7 @@ struct reg_key_path { }; struct registry_local { - struct registry_context registry; + const struct registry_operations *ops; struct mountpoint { struct reg_key_path path; @@ -299,7 +299,7 @@ WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx, W_ERROR_HAVE_NO_MEMORY(ret); - ret->registry.ops = &local_ops; + ret->ops = &local_ops; ret->session_info = session_info; ret->credentials = credentials; diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 7999719909..8273333b24 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -80,7 +80,6 @@ typedef void (*reg_key_notification_function) (void); typedef void (*reg_value_notification_function) (void); struct cli_credentials; -struct registry_context; struct registry_operations { const char *name; diff --git a/source4/lib/registry/rpc.c b/source4/lib/registry/rpc.c index 7f800b786e..2a6cabc3b8 100644 --- a/source4/lib/registry/rpc.c +++ b/source4/lib/registry/rpc.c @@ -96,9 +96,10 @@ static WERROR rpc_get_predefined_key(struct registry_context *ctx, struct registry_key **k) { int n; - struct rpc_registry_context *rctx = talloc_get_type(ctx, - struct rpc_registry_context); struct rpc_key *mykeydata; + struct rpc_registry_context *rctx = talloc_get_type(ctx, struct rpc_registry_context); + + *k = NULL; for(n = 0; known_hives[n].hkey; n++) { if(known_hives[n].hkey == hkey_type) @@ -110,11 +111,13 @@ static WERROR rpc_get_predefined_key(struct registry_context *ctx, return WERR_NO_MORE_ITEMS; } - mykeydata = talloc(ctx, struct rpc_key); - mykeydata->pipe = rctx->pipe; + mykeydata = talloc_zero(ctx, struct rpc_key); + mykeydata->key.context = ctx; + mykeydata->pipe = talloc_reference(mykeydata, rctx->pipe); mykeydata->num_values = -1; mykeydata->num_subkeys = -1; - return known_hives[n].open(mykeydata->pipe, *k, &(mykeydata->pol)); + *k = (struct registry_key *)mykeydata; + return known_hives[n].open(mykeydata->pipe, mykeydata, &(mykeydata->pol)); } #if 0 @@ -146,21 +149,32 @@ static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, const char *name, struct registry_key **key) { - struct rpc_key *mykeydata = talloc_get_type(h, struct rpc_key), - *newkeydata; + struct rpc_key *parentkeydata = talloc_get_type(h, struct rpc_key), + *mykeydata; struct winreg_OpenKey r; + NTSTATUS status; mykeydata = talloc(mem_ctx, struct rpc_key); + mykeydata->key.context = parentkeydata->key.context; + mykeydata->pipe = talloc_reference(mykeydata, parentkeydata->pipe); + mykeydata->num_values = -1; + mykeydata->num_subkeys = -1; + *key = (struct registry_key *)mykeydata; + /* Then, open the handle using the hive */ - memset(&r, 0, sizeof(struct winreg_OpenKey)); - r.in.parent_handle = &mykeydata->pol; + ZERO_STRUCT(r); + r.in.parent_handle = &parentkeydata->pol; init_winreg_String(&r.in.keyname, name); r.in.unknown = 0x00000000; r.in.access_mask = 0x02000000; - r.out.handle = &newkeydata->pol; + r.out.handle = &mykeydata->pol; - dcerpc_winreg_OpenKey(mykeydata->pipe, mem_ctx, &r); + status = dcerpc_winreg_OpenKey(mykeydata->pipe, mem_ctx, &r); + if (NT_STATUS_IS_ERR(status)) { + DEBUG(0,("Error executing openkey: %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); + } return r.out.result; } @@ -175,29 +189,29 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key); WERROR error; struct winreg_EnumValue r; - uint32_t len1, zero = 0; + uint32_t in_type = 0; NTSTATUS status; struct winreg_StringBuf name; - uint8_t u8; + uint32_t zero = 0; + + ZERO_STRUCT(r); if (mykeydata->num_values == -1) { error = rpc_query_key(parent); if(!W_ERROR_IS_OK(error)) return error; } - len1 = mykeydata->max_valdatalen; - name.length = 0; - name.size = mykeydata->max_valnamelen * 2; - name.name = ""; + name.size = mykeydata->max_valnamelen * 2+1; + name.name = NULL; r.in.handle = &mykeydata->pol; r.in.enum_index = n; r.in.name = &name; - r.in.type = type; - r.in.value = &u8; + r.in.type = &in_type; + r.in.value = talloc_zero_array(mem_ctx, uint8_t, 0); r.in.length = &zero; - r.in.size = &len1; + r.in.size = &mykeydata->max_valdatalen; r.out.name = &name; status = dcerpc_winreg_EnumValue(mykeydata->pipe, mem_ctx, &r); @@ -229,6 +243,8 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct winreg_StringBuf namebuf, classbuf; NTTIME change_time = 0; + ZERO_STRUCT(r); + namebuf.length = 0; namebuf.size = 1024; namebuf.name = NULL; @@ -241,13 +257,14 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, r.in.name = &namebuf; r.in.keyclass = &classbuf; r.in.last_changed_time = &change_time; + r.out.name = &namebuf; status = dcerpc_winreg_EnumKey(mykeydata->pipe, mem_ctx, &r); if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { *name = talloc_strdup(mem_ctx, r.out.name->name); - *keyclass = talloc_strdup(mem_ctx, r.out.keyclass->name); - *last_changed_time = *r.out.last_changed_time; + if (keyclass != NULL) + *keyclass = talloc_strdup(mem_ctx, r.out.keyclass->name); } return r.out.result; @@ -295,8 +312,23 @@ static WERROR rpc_query_key(const struct registry_key *k) struct winreg_QueryInfoKey r; struct rpc_key *mykeydata = talloc_get_type(k, struct rpc_key); TALLOC_CTX *mem_ctx = talloc_init("query_key"); + uint32_t max_subkeysize; + uint32_t num_values; + uint32_t secdescsize; + NTTIME last_changed_time; + + ZERO_STRUCT(r.out); - r.in.classname = talloc(mem_ctx, struct winreg_String); + r.out.num_subkeys = &mykeydata->num_subkeys; + r.out.max_subkeylen = &mykeydata->num_values; + r.out.max_valnamelen = &mykeydata->max_valnamelen; + r.out.max_valbufsize = &mykeydata->max_valdatalen; + r.out.max_subkeysize = &max_subkeysize; + r.out.num_values = &num_values; + r.out.secdescsize = &secdescsize; + r.out.last_changed_time = &last_changed_time; + + r.out.classname = r.in.classname = talloc_zero(mem_ctx, struct winreg_String); init_winreg_String(r.in.classname, NULL); r.in.handle = &mykeydata->pol; @@ -309,10 +341,6 @@ static WERROR rpc_query_key(const struct registry_key *k) } if (W_ERROR_IS_OK(r.out.result)) { - mykeydata->num_subkeys = *r.out.num_subkeys; - mykeydata->num_values = *r.out.num_values; - mykeydata->max_valnamelen = *r.out.max_valnamelen; - mykeydata->max_valdatalen = *r.out.max_valbufsize; } return r.out.result; @@ -364,6 +392,7 @@ static WERROR rpc_get_info(TALLOC_CTX *mem_ctx, const struct registry_key *key, static struct registry_operations reg_backend_rpc = { .name = "rpc", .open_key = rpc_open_key, + .get_predefined_key = rpc_get_predefined_key, .enum_key = rpc_get_subkey_by_index, .enum_value = rpc_get_value_by_index, .create_key = rpc_add_key, @@ -388,10 +417,10 @@ _PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, /* Default to local smbd if no connection is specified */ if (!location) { - location = talloc_strdup(ctx, "ncalrpc:"); + location = talloc_strdup(rctx, "ncalrpc:"); } - status = dcerpc_pipe_connect(*ctx /* TALLOC_CTX */, + status = dcerpc_pipe_connect(rctx /* TALLOC_CTX */, &p, location, &ndr_table_winreg, credentials, ev, lp_ctx); @@ -400,7 +429,7 @@ _PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, if(NT_STATUS_IS_ERR(status)) { DEBUG(1, ("Unable to open '%s': %s\n", location, nt_errstr(status))); - talloc_free(*ctx); + talloc_free(rctx); *ctx = NULL; return ntstatus_to_werror(status); } diff --git a/source4/lib/registry/tools/common.c b/source4/lib/registry/tools/common.c index 29e96475e6..cec0f8b906 100644 --- a/source4/lib/registry/tools/common.c +++ b/source4/lib/registry/tools/common.c @@ -27,7 +27,7 @@ struct registry_context *reg_common_open_remote(const char *remote, struct loadparm_context *lp_ctx, struct cli_credentials *creds) { - struct registry_context *h; + struct registry_context *h = NULL; WERROR error; error = reg_open_remote(&h, NULL, creds, lp_ctx, remote, NULL); @@ -46,7 +46,7 @@ struct registry_key *reg_common_open_file(const char *path, struct cli_credentials *creds) { struct hive_key *hive_root; - struct registry_context *h; + struct registry_context *h = NULL; WERROR error; error = reg_open_hive(NULL, path, NULL, creds, lp_ctx, &hive_root); @@ -70,7 +70,7 @@ struct registry_key *reg_common_open_file(const char *path, struct registry_context *reg_common_open_local(struct cli_credentials *creds, struct loadparm_context *lp_ctx) { WERROR error; - struct registry_context *h; + struct registry_context *h = NULL; error = reg_open_samba(NULL, &h, lp_ctx, NULL, creds); -- cgit From 47f6bbf8cf5bdd03c72c59d00e3e1eab8895590e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 7 Jan 2008 14:11:29 -0600 Subject: r26689: registry: Return max_subkeynamelen, max_valnamelen and max_valbufsize in getkeyinfo(). (This used to be commit b06896d2378e536f5044dbe500a5232a89d6d0b5) --- source4/lib/registry/dir.c | 32 +++++++++++++++++---- source4/lib/registry/hive.c | 9 ++++-- source4/lib/registry/hive.h | 10 +++++-- source4/lib/registry/interface.c | 9 ++++-- source4/lib/registry/ldb.c | 52 +++++++++++++++++++++++++++++++++-- source4/lib/registry/local.c | 8 ++++-- source4/lib/registry/patchfile.c | 11 +++----- source4/lib/registry/regf.c | 11 +++++++- source4/lib/registry/registry.h | 10 +++++-- source4/lib/registry/rpc.c | 23 ++++++++++++---- source4/lib/registry/tests/hive.c | 4 +-- source4/lib/registry/tests/registry.c | 4 +-- source4/lib/registry/tools/regshell.c | 32 +++++++++++++++------ 13 files changed, 171 insertions(+), 44 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/dir.c b/source4/lib/registry/dir.c index 2f00d2fea0..a13e3753b7 100644 --- a/source4/lib/registry/dir.c +++ b/source4/lib/registry/dir.c @@ -184,7 +184,10 @@ static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key, const char **classname, uint32_t *num_subkeys, uint32_t *num_values, - NTTIME *lastmod) + NTTIME *lastmod, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize) { DIR *d; const struct dir_key *dk = talloc_get_type(key, struct dir_key); @@ -206,6 +209,15 @@ static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key, if (num_values != NULL) *num_values = 0; + if (max_subkeynamelen != NULL) + *max_subkeynamelen = 0; + + if (max_valnamelen != NULL) + *max_valnamelen = 0; + + if (max_valbufsize != NULL) + *max_valbufsize = 0; + while((e = readdir(d))) { if(!ISDOT(e->d_name) && !ISDOTDOT(e->d_name)) { char *path = talloc_asprintf(ctx, "%s/%s", @@ -217,11 +229,21 @@ static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key, continue; } - if (S_ISDIR(st.st_mode) && num_subkeys != NULL) - (*num_subkeys)++; + if (S_ISDIR(st.st_mode)) { + if (num_subkeys != NULL) + (*num_subkeys)++; + if (max_subkeynamelen != NULL) + *max_subkeynamelen = MAX(*max_subkeynamelen, strlen(e->d_name)); + } - if (!S_ISDIR(st.st_mode) && num_values != NULL) - (*num_values)++; + if (!S_ISDIR(st.st_mode)) { + if (num_values != NULL) + (*num_values)++; + if (max_valnamelen != NULL) + *max_valnamelen = MAX(*max_valnamelen, strlen(e->d_name)); + if (max_valbufsize != NULL) + *max_valbufsize = MAX(*max_valbufsize, st.st_size); + } talloc_free(path); } diff --git a/source4/lib/registry/hive.c b/source4/lib/registry/hive.c index d7d12076f3..bbe510772c 100644 --- a/source4/lib/registry/hive.c +++ b/source4/lib/registry/hive.c @@ -66,10 +66,15 @@ _PUBLIC_ WERROR hive_key_get_info(TALLOC_CTX *mem_ctx, const struct hive_key *key, const char **classname, uint32_t *num_subkeys, uint32_t *num_values, - NTTIME *last_change_time) + NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize) { return key->ops->get_key_info(mem_ctx, key, classname, num_subkeys, - num_values, last_change_time); + num_values, last_change_time, + max_subkeynamelen, + max_valnamelen, max_valbufsize); } _PUBLIC_ WERROR hive_key_add_name(TALLOC_CTX *ctx, diff --git a/source4/lib/registry/hive.h b/source4/lib/registry/hive.h index 1e05f6b013..6d9a69c7c5 100644 --- a/source4/lib/registry/hive.h +++ b/source4/lib/registry/hive.h @@ -135,7 +135,10 @@ struct hive_operations { const char **classname, uint32_t *num_subkeys, uint32_t *num_values, - NTTIME *last_change_time); + NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize); }; struct cli_credentials; @@ -148,8 +151,9 @@ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, struct hive_key **root); WERROR hive_key_get_info(TALLOC_CTX *mem_ctx, const struct hive_key *key, const char **classname, uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_change_time); + uint32_t *num_values, NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, uint32_t *max_valbufsize); WERROR hive_key_add_name(TALLOC_CTX *ctx, const struct hive_key *parent_key, const char *name, const char *classname, struct security_descriptor *desc, diff --git a/source4/lib/registry/interface.c b/source4/lib/registry/interface.c index b914fbab30..a18fd2c28c 100644 --- a/source4/lib/registry/interface.c +++ b/source4/lib/registry/interface.c @@ -128,7 +128,10 @@ _PUBLIC_ WERROR reg_key_get_info(TALLOC_CTX *mem_ctx, const char **classname, uint32_t *num_subkeys, uint32_t *num_values, - NTTIME *last_change_time) + NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize) { if (key == NULL) return WERR_INVALID_PARAM; @@ -138,7 +141,9 @@ _PUBLIC_ WERROR reg_key_get_info(TALLOC_CTX *mem_ctx, return key->context->ops->get_key_info(mem_ctx, key, classname, num_subkeys, - num_values, last_change_time); + num_values, last_change_time, + max_subkeynamelen, + max_valnamelen, max_valbufsize); } /** diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index c9697ddb4c..1e345ba9f3 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -41,16 +41,19 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, DATA_BLOB *data) { const struct ldb_val *val; + uint32_t value_type; + if (name != NULL) *name = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(msg, "value", NULL)); + value_type = ldb_msg_find_attr_as_uint(msg, "type", 0); if (type != NULL) - *type = ldb_msg_find_attr_as_uint(msg, "type", 0); + *type = value_type; val = ldb_msg_find_ldb_val(msg, "data"); - switch (*type) + switch (value_type) { case REG_SZ: case REG_EXPAND_SZ: @@ -483,7 +486,10 @@ static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, const char **classname, uint32_t *num_subkeys, uint32_t *num_values, - NTTIME *last_change_time) + NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize) { struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data); @@ -504,6 +510,46 @@ static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, if (last_change_time != NULL) *last_change_time = 0; + if (max_subkeynamelen != NULL) { + int i; + struct ldb_message_element *el; + W_ERROR_NOT_OK_RETURN(cache_subkeys(kd)); + + *max_subkeynamelen = 0; + + for (i = 0; i < kd->subkey_count; i++) { + el = ldb_msg_find_element(kd->subkeys[i], "key"); + *max_subkeynamelen = MAX(*max_subkeynamelen, el->values[0].length); + } + } + + if (max_valnamelen != NULL || max_valbufsize != NULL) { + int i; + struct ldb_message_element *el; + W_ERROR_NOT_OK_RETURN(cache_values(kd)); + + if (max_valbufsize != NULL) + *max_valbufsize = 0; + + if (max_valnamelen != NULL) + *max_valnamelen = 0; + + for (i = 0; i < kd->value_count; i++) { + if (max_valnamelen != NULL) { + el = ldb_msg_find_element(kd->values[i], "value"); + *max_valnamelen = MAX(*max_valnamelen, el->values[0].length); + } + + if (max_valbufsize != NULL) { + DATA_BLOB data; + reg_ldb_unpack_value(mem_ctx, kd->values[i], NULL, + NULL, &data); + *max_valbufsize = MAX(*max_valbufsize, data.length); + talloc_free(data.data); + } + } + } + return WERR_OK; } diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index 35724e7ea6..fa59f25596 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -266,13 +266,17 @@ static WERROR local_get_key_info(TALLOC_CTX *mem_ctx, const char **classname, uint32_t *num_subkeys, uint32_t *num_values, - NTTIME *last_change_time) + NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize) { const struct local_key *local = (const struct local_key *)key; return hive_key_get_info(mem_ctx, local->hive_key, classname, num_subkeys, num_values, - last_change_time); + last_change_time, max_subkeynamelen, + max_valnamelen, max_valbufsize); } const static struct registry_operations local_ops = { diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index 8a417d5935..b6ad7dfb10 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -54,7 +54,7 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, if (oldkey != NULL) { error = reg_key_get_info(mem_ctx, oldkey, NULL, &old_num_subkeys, &old_num_values, - NULL); + NULL, NULL, NULL, NULL); if (!W_ERROR_IS_OK(error)) { DEBUG(0, ("Error occured while getting key info: %s\n", win_errstr(error))); @@ -102,7 +102,7 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, if (newkey != NULL) { error = reg_key_get_info(mem_ctx, newkey, NULL, &new_num_subkeys, &new_num_values, - NULL); + NULL, NULL, NULL, NULL); if (!W_ERROR_IS_OK(error)) { DEBUG(0, ("Error occured while getting key info: %s\n", win_errstr(error))); @@ -412,11 +412,8 @@ static WERROR reg_diff_apply_del_all_values(void *_ctx, const char *key_name) return error; } - W_ERROR_NOT_OK_RETURN(reg_key_get_info(ctx, key, - NULL, - NULL, - &num_values, - NULL)); + W_ERROR_NOT_OK_RETURN(reg_key_get_info(ctx, key, NULL, + NULL, &num_values, NULL, NULL, NULL, NULL)); for (i = 0; i < num_values; i++) { const char *name; diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 9264339a6c..9b126cc808 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -428,7 +428,10 @@ static WERROR regf_get_info(TALLOC_CTX *mem_ctx, const char **classname, uint32_t *num_subkeys, uint32_t *num_values, - NTTIME *last_mod_time) + NTTIME *last_mod_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize) { const struct regf_key_data *private_data = (const struct regf_key_data *)key; @@ -452,6 +455,12 @@ static WERROR regf_get_info(TALLOC_CTX *mem_ctx, /* TODO: Last mod time */ + /* TODO: max valnamelen */ + + /* TODO: max valbufsize */ + + /* TODO: max subkeynamelen */ + return WERR_OK; } diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 8273333b24..fac9180378 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -89,7 +89,10 @@ struct registry_operations { const char **classname, uint32_t *numsubkeys, uint32_t *numvalues, - NTTIME *last_change_time); + NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize); WERROR (*flush_key) (struct registry_key *key); @@ -211,7 +214,10 @@ WERROR reg_key_get_info(TALLOC_CTX *mem_ctx, const char **class_name, uint32_t *num_subkeys, uint32_t *num_values, - NTTIME *last_change_time); + NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize); WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *key, int idx, diff --git a/source4/lib/registry/rpc.c b/source4/lib/registry/rpc.c index 2a6cabc3b8..18b7607713 100644 --- a/source4/lib/registry/rpc.c +++ b/source4/lib/registry/rpc.c @@ -29,6 +29,7 @@ struct rpc_key { uint32_t num_subkeys; uint32_t max_valnamelen; uint32_t max_valdatalen; + uint32_t max_subkeynamelen; }; struct rpc_registry_context { @@ -202,7 +203,7 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, } name.length = 0; - name.size = mykeydata->max_valnamelen * 2+1; + name.size = mykeydata->max_valnamelen * 2; name.name = NULL; r.in.handle = &mykeydata->pol; @@ -213,6 +214,7 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, r.in.length = &zero; r.in.size = &mykeydata->max_valdatalen; r.out.name = &name; + r.out.type = type; status = dcerpc_winreg_EnumValue(mykeydata->pipe, mem_ctx, &r); if(NT_STATUS_IS_ERR(status)) { @@ -313,18 +315,17 @@ static WERROR rpc_query_key(const struct registry_key *k) struct rpc_key *mykeydata = talloc_get_type(k, struct rpc_key); TALLOC_CTX *mem_ctx = talloc_init("query_key"); uint32_t max_subkeysize; - uint32_t num_values; uint32_t secdescsize; NTTIME last_changed_time; ZERO_STRUCT(r.out); r.out.num_subkeys = &mykeydata->num_subkeys; - r.out.max_subkeylen = &mykeydata->num_values; + r.out.max_subkeylen = &mykeydata->max_subkeynamelen; r.out.max_valnamelen = &mykeydata->max_valnamelen; r.out.max_valbufsize = &mykeydata->max_valdatalen; r.out.max_subkeysize = &max_subkeysize; - r.out.num_values = &num_values; + r.out.num_values = &mykeydata->num_values; r.out.secdescsize = &secdescsize; r.out.last_changed_time = &last_changed_time; @@ -367,7 +368,10 @@ static WERROR rpc_get_info(TALLOC_CTX *mem_ctx, const struct registry_key *key, const char **classname, uint32_t *numsubkeys, uint32_t *numvalue, - NTTIME *last_changed_time) + NTTIME *last_changed_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize) { struct rpc_key *mykeydata = talloc_get_type(key, struct rpc_key); WERROR error; @@ -386,6 +390,15 @@ static WERROR rpc_get_info(TALLOC_CTX *mem_ctx, const struct registry_key *key, if (numsubkeys != NULL) *numsubkeys = mykeydata->num_subkeys; + if (max_valnamelen != NULL) + *max_valnamelen = mykeydata->max_valnamelen; + + if (max_valbufsize != NULL) + *max_valbufsize = mykeydata->max_valdatalen; + + if (max_subkeynamelen != NULL) + *max_subkeynamelen = mykeydata->max_subkeynamelen; + return WERR_OK; } diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index 36eea84d94..22b4785222 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -47,7 +47,7 @@ static bool test_keyinfo_root(struct torture_context *tctx, /* This is a new backend. There should be no subkeys and no * values */ error = hive_key_get_info(tctx, root, NULL, &num_subkeys, &num_values, - NULL); + NULL, NULL, NULL, NULL); torture_assert_werr_ok(tctx, error, "reg_key_num_subkeys()"); torture_assert_int_equal(tctx, num_subkeys, 0, @@ -80,7 +80,7 @@ static bool test_keyinfo_nums(struct torture_context *tctx, void *test_data) /* This is a new backend. There should be no subkeys and no * values */ error = hive_key_get_info(tctx, root, NULL, &num_subkeys, &num_values, - NULL); + NULL, NULL, NULL, NULL); torture_assert_werr_ok(tctx, error, "reg_key_num_subkeys()"); torture_assert_int_equal(tctx, num_subkeys, 1, "subkey count"); diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 2133e72310..75fbe1cbea 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -265,7 +265,7 @@ static bool test_query_key(struct torture_context *tctx, void *_data) error = reg_key_get_info(tctx, subkey, &classname, &num_subkeys, &num_values, - &last_changed_time); + &last_changed_time, NULL, NULL, NULL); torture_assert_werr_ok(tctx, error, "get info key"); torture_assert(tctx, classname == NULL, "classname"); @@ -295,7 +295,7 @@ static bool test_query_key_nums(struct torture_context *tctx, void *_data) torture_assert_werr_ok(tctx, error, "set value"); error = reg_key_get_info(tctx, subkey1, NULL, &num_subkeys, - &num_values, NULL); + &num_values, NULL, NULL, NULL, NULL); torture_assert_werr_ok(tctx, error, "get info key"); torture_assert_int_equal(tctx, num_subkeys, 1, "num subkeys"); diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 329d6ab670..93f28f3e5a 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -53,11 +53,16 @@ static WERROR cmd_info(struct regshell_context *ctx, int argc, char **argv) struct security_descriptor *sec_desc = NULL; time_t last_mod; WERROR error; - const char *classname; + const char *classname = NULL; NTTIME last_change; - - error = reg_key_get_info(ctx, ctx->current, &classname, NULL, NULL, - &last_change); + uint32_t max_subkeynamelen; + uint32_t max_valnamelen; + uint32_t max_valbufsize; + uint32_t num_subkeys; + uint32_t num_values; + + error = reg_key_get_info(ctx, ctx->current, &classname, &num_subkeys, &num_values, + &last_change, &max_subkeynamelen, &max_valnamelen, &max_valbufsize); if (!W_ERROR_IS_OK(error)) { printf("Error getting key info: %s\n", win_errstr(error)); return error; @@ -67,9 +72,21 @@ static WERROR cmd_info(struct regshell_context *ctx, int argc, char **argv) printf("Name: %s\n", strchr(ctx->path, '\\')?strrchr(ctx->path, '\\')+1: ctx->path); printf("Full path: %s\n", ctx->path); - printf("Key Class: %s\n", classname); + if (classname != NULL) + printf("Key Class: %s\n", classname); last_mod = nt_time_to_unix(last_change); printf("Time Last Modified: %s\n", ctime(&last_mod)); + printf("Number of subkeys: %d\n", num_subkeys); + printf("Number of values: %d\n", num_values); + + if (max_valnamelen > 0) + printf("Maximum value name length: %d\n", max_valnamelen); + + if (max_valbufsize > 0) + printf("Maximum value data length: %d\n", max_valbufsize); + + if (max_subkeynamelen > 0) + printf("Maximum sub key name length: %d\n", max_subkeynamelen); error = reg_get_sec_desc(ctx, ctx->current, &sec_desc); if (!W_ERROR_IS_OK(error)) { @@ -188,10 +205,9 @@ static WERROR cmd_ls(struct regshell_context *ctx, int argc, char **argv) { int i; WERROR error; - struct registry_value *value; uint32_t data_type; DATA_BLOB data; - const char *name; + const char *name = NULL; for (i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(ctx, ctx->current, @@ -213,7 +229,7 @@ static WERROR cmd_ls(struct regshell_context *ctx, int argc, char **argv) &name, &data_type, &data)); i++) { - printf("V \"%s\" %s %s\n", value->name, str_regtype(data_type), + printf("V \"%s\" %s %s\n", name, str_regtype(data_type), reg_val_data_string(ctx, data_type, data)); } -- cgit From 83a7d865e41e56ee7ad6c732f743df51a418168e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 7 Jan 2008 23:41:55 -0600 Subject: r26692: registry: Treat key and value names case-insensitively. (This used to be commit 9fc5f098e01145db5b01efb0bf22cdddf0213d20) --- source4/lib/registry/ldb.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 1e345ba9f3..259315cc39 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -345,6 +345,7 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, { struct ldb_key_data *kd; struct ldb_context *wrap; + struct ldb_message *attrs_msg; if (location == NULL) return WERR_INVALID_PARAM; @@ -357,6 +358,15 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, return WERR_FOOBAR; } + attrs_msg = ldb_msg_new(wrap); + W_ERROR_HAVE_NO_MEMORY(attrs_msg); + attrs_msg->dn = ldb_dn_new(attrs_msg, wrap, "@ATTRIBUTES"); + W_ERROR_HAVE_NO_MEMORY(attrs_msg->dn); + ldb_msg_add_string(attrs_msg, "key", "CASE_INSENSITIVE"); + ldb_msg_add_string(attrs_msg, "value", "CASE_INSENSITIVE"); + + ldb_add(wrap, attrs_msg); + ldb_set_debug_stderr(wrap); kd = talloc_zero(parent_ctx, struct ldb_key_data); -- cgit From 73626c266c3ea1b477185a428b2c1be64feff598 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 18 Jan 2008 01:47:10 +0100 Subject: registry: Check for more specific LDB return codes, handle changing existing values better. (This used to be commit c8b22ef30c7fc0ccc15e9fc9a38fdc639fc4b976) --- source4/lib/registry/ldb.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 259315cc39..d56b63299d 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -478,13 +478,18 @@ static WERROR ldb_set_value(struct hive_key *parent, ldb_dn_add_child_fmt(msg->dn, "value=%s", name); ret = ldb_add(kd->ldb, msg); - if (ret < 0) { - ret = ldb_modify(kd->ldb, msg); - if (ret < 0) { - DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(kd->ldb))); - talloc_free(mem_ctx); - return WERR_FOOBAR; + if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { + int i; + for (i = 0; i < msg->num_elements; i++) { + msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; } + ret = ldb_modify(kd->ldb, msg); + } + + if (ret != LDB_SUCCESS) { + DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(kd->ldb))); + talloc_free(mem_ctx); + return WERR_FOOBAR; } talloc_free(mem_ctx); -- cgit From 158a2eed334512c28a7101b3af2c364b4ac1b3fd Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Fri, 18 Jan 2008 01:48:48 +0100 Subject: registry: Properly check return values from ldb_*() functions. There were a few cases left that attempted to detect errors from ldb_*() function calls using "(ret < 0)". As all LDB_* error codes are greater than zero, there was no chance any errors would be detected. Changed all such tests to use "(ret != LDB_SUCCESS)". (This used to be commit 0ed6f1b1628da5b922f02a5f9a6c60071b6277f2) --- source4/lib/registry/ldb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index d56b63299d..d87bc6cf8e 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -400,7 +400,7 @@ static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent, talloc_strdup(mem_ctx, classname)); ret = ldb_add(parentkd->ldb, msg); - if (ret < 0) { + if (ret != LDB_SUCCESS) { DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parentkd->ldb))); return WERR_FOOBAR; } @@ -432,7 +432,7 @@ static WERROR ldb_del_key(const struct hive_key *key, const char *child) if (ret == LDB_ERR_NO_SUCH_OBJECT) { return WERR_NOT_FOUND; - } else if (ret < 0) { + } else if (ret != LDB_SUCCESS) { DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(parentkd->ldb))); return WERR_FOOBAR; } @@ -455,7 +455,7 @@ static WERROR ldb_del_value (struct hive_key *key, const char *child) if (ret == LDB_ERR_NO_SUCH_OBJECT) { return WERR_NOT_FOUND; - } else if (ret < 0) { + } else if (ret != LDB_SUCCESS) { DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(kd->ldb))); return WERR_FOOBAR; } -- cgit From 4d8a60f617f941ff6481bcfbac73d7ed69e43daa Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Fri, 18 Jan 2008 01:50:33 +0100 Subject: When Windows initially creates a new value, the value name is "New Value #1". The '#' character was causing problems, as it was not being escaped for the dn, but the failure returned by ldb_dn_add_child_fmt() was not being caught. This was causing the new value to be added on the parent key, not the current key. When attempting to delete the new value (now on the parent key) the same escaping error was returned by ldb_dn_add_child_fmt(), causing the delete to delete the key and not the value. When attempting to rename a value, Windows first tries to ensure the new name does not already exist. When a value does not exist, Windows expects a return value of WERR_BADFILE, but WERR_NOT_FOUND was being returned instead. Providing the WERR_BADFILE that Windows expects allows values to be renamed. (This used to be commit 94fb39cfd967455ce5a554720c1c7e6183f91056) --- source4/lib/registry/ldb.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index d87bc6cf8e..884aed1579 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -112,6 +112,16 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, } +static char *reg_ldb_escape(TALLOC_CTX *mem_ctx, const char *value) +{ + struct ldb_val val; + + val.data = discard_const_p(uint8_t, value); + val.length = strlen(value); + + return ldb_dn_escape_value(mem_ctx, val); +} + static int reg_close_ldb_key(struct ldb_key_data *key) { if (key->subkeys != NULL) { @@ -447,7 +457,12 @@ static WERROR ldb_del_value (struct hive_key *key, const char *child) struct ldb_dn *childdn; childdn = ldb_dn_copy(kd->ldb, kd->dn); - ldb_dn_add_child_fmt(childdn, "value=%s", child); + if (!ldb_dn_add_child_fmt(childdn, "value=%s", + reg_ldb_escape(childdn, child))) + { + talloc_free(childdn); + return WERR_FOOBAR; + } ret = ldb_delete(kd->ldb, childdn); @@ -475,7 +490,12 @@ static WERROR ldb_set_value(struct hive_key *parent, msg = reg_ldb_pack_value(kd->ldb, mem_ctx, name, type, data); msg->dn = ldb_dn_copy(msg, kd->dn); - ldb_dn_add_child_fmt(msg->dn, "value=%s", name); + if (!ldb_dn_add_child_fmt(msg->dn, "value=%s", + reg_ldb_escape(mem_ctx, name))) + { + talloc_free(mem_ctx); + return WERR_FOOBAR; + } ret = ldb_add(kd->ldb, msg); if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { -- cgit From 85d60d2d091a2eb6bd4c73c87c94b10ee93167ee Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 18 Jan 2008 02:45:00 +0100 Subject: registry: Improve error codes and update tests. Rather than map the error returned by the registry to the correct error, return the correct error in the first place. Also deal with the fact that the right error code is now returned in a couple of places. (This used to be commit 1e31fcb8a097810a97e2d4bb1f243f1b34cc2415) --- source4/lib/registry/dir.c | 2 +- source4/lib/registry/ldb.c | 9 ++++++--- source4/lib/registry/patchfile.c | 10 +++++----- source4/lib/registry/regf.c | 2 +- source4/lib/registry/tests/hive.c | 4 ++-- source4/lib/registry/tests/registry.c | 16 ++++++++-------- 6 files changed, 23 insertions(+), 20 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/dir.c b/source4/lib/registry/dir.c index a13e3753b7..87d76e5eb7 100644 --- a/source4/lib/registry/dir.c +++ b/source4/lib/registry/dir.c @@ -282,7 +282,7 @@ static WERROR reg_dir_get_value(TALLOC_CTX *mem_ctx, contents = file_load(path, &size, mem_ctx); talloc_free(path); if (contents == NULL) - return WERR_NOT_FOUND; + return WERR_BADFILE; if (type != NULL) *type = 4; /* FIXME */ diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 884aed1579..17fac4abb2 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -111,7 +111,6 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, return msg; } - static char *reg_ldb_escape(TALLOC_CTX *mem_ctx, const char *value) { struct ldb_val val; @@ -303,7 +302,7 @@ static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, } if (res->count == 0) - return WERR_NOT_FOUND; + return WERR_BADFILE; reg_ldb_unpack_value(mem_ctx, res->msgs[0], NULL, data_type, data); @@ -410,8 +409,12 @@ static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent, talloc_strdup(mem_ctx, classname)); ret = ldb_add(parentkd->ldb, msg); + if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { + return WERR_ALREADY_EXISTS; + } + if (ret != LDB_SUCCESS) { - DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parentkd->ldb))); + DEBUG(1, ("ldb_add: %s\n", ldb_errstring(parentkd->ldb))); return WERR_FOOBAR; } diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index b6ad7dfb10..d859bc3134 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -132,10 +132,10 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, continue; } else { t1 = NULL; - error2 = WERR_DEST_NOT_FOUND; + error2 = WERR_NOT_FOUND; } - if (!W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { + if (!W_ERROR_EQUAL(error2, WERR_NOT_FOUND)) { DEBUG(0, ("Error occured while getting subkey by name: %s\n", win_errstr(error2))); talloc_free(mem_ctx); @@ -174,10 +174,10 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, name, &type2, &contents2); } else - error2 = WERR_DEST_NOT_FOUND; + error2 = WERR_BADFILE; if(!W_ERROR_IS_OK(error2) && - !W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { + !W_ERROR_EQUAL(error2, WERR_BADFILE)) { DEBUG(0, ("Error occured while getting value by name: %s\n", win_errstr(error2))); talloc_free(mem_ctx); @@ -210,7 +210,7 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, if (W_ERROR_IS_OK(error2)) continue; - if (!W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { + if (!W_ERROR_EQUAL(error2, WERR_BADFILE)) { DEBUG(0, ("Error occured while getting value by name: %s\n", win_errstr(error2))); return error2; diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 9b126cc808..475ec7bb5d 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -575,7 +575,7 @@ static WERROR regf_get_value_by_name(TALLOC_CTX *mem_ctx, } if (W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) - return WERR_NOT_FOUND; + return WERR_BADFILE; return error; } diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index 22b4785222..f72b7d6bf3 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -174,7 +174,7 @@ static bool test_get_value(struct torture_context *tctx, const void *test_data) torture_assert_werr_ok(tctx, error, "hive_key_add_name"); error = hive_get_value(mem_ctx, subkey, "Answer", &type, &value); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "getting missing value"); error = hive_key_set_value(subkey, "Answer", REG_DWORD, @@ -215,7 +215,7 @@ static bool test_del_value(struct torture_context *tctx, const void *test_data) torture_assert_werr_ok(tctx, error, "deleting value"); error = hive_get_value(mem_ctx, subkey, "Answer", &type, &value); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "getting value"); + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "getting value"); error = hive_key_del_value(subkey, "Answer"); torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 75fbe1cbea..59e31f55dc 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -195,15 +195,15 @@ static bool test_del_key(struct torture_context *tctx, void *_data) torture_assert_werr_ok(tctx, error, "getting predefined key failed"); - error = reg_key_add_name(rctx, root, "Hamburg", NULL, NULL, &newkey); + error = reg_key_add_name(rctx, root, "Polen", NULL, NULL, &newkey); torture_assert_werr_ok(tctx, error, "Creating key return code"); torture_assert(tctx, newkey != NULL, "Creating new key"); - error = reg_key_del(root, "Hamburg"); + error = reg_key_del(root, "Polen"); torture_assert_werr_ok(tctx, error, "Delete key"); - error = reg_key_del(root, "Hamburg"); + error = reg_key_del(root, "Polen"); torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "Delete missing key"); @@ -239,7 +239,7 @@ static bool test_flush_key(struct torture_context *tctx, void *_data) struct registry_key *root, *subkey; WERROR error; - if (!create_test_key(tctx, rctx, "Munchen", &root, &subkey)) + if (!create_test_key(tctx, rctx, "Bremen", &root, &subkey)) return false; error = reg_key_flush(subkey); @@ -416,7 +416,7 @@ static bool test_get_value(struct torture_context *tctx, void *_data) error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, &data); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "getting missing value"); error = reg_val_set(subkey, __FUNCTION__, REG_DWORD, @@ -447,12 +447,12 @@ static bool test_del_value(struct torture_context *tctx, void *_data) uint32_t value = 42; uint32_t type; - if (!create_test_key(tctx, rctx, "Duisburg", &root, &subkey)) + if (!create_test_key(tctx, rctx, "Warschau", &root, &subkey)) return false; error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, &data); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "getting missing value"); error = reg_val_set(subkey, __FUNCTION__, REG_DWORD, @@ -464,7 +464,7 @@ static bool test_del_value(struct torture_context *tctx, void *_data) error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, &data); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "getting missing value"); return true; -- cgit From e490415e2e300452e152373eb79fb437fb11449d Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Fri, 18 Jan 2008 02:51:51 +0100 Subject: When Windows attempts to create a new key, it looks for an available key name starting with "New Key #1" and iterating up to "New Key #99" before giving up. ldb_open_key() calls reg_path_to_ldb() to build the appropriate dn from the key name. reg_path_to_ldb() was not catching the error returned by ldb_dn_add_base_fmt() due to the unescaped '#' character, causing the returned dn to be that of the parent key, not the potential new key. Additionally, Windows expects a return value of WERR_BADFILE when a key does not exist, but WERR_NOT_FOUND was being returned instead. Correcting the building of the dn and the providing the expected return value allows new key creation to succeed. When attempting to delete a key, Windows passes the complete path to the key, not just the name of the child key to be deleted. Using reg_path_to_ldb() to build the correct dn allows key deletion to succeed. (This used to be commit d57792d67b865ef43e7f21640b158862627f4b45) --- source4/lib/registry/ldb.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 17fac4abb2..edfb1f2e59 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -168,7 +168,13 @@ static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, else keyname = mypath; if(strlen(keyname)) { - ldb_dn_add_base_fmt(ret, "key=%s", keyname); + if (!ldb_dn_add_base_fmt(ret, "key=%s", + reg_ldb_escape(local_ctx, + keyname))) + { + talloc_free(local_ctx); + return NULL; + } } if(begin) { @@ -430,18 +436,18 @@ static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent, return WERR_OK; } -static WERROR ldb_del_key(const struct hive_key *key, const char *child) +static WERROR ldb_del_key(const struct hive_key *key, const char *name) { int ret; struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data); - struct ldb_dn *childdn; + struct ldb_dn *ldap_path; + TALLOC_CTX *mem_ctx = talloc_init("ldb_del_key"); - childdn = ldb_dn_copy(parentkd->ldb, parentkd->dn); - ldb_dn_add_child_fmt(childdn, "key=%s", child); + ldap_path = reg_path_to_ldb(mem_ctx, key, name, NULL); - ret = ldb_delete(parentkd->ldb, childdn); + ret = ldb_delete(parentkd->ldb, ldap_path); - talloc_free(childdn); + talloc_free(mem_ctx); if (ret == LDB_ERR_NO_SUCH_OBJECT) { return WERR_NOT_FOUND; -- cgit From b5ba4910120e5350e48927cc0f5f06742ee02eb8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 18 Jan 2008 03:00:00 +0100 Subject: registry: Avoid mapping registry return codes: return the right value in the first place. (This used to be commit 434e4857cec17d6d9e8983e151c170eed59fc6d1) --- source4/lib/registry/local.c | 2 +- source4/lib/registry/samba.c | 2 +- source4/lib/registry/tests/registry.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index fa59f25596..3e463100c9 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -140,7 +140,7 @@ WERROR local_get_predefined_key(struct registry_context *ctx, } if (mp == NULL) - return WERR_NOT_FOUND; + return WERR_BADFILE; *key = reg_import_hive_key(ctx, mp->key, mp->path.predefined_key, diff --git a/source4/lib/registry/samba.c b/source4/lib/registry/samba.c index 02f3363bab..599385e73c 100644 --- a/source4/lib/registry/samba.c +++ b/source4/lib/registry/samba.c @@ -42,7 +42,7 @@ static WERROR mount_samba_hive(struct registry_context *ctx, error = reg_open_hive(ctx, location, auth_info, creds, lp_ctx, &hive); - if (W_ERROR_EQUAL(error, WERR_NOT_FOUND)) + if (W_ERROR_EQUAL(error, WERR_BADFILE)) error = reg_open_ldb_file(ctx, location, auth_info, creds, lp_ctx, &hive); diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 59e31f55dc..06783e6a75 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -53,7 +53,7 @@ static bool test_get_predefined_unknown(struct torture_context *tctx, WERROR error; error = reg_get_predefined_key(rctx, 1337, &root); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "getting predefined key failed"); return true; } -- cgit From 55ad09a01b31f2d2c9503f744b519e089f9f936b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 18 Jan 2008 03:37:06 +0100 Subject: registry: Use correct return values. (This used to be commit 98ebdbe52fd615ea62a3caa17acfe8bb31b8f85d) --- source4/lib/registry/dir.c | 4 ++-- source4/lib/registry/hive.c | 2 +- source4/lib/registry/ldb.c | 35 ++++++++++++++++++++++++++++------- source4/lib/registry/patchfile.c | 14 +++++++------- source4/lib/registry/regf.c | 22 +++++++++++----------- source4/lib/registry/tests/hive.c | 6 +++--- source4/lib/registry/tests/registry.c | 2 +- 7 files changed, 53 insertions(+), 32 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/dir.c b/source4/lib/registry/dir.c index 87d76e5eb7..27cae8c490 100644 --- a/source4/lib/registry/dir.c +++ b/source4/lib/registry/dir.c @@ -64,7 +64,7 @@ static WERROR reg_dir_del_key(const struct hive_key *k, const char *name) if (rmdir(child) == 0) ret = WERR_OK; else if (errno == ENOENT) - ret = WERR_NOT_FOUND; + ret = WERR_BADFILE; else ret = WERR_GENERAL_FAILURE; @@ -339,7 +339,7 @@ static WERROR reg_dir_del_value (struct hive_key *key, const char *name) if (unlink(path) < 0) { talloc_free(path); if (errno == ENOENT) - return WERR_NOT_FOUND; + return WERR_BADFILE; return WERR_GENERAL_FAILURE; } talloc_free(path); diff --git a/source4/lib/registry/hive.c b/source4/lib/registry/hive.c index bbe510772c..5d56a30b3e 100644 --- a/source4/lib/registry/hive.c +++ b/source4/lib/registry/hive.c @@ -41,7 +41,7 @@ _PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, fd = open(location, O_RDWR); if (fd == -1) { if (errno == ENOENT) - return WERR_NOT_FOUND; + return WERR_BADFILE; return WERR_BADFILE; } diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index edfb1f2e59..262859f64b 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -337,7 +337,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, DEBUG(3, ("Key '%s' not found\n", ldb_dn_get_linearized(ldap_path))); talloc_free(res); - return WERR_NOT_FOUND; + return WERR_BADFILE; } newkd = talloc_zero(mem_ctx, struct ldb_key_data); @@ -400,7 +400,7 @@ static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent, struct security_descriptor *sd, struct hive_key **newkey) { - const struct ldb_key_data *parentkd = (const struct ldb_key_data *)parent; + struct ldb_key_data *parentkd = (const struct ldb_key_data *)parent; struct ldb_message *msg; struct ldb_key_data *newkd; int ret; @@ -433,6 +433,10 @@ static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent, *newkey = (struct hive_key *)newkd; + /* reset cache */ + talloc_free(parentkd->subkeys); + parentkd->subkeys = NULL; + return WERR_OK; } @@ -450,12 +454,16 @@ static WERROR ldb_del_key(const struct hive_key *key, const char *name) talloc_free(mem_ctx); if (ret == LDB_ERR_NO_SUCH_OBJECT) { - return WERR_NOT_FOUND; + return WERR_BADFILE; } else if (ret != LDB_SUCCESS) { DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(parentkd->ldb))); return WERR_FOOBAR; } + /* reset cache */ + talloc_free(parentkd->subkeys); + parentkd->subkeys = NULL; + return WERR_OK; } @@ -478,12 +486,16 @@ static WERROR ldb_del_value (struct hive_key *key, const char *child) talloc_free(childdn); if (ret == LDB_ERR_NO_SUCH_OBJECT) { - return WERR_NOT_FOUND; + return WERR_BADFILE; } else if (ret != LDB_SUCCESS) { DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(kd->ldb))); return WERR_FOOBAR; } + /* reset cache */ + talloc_free(kd->values); + kd->values = NULL; + return WERR_OK; } @@ -521,6 +533,10 @@ static WERROR ldb_set_value(struct hive_key *parent, return WERR_FOOBAR; } + /* reset cache */ + talloc_free(kd->values); + kd->values = NULL; + talloc_free(mem_ctx); return WERR_OK; } @@ -537,17 +553,23 @@ static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, { struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data); + if (kd->subkeys == NULL) { + W_ERROR_NOT_OK_RETURN(cache_subkeys(kd)); + } + + if (kd->values == NULL) { + W_ERROR_NOT_OK_RETURN(cache_values(kd)); + } + /* FIXME */ if (classname != NULL) *classname = NULL; if (num_subkeys != NULL) { - W_ERROR_NOT_OK_RETURN(cache_subkeys(kd)); *num_subkeys = kd->subkey_count; } if (num_values != NULL) { - W_ERROR_NOT_OK_RETURN(cache_values(kd)); *num_values = kd->value_count; } @@ -557,7 +579,6 @@ static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, if (max_subkeynamelen != NULL) { int i; struct ldb_message_element *el; - W_ERROR_NOT_OK_RETURN(cache_subkeys(kd)); *max_subkeynamelen = 0; diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index d859bc3134..fa1367bbd2 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -82,11 +82,11 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, if (W_ERROR_IS_OK(error2)) continue; } else { - error2 = WERR_DEST_NOT_FOUND; + error2 = WERR_BADFILE; t2 = NULL; } - if (!W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { + if (!W_ERROR_EQUAL(error2, WERR_BADFILE)) { DEBUG(0, ("Error occured while getting subkey by name: %s\n", win_errstr(error2))); talloc_free(mem_ctx); @@ -132,10 +132,10 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, continue; } else { t1 = NULL; - error2 = WERR_NOT_FOUND; + error2 = WERR_BADFILE; } - if (!W_ERROR_EQUAL(error2, WERR_NOT_FOUND)) { + if (!W_ERROR_EQUAL(error2, WERR_BADFILE)) { DEBUG(0, ("Error occured while getting subkey by name: %s\n", win_errstr(error2))); talloc_free(mem_ctx); @@ -238,14 +238,14 @@ _PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1, struct registry_key *r1 = NULL, *r2 = NULL; error = reg_get_predefined_key(ctx1, i, &r1); if (!W_ERROR_IS_OK(error) && - !W_ERROR_EQUAL(error, WERR_NOT_FOUND)) { + !W_ERROR_EQUAL(error, WERR_BADFILE)) { DEBUG(0, ("Unable to open hive %s for backend 1\n", reg_get_predef_name(i))); } error = reg_get_predefined_key(ctx2, i, &r2); if (!W_ERROR_IS_OK(error) && - !W_ERROR_EQUAL(error, WERR_NOT_FOUND)) { + !W_ERROR_EQUAL(error, WERR_BADFILE)) { DEBUG(0, ("Unable to open hive %s for backend 2\n", reg_get_predef_name(i))); } @@ -356,7 +356,7 @@ static WERROR reg_diff_apply_set_value(void *_ctx, const char *path, /* Open key */ error = reg_open_key_abs(ctx, ctx, path, &tmp); - if (W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) { + if (W_ERROR_EQUAL(error, WERR_BADFILE)) { DEBUG(0, ("Error opening key '%s'\n", path)); return error; } diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 475ec7bb5d..15b60745f0 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -870,7 +870,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, break; } if (key_off == 0) - return WERR_NOT_FOUND; + return WERR_BADFILE; } else if (!strncmp((char *)data.data, "lf", 2)) { struct lf_block lf; struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience); @@ -905,7 +905,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, break; } if (key_off == 0) - return WERR_NOT_FOUND; + return WERR_BADFILE; } else if (!strncmp((char *)data.data, "lh", 2)) { struct lh_block lh; struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience); @@ -942,7 +942,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, break; } if (key_off == 0) - return WERR_NOT_FOUND; + return WERR_BADFILE; } else if (!strncmp((char *)data.data, "ri", 2)) { struct ri_block ri; struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience); @@ -1022,7 +1022,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, } talloc_free(pull); if (!key_off) - return WERR_NOT_FOUND; + return WERR_BADFILE; } else { DEBUG(0, ("Unknown subkey list type.\n")); return WERR_GENERAL_FAILURE; @@ -1419,7 +1419,7 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, } if (!found_offset) { DEBUG(2, ("Subkey not found\n")); - return WERR_NOT_FOUND; + return WERR_BADFILE; } li.key_count--; @@ -1464,7 +1464,7 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, } if (!found_offset) { DEBUG(2, ("Subkey not found\n")); - return WERR_NOT_FOUND; + return WERR_BADFILE; } lf.key_count--; @@ -1510,7 +1510,7 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, } if (!found_offset) { DEBUG(0, ("Subkey not found\n")); - return WERR_NOT_FOUND; + return WERR_BADFILE; } lh.key_count--; @@ -1548,7 +1548,7 @@ static WERROR regf_del_value (struct hive_key *key, const char *name) uint32_t i; if (nk->values_offset == -1) { - return WERR_NOT_FOUND; + return WERR_BADFILE; } values = hbin_get(regf, nk->values_offset); @@ -1572,7 +1572,7 @@ static WERROR regf_del_value (struct hive_key *key, const char *name) } } if (!found_offset) { - return WERR_NOT_FOUND; + return WERR_BADFILE; } else { nk->num_values--; values.length = (nk->num_values)*4; @@ -1608,14 +1608,14 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name) if (parent_nk->subkeys_offset == -1) { DEBUG(4, ("Subkey list is empty, this key cannot contain subkeys.\n")); - return WERR_NOT_FOUND; + return WERR_BADFILE; } /* Find the key */ if (!W_ERROR_IS_OK(regf_get_subkey_by_name(parent_nk, parent, name, (struct hive_key **)&key))) { DEBUG(2, ("Key '%s' not found\n", name)); - return WERR_NOT_FOUND; + return WERR_BADFILE; } if (key->nk->subkeys_offset != -1 || diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index f72b7d6bf3..4d27e83a74 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -31,7 +31,7 @@ static bool test_del_nonexistant_key(struct torture_context *tctx, { const struct hive_key *root = (const struct hive_key *)test_data; WERROR error = hive_key_del(root, "bla"); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "invalid return code"); return true; @@ -134,7 +134,7 @@ static bool test_del_key(struct torture_context *tctx, const void *test_data) torture_assert_werr_ok(tctx, error, "reg_key_del"); error = hive_key_del(root, "Nested Key"); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "reg_key_del"); + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "reg_key_del"); return true; } @@ -218,7 +218,7 @@ static bool test_del_value(struct torture_context *tctx, const void *test_data) torture_assert_werr_equal(tctx, error, WERR_BADFILE, "getting value"); error = hive_key_del_value(subkey, "Answer"); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "deleting value"); return true; diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 06783e6a75..7d14b3a412 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -204,7 +204,7 @@ static bool test_del_key(struct torture_context *tctx, void *_data) torture_assert_werr_ok(tctx, error, "Delete key"); error = reg_key_del(root, "Polen"); - torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + torture_assert_werr_equal(tctx, error, WERR_BADFILE, "Delete missing key"); return true; -- cgit From 127e8743193dbb4b0632172ac5a562a3b807f07d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 22 Jan 2008 18:28:51 +0100 Subject: registry: Use manually written .pc file. (This used to be commit 5c64d4adaf50215ec2645f76e6c0335572147614) --- source4/lib/registry/config.mk | 1 + source4/lib/registry/registry.pc.in | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 source4/lib/registry/registry.pc.in (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index f1f50479cb..a7365a49ae 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -18,6 +18,7 @@ clean:: # Start SUBSYSTEM registry [LIBRARY::registry] VERSION = 0.0.1 +PC_FILE = registry.pc SO_VERSION = 0 DESCRIPTION = Windows-style registry library OBJ_FILES = \ diff --git a/source4/lib/registry/registry.pc.in b/source4/lib/registry/registry.pc.in new file mode 100644 index 0000000000..21184c483c --- /dev/null +++ b/source4/lib/registry/registry.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: registry +Description: Windows-style registry library +Requires: ldb +Requires.private: +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lregistry +Cflags: -I${includedir} -DHAVE_IMMEDIATE_STRUCTURES=1 -- cgit From 9209470b920eaa904129ae43d454db2526f97ca8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 22 Jan 2008 18:36:14 +0100 Subject: dcerpc: Use manually written .pc files for dcerpc and ndr. (This used to be commit 676fd18fa2914b7b5530014a944a11ea1d6f631d) --- source4/lib/registry/registry.pc.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.pc.in b/source4/lib/registry/registry.pc.in index 21184c483c..98943a0736 100644 --- a/source4/lib/registry/registry.pc.in +++ b/source4/lib/registry/registry.pc.in @@ -7,6 +7,6 @@ Name: registry Description: Windows-style registry library Requires: ldb Requires.private: -Version: @PACKAGE_VERSION@ +Version: 0.0.1 Libs: -L${libdir} -lregistry Cflags: -I${includedir} -DHAVE_IMMEDIATE_STRUCTURES=1 -- cgit From a2595477869d5fee2f916bc857ca028e3b2fc677 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 22 Jan 2008 18:49:51 +0100 Subject: build: Remove support for DESCRIPTION setting that is now unused. (This used to be commit 91d7ba5202e6c375456a42c2c6861f63c7fcfc20) --- source4/lib/registry/config.mk | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index a7365a49ae..7a9c8fcff1 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -20,7 +20,6 @@ clean:: VERSION = 0.0.1 PC_FILE = registry.pc SO_VERSION = 0 -DESCRIPTION = Windows-style registry library OBJ_FILES = \ interface.o \ util.o \ -- cgit From 7a402da97eb12fbcae3ad86171562623ba52a116 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 9 Feb 2008 17:18:51 +0100 Subject: registry: Fix warning. (This used to be commit dad809030478a85ac13a73bce9c07314792f01c2) --- source4/lib/registry/ldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 262859f64b..0c8a55396e 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -400,7 +400,7 @@ static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent, struct security_descriptor *sd, struct hive_key **newkey) { - struct ldb_key_data *parentkd = (const struct ldb_key_data *)parent; + struct ldb_key_data *parentkd = discard_const_p(struct ldb_key_data, parent); struct ldb_message *msg; struct ldb_key_data *newkd; int ret; -- cgit From d82b6dd09adc0b30567ffcc9e47553eb3ed51b2a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 11 Feb 2008 11:47:31 +0100 Subject: Fix switching of hives in regshell (#5254) (This used to be commit 5f33545c78e13871d622c0a5a0ded789bf624869) --- source4/lib/registry/tools/regshell.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 93f28f3e5a..d5c506ab31 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -116,6 +116,9 @@ static WERROR cmd_predef(struct regshell_context *ctx, int argc, char **argv) argv[1], win_errstr(error)); return error; } + + ctx->path = strupper_talloc(ctx, argv[1]); + ctx->current = ret; } return WERR_OK; -- cgit From b66ee2ed22754dd44b20c06e573072e328d9a3dd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 16 Feb 2008 18:38:02 +0100 Subject: Move responsibilities of build.h to makefile. (This used to be commit a43f6d37bce85748e9cf2675e5beced5db26f1c3) --- source4/lib/registry/interface.c | 1 - source4/lib/registry/local.c | 1 - 2 files changed, 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/interface.c b/source4/lib/registry/interface.c index a18fd2c28c..ff3ddf0a35 100644 --- a/source4/lib/registry/interface.c +++ b/source4/lib/registry/interface.c @@ -21,7 +21,6 @@ #include "lib/util/dlinklist.h" #include "lib/registry/registry.h" #include "system/filesys.h" -#include "build.h" /** diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index 3e463100c9..b2cdec9cdf 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -22,7 +22,6 @@ #include "lib/util/dlinklist.h" #include "lib/registry/registry.h" #include "system/filesys.h" -#include "build.h" struct reg_key_path { uint32_t predefined_key; -- cgit From 48307b54f95395fbd201d92d738b482f80cd15ef Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 16:01:19 +0100 Subject: Remove more uses of global_loadparm. (This used to be commit 3430cc60972b94d0d238bc39f473feed96949c5d) --- source4/lib/registry/patchfile.c | 4 +++- source4/lib/registry/patchfile_dotreg.c | 10 ++++++++-- source4/lib/registry/registry.h | 7 +++---- source4/lib/registry/tests/generic.c | 14 +++++++------- source4/lib/registry/tools/regshell.c | 7 ++++--- source4/lib/registry/tools/regtree.c | 2 +- source4/lib/registry/util.c | 18 ++++++++++++------ 7 files changed, 38 insertions(+), 24 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index fa1367bbd2..a4579010cd 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -23,6 +23,7 @@ #include "lib/registry/patchfile.h" #include "lib/registry/registry.h" #include "system/filesys.h" +#include "param/param.h" _PUBLIC_ WERROR reg_preg_diff_load(int fd, @@ -30,6 +31,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, void *callback_data); _PUBLIC_ WERROR reg_dotreg_diff_load(int fd, + struct smb_iconv_convenience *iconv_convenience, const struct reg_diff_callbacks *callbacks, void *callback_data); @@ -306,7 +308,7 @@ _PUBLIC_ WERROR reg_diff_load(const char *filename, return reg_preg_diff_load(fd, callbacks, callback_data); } else { /* Must be a normal .REG file */ - return reg_dotreg_diff_load(fd, callbacks, callback_data); + return reg_dotreg_diff_load(fd, lp_iconv_convenience(global_loadparm), callbacks, callback_data); } } diff --git a/source4/lib/registry/patchfile_dotreg.c b/source4/lib/registry/patchfile_dotreg.c index ebcafc92af..46ea7c0008 100644 --- a/source4/lib/registry/patchfile_dotreg.c +++ b/source4/lib/registry/patchfile_dotreg.c @@ -26,6 +26,7 @@ #include "lib/registry/patchfile.h" #include "lib/registry/registry.h" #include "system/filesys.h" +#include "param/param.h" /** * @file @@ -36,6 +37,7 @@ struct dotreg_data { int fd; + struct smb_iconv_convenience *iconv_convenience; }; static WERROR reg_dotreg_diff_add_key(void *_data, const char *key_name) @@ -64,7 +66,7 @@ static WERROR reg_dotreg_diff_set_value(void *_data, const char *path, fdprintf(data->fd, "\"%s\"=%s:%s\n", value_name, str_regtype(value_type), - reg_val_data_string(NULL, value_type, value)); + reg_val_data_string(NULL, data->iconv_convenience, value_type, value)); return WERR_OK; } @@ -107,6 +109,8 @@ _PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, data = talloc_zero(ctx, struct dotreg_data); *callback_data = data; + data->iconv_convenience = lp_iconv_convenience(global_loadparm); + if (filename) { data->fd = open(filename, O_CREAT, 0755); if (data->fd == -1) { @@ -135,6 +139,7 @@ _PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, * Load diff file */ _PUBLIC_ WERROR reg_dotreg_diff_load(int fd, + struct smb_iconv_convenience *iconv_convenience, const struct reg_diff_callbacks *callbacks, void *callback_data) { @@ -239,7 +244,8 @@ _PUBLIC_ WERROR reg_dotreg_diff_load(int fd, q++; } - reg_string_to_val(line, q?p:"REG_SZ", q?q:p, + reg_string_to_val(line, iconv_convenience, + q?p:"REG_SZ", q?q:p, &value_type, &value); error = callbacks->set_value(callback_data, curkey, line, diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index fac9180378..5e0b971a1d 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -254,11 +254,10 @@ WERROR reg_create_key(TALLOC_CTX *mem_ctx, /* Utility functions */ const char *str_regtype(int type); -char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, - const DATA_BLOB data); -char *reg_val_description(TALLOC_CTX *mem_ctx, const char *name, +char *reg_val_data_string(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, uint32_t type, const DATA_BLOB data); +char *reg_val_description(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, const char *name, uint32_t type, const DATA_BLOB data); -bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, +bool reg_string_to_val(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data); WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result); diff --git a/source4/lib/registry/tests/generic.c b/source4/lib/registry/tests/generic.c index 25a89793bd..145e599504 100644 --- a/source4/lib/registry/tests/generic.c +++ b/source4/lib/registry/tests/generic.c @@ -45,7 +45,7 @@ static bool test_reg_val_data_string_dword(struct torture_context *ctx) uint32_t d = 0x20; DATA_BLOB db = { (uint8_t *)&d, sizeof(d) }; torture_assert_str_equal(ctx, "0x20", - reg_val_data_string(ctx, REG_DWORD, db), + reg_val_data_string(ctx, lp_iconv_convenience(ctx->lp_ctx), REG_DWORD, db), "dword failed"); return true; } @@ -56,11 +56,11 @@ static bool test_reg_val_data_string_sz(struct torture_context *ctx) db.length = convert_string_talloc(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UNIX, CH_UTF16, "bla", 3, (void **)&db.data); torture_assert_str_equal(ctx, "bla", - reg_val_data_string(ctx, REG_SZ, db), + reg_val_data_string(ctx, lp_iconv_convenience(ctx->lp_ctx), REG_SZ, db), "sz failed"); db.length = 4; torture_assert_str_equal(ctx, "bl", - reg_val_data_string(ctx, REG_SZ, db), + reg_val_data_string(ctx, lp_iconv_convenience(ctx->lp_ctx), REG_SZ, db), "sz failed"); return true; } @@ -70,7 +70,7 @@ static bool test_reg_val_data_string_binary(struct torture_context *ctx) uint8_t x[] = { 0x1, 0x2, 0x3, 0x4 }; DATA_BLOB db = { x, 4 }; torture_assert_str_equal(ctx, "01020304", - reg_val_data_string(ctx, REG_BINARY, db), + reg_val_data_string(ctx, lp_iconv_convenience(ctx->lp_ctx), REG_BINARY, db), "binary failed"); return true; } @@ -80,7 +80,7 @@ static bool test_reg_val_data_string_empty(struct torture_context *ctx) { DATA_BLOB db = { NULL, 0 }; torture_assert_str_equal(ctx, "", - reg_val_data_string(ctx, REG_BINARY, db), + reg_val_data_string(ctx, lp_iconv_convenience(ctx->lp_ctx), REG_BINARY, db), "empty failed"); return true; } @@ -93,7 +93,7 @@ static bool test_reg_val_description(struct torture_context *ctx) strlen("stationary traveller"), (void **)&data.data); torture_assert_str_equal(ctx, "camel = REG_SZ : stationary traveller", - reg_val_description(ctx, "camel", REG_SZ, data), + reg_val_description(ctx, lp_iconv_convenience(ctx->lp_ctx), "camel", REG_SZ, data), "reg_val_description failed"); return true; } @@ -107,7 +107,7 @@ static bool test_reg_val_description_nullname(struct torture_context *ctx) strlen("west berlin"), (void **)&data.data); torture_assert_str_equal(ctx, " = REG_SZ : west berlin", - reg_val_description(ctx, NULL, REG_SZ, data), + reg_val_description(ctx, lp_iconv_convenience(ctx->lp_ctx), NULL, REG_SZ, data), "description with null name failed"); return true; } diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index d5c506ab31..58f64cb049 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -141,7 +141,8 @@ static WERROR cmd_set(struct regshell_context *ctx, int argc, char **argv) return WERR_INVALID_PARAM; } - if (!reg_string_to_val(ctx, argv[2], argv[3], &val.data_type, + if (!reg_string_to_val(ctx, lp_iconv_convenience(cmdline_lp_ctx), + argv[2], argv[3], &val.data_type, &val.data)) { fprintf(stderr, "Unable to interpret data\n"); return WERR_INVALID_PARAM; @@ -199,7 +200,7 @@ static WERROR cmd_print(struct regshell_context *ctx, int argc, char **argv) } printf("%s\n%s\n", str_regtype(value_type), - reg_val_data_string(ctx, value_type, value_data)); + reg_val_data_string(ctx, lp_iconv_convenience(cmdline_lp_ctx), value_type, value_data)); return WERR_OK; } @@ -233,7 +234,7 @@ static WERROR cmd_ls(struct regshell_context *ctx, int argc, char **argv) &data_type, &data)); i++) { printf("V \"%s\" %s %s\n", name, str_regtype(data_type), - reg_val_data_string(ctx, data_type, data)); + reg_val_data_string(ctx, lp_iconv_convenience(cmdline_lp_ctx), data_type, data)); } return WERR_OK; diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 0f47d8f8dd..424d3515e0 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -82,7 +82,7 @@ static void print_tree(int level, struct registry_key *p, int j; char *desc; for(j = 0; j < level+1; j++) putchar(' '); - desc = reg_val_description(mem_ctx, valuename, + desc = reg_val_description(mem_ctx, lp_iconv_convenience(cmdline_lp_ctx), valuename, value_type, value_data); printf("%s\n", desc); } diff --git a/source4/lib/registry/util.c b/source4/lib/registry/util.c index a251ae49a5..68efd56a86 100644 --- a/source4/lib/registry/util.c +++ b/source4/lib/registry/util.c @@ -51,7 +51,9 @@ _PUBLIC_ const char *str_regtype(int type) return "Unknown"; } -_PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, +_PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + uint32_t type, const DATA_BLOB data) { char *ret = NULL; @@ -62,7 +64,7 @@ _PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, switch (type) { case REG_EXPAND_SZ: case REG_SZ: - convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, + convert_string_talloc(mem_ctx, iconv_convenience, CH_UTF16, CH_UNIX, data.data, data.length, (void **)&ret); return ret; @@ -85,16 +87,20 @@ _PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, } /** Generate a string that describes a registry value */ -_PUBLIC_ char *reg_val_description(TALLOC_CTX *mem_ctx, const char *name, +_PUBLIC_ char *reg_val_description(TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + const char *name, uint32_t data_type, const DATA_BLOB data) { return talloc_asprintf(mem_ctx, "%s = %s : %s", name?name:"", str_regtype(data_type), - reg_val_data_string(mem_ctx, data_type, data)); + reg_val_data_string(mem_ctx, iconv_convenience, data_type, data)); } -_PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, +_PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data) { @@ -118,7 +124,7 @@ _PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, { case REG_SZ: case REG_EXPAND_SZ: - data->length = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UNIX, CH_UTF16, + data->length = convert_string_talloc(mem_ctx, iconv_convenience, CH_UNIX, CH_UTF16, data_str, strlen(data_str), (void **)&data->data); break; -- cgit From c38c2765d1059b33f044a42c6555f3d10d339911 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 17:17:37 +0100 Subject: Remove yet more uses of global_loadparm. (This used to be commit e01c1e87c0fe9709df7eb5b863f7ce85564174cd) --- source4/lib/registry/hive.c | 3 ++- source4/lib/registry/hive.h | 3 ++- source4/lib/registry/regf.c | 10 ++++++---- source4/lib/registry/tests/hive.c | 4 +++- 4 files changed, 13 insertions(+), 7 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/hive.c b/source4/lib/registry/hive.c index 5d56a30b3e..ad6a6421ab 100644 --- a/source4/lib/registry/hive.c +++ b/source4/lib/registry/hive.c @@ -22,6 +22,7 @@ #include "includes.h" #include "hive.h" #include "system/filesys.h" +#include "param/param.h" /** Open a registry file/host/etc */ _PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, @@ -52,7 +53,7 @@ _PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, if (!strncmp(peek, "regf", 4)) { close(fd); - return reg_open_regf_file(parent_ctx, location, lp_ctx, root); + return reg_open_regf_file(parent_ctx, location, lp_iconv_convenience(lp_ctx), root); } else if (!strncmp(peek, "TDB file", 8)) { close(fd); return reg_open_ldb_file(parent_ctx, location, session_info, diff --git a/source4/lib/registry/hive.h b/source4/lib/registry/hive.h index 6d9a69c7c5..87f335663d 100644 --- a/source4/lib/registry/hive.h +++ b/source4/lib/registry/hive.h @@ -188,7 +188,7 @@ WERROR hive_key_flush(struct hive_key *key); WERROR reg_open_directory(TALLOC_CTX *parent_ctx, const char *location, struct hive_key **key); WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, - const char *location, struct loadparm_context *lp_ctx, + const char *location, struct smb_iconv_convenience *iconv_convenience, struct hive_key **key); WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, @@ -200,6 +200,7 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, WERROR reg_create_directory(TALLOC_CTX *parent_ctx, const char *location, struct hive_key **key); WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, + struct smb_iconv_convenience *iconv_convenience, const char *location, int major_version, struct hive_key **key); diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 15b60745f0..cf3e564c0e 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -1863,7 +1863,9 @@ static WERROR regf_save_hbin(struct regf_data *regf) return WERR_OK; } -WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location, +WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, + struct smb_iconv_convenience *iconv_convenience, + const char *location, int minor_version, struct hive_key **key) { struct regf_data *regf; @@ -1874,7 +1876,7 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location, regf = (struct regf_data *)talloc_zero(NULL, struct regf_data); - regf->iconv_convenience = lp_iconv_convenience(global_loadparm); + regf->iconv_convenience = iconv_convenience; W_ERROR_HAVE_NO_MEMORY(regf); @@ -1950,7 +1952,7 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location, } WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, const char *location, - struct loadparm_context *lp_ctx, struct hive_key **key) + struct smb_iconv_convenience *iconv_convenience, struct hive_key **key) { struct regf_data *regf; struct regf_hdr *regf_hdr; @@ -1959,7 +1961,7 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, const char *location, regf = (struct regf_data *)talloc_zero(NULL, struct regf_data); - regf->iconv_convenience = lp_iconv_convenience(lp_ctx); + regf->iconv_convenience = iconv_convenience; W_ERROR_HAVE_NO_MEMORY(regf); diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index 4d27e83a74..1dcb464d80 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -25,6 +25,7 @@ #include "torture/torture.h" #include "librpc/gen_ndr/winreg.h" #include "system/filesys.h" +#include "param/param.h" static bool test_del_nonexistant_key(struct torture_context *tctx, const void *test_data) @@ -349,7 +350,8 @@ static bool hive_setup_regf(struct torture_context *tctx, void **data) rmdir(dirname); - error = reg_create_regf_file(tctx, dirname, 5, &key); + error = reg_create_regf_file(tctx, lp_iconv_convenience(tctx->lp_ctx), + dirname, 5, &key); if (!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to create new regf file\n"); return false; -- cgit From 10169a203019445e6d325a5c1559de3c73782237 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 17:54:24 +0100 Subject: Remove more global_loadparm instance.s (This used to be commit a1280252ce924df69d911e597b7f65d8038abef9) --- source4/lib/registry/ldb.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 0c8a55396e..dfd368ea80 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -36,7 +36,9 @@ struct ldb_key_data int subkey_count, value_count; }; -static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, +static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + struct ldb_message *msg, const char **name, uint32_t *type, DATA_BLOB *data) { @@ -57,7 +59,7 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, { case REG_SZ: case REG_EXPAND_SZ: - data->length = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF8, CH_UTF16, + data->length = convert_string_talloc(mem_ctx, iconv_convenience, CH_UTF8, CH_UTF16, val->data, val->length, (void **)&data->data); break; @@ -281,7 +283,7 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct hive_key *k, if (idx >= kd->value_count) return WERR_NO_MORE_ITEMS; - reg_ldb_unpack_value(mem_ctx, kd->values[idx], + reg_ldb_unpack_value(mem_ctx, lp_iconv_convenience(global_loadparm), kd->values[idx], name, data_type, data); return WERR_OK; @@ -310,7 +312,7 @@ static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, if (res->count == 0) return WERR_BADFILE; - reg_ldb_unpack_value(mem_ctx, res->msgs[0], NULL, data_type, data); + reg_ldb_unpack_value(mem_ctx, lp_iconv_convenience(global_loadparm), res->msgs[0], NULL, data_type, data); return WERR_OK; } @@ -607,7 +609,9 @@ static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, if (max_valbufsize != NULL) { DATA_BLOB data; - reg_ldb_unpack_value(mem_ctx, kd->values[i], NULL, + reg_ldb_unpack_value(mem_ctx, + lp_iconv_convenience(global_loadparm), + kd->values[i], NULL, NULL, &data); *max_valbufsize = MAX(*max_valbufsize, data.length); talloc_free(data.data); -- cgit From 299265d47b5b2faac39fbf908c738f336ea21e67 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 18:09:47 +0100 Subject: Remove yet more global_loadparm instances. (This used to be commit 5de88728ac5c567d3711d1ac6862bbdaced84b75) --- source4/lib/registry/patchfile.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index a4579010cd..7903bea246 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -273,6 +273,7 @@ _PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1, * Load diff file */ _PUBLIC_ WERROR reg_diff_load(const char *filename, + struct smb_iconv_convenience *iconv_convenience, const struct reg_diff_callbacks *callbacks, void *callback_data) { @@ -308,7 +309,7 @@ _PUBLIC_ WERROR reg_diff_load(const char *filename, return reg_preg_diff_load(fd, callbacks, callback_data); } else { /* Must be a normal .REG file */ - return reg_dotreg_diff_load(fd, lp_iconv_convenience(global_loadparm), callbacks, callback_data); + return reg_dotreg_diff_load(fd, iconv_convenience, callbacks, callback_data); } } @@ -442,5 +443,6 @@ _PUBLIC_ WERROR reg_diff_apply(struct registry_context *ctx, const char *filenam callbacks.del_all_values = reg_diff_apply_del_all_values; callbacks.done = NULL; - return reg_diff_load(filename, &callbacks, ctx); + return reg_diff_load(filename, lp_iconv_convenience(global_loadparm), + &callbacks, ctx); } -- cgit From 3101cb888d5cbad785050b8491b138d683d444fb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 25 Feb 2008 12:51:55 +0100 Subject: Remove uses of global_loadparm. (This used to be commit a16c9a2129ce92e7e1a613b2badd168e42ead436) --- source4/lib/registry/patchfile.c | 3 ++- source4/lib/registry/patchfile.h | 1 + source4/lib/registry/patchfile_dotreg.c | 3 ++- source4/lib/registry/patchfile_preg.c | 17 +++++++++-------- source4/lib/registry/tools/regdiff.c | 2 +- 5 files changed, 15 insertions(+), 11 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index 7903bea246..687fd4b91b 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -27,6 +27,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, + struct smb_iconv_convenience *iconv_convenience, const struct reg_diff_callbacks *callbacks, void *callback_data); @@ -306,7 +307,7 @@ _PUBLIC_ WERROR reg_diff_load(const char *filename, #endif if (strncmp(hdr, "PReg", 4) == 0) { /* Must be a GPO Registry.pol file */ - return reg_preg_diff_load(fd, callbacks, callback_data); + return reg_preg_diff_load(fd, iconv_convenience, callbacks, callback_data); } else { /* Must be a normal .REG file */ return reg_dotreg_diff_load(fd, iconv_convenience, callbacks, callback_data); diff --git a/source4/lib/registry/patchfile.h b/source4/lib/registry/patchfile.h index 08a977d9cd..9289390685 100644 --- a/source4/lib/registry/patchfile.h +++ b/source4/lib/registry/patchfile.h @@ -43,6 +43,7 @@ WERROR reg_generate_diff(struct registry_context *ctx1, const struct reg_diff_callbacks *callbacks, void *callback_data); WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, + struct smb_iconv_convenience *iconv_convenience, struct reg_diff_callbacks **callbacks, void **callback_data); WERROR reg_generate_diff_key(struct registry_key *oldkey, diff --git a/source4/lib/registry/patchfile_dotreg.c b/source4/lib/registry/patchfile_dotreg.c index 46ea7c0008..6de642ecb8 100644 --- a/source4/lib/registry/patchfile_dotreg.c +++ b/source4/lib/registry/patchfile_dotreg.c @@ -101,6 +101,7 @@ static WERROR reg_dotreg_diff_del_all_values(void *callback_data, * Save registry diff */ _PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, + struct smb_iconv_convenience *iconv_convenience, struct reg_diff_callbacks **callbacks, void **callback_data) { @@ -109,7 +110,7 @@ _PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, data = talloc_zero(ctx, struct dotreg_data); *callback_data = data; - data->iconv_convenience = lp_iconv_convenience(global_loadparm); + data->iconv_convenience = iconv_convenience; if (filename) { data->fd = open(filename, O_CREAT, 0755); diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c index 9cc9a5dec2..0d39e67450 100644 --- a/source4/lib/registry/patchfile_preg.c +++ b/source4/lib/registry/patchfile_preg.c @@ -29,14 +29,14 @@ struct preg_data { int fd; }; -static WERROR preg_read_utf16(int fd, char *c) +static WERROR preg_read_utf16(struct smb_iconv_convenience *ic, int fd, char *c) { uint16_t v; if (read(fd, &v, 2) < 2) { return WERR_GENERAL_FAILURE; } - push_codepoint(lp_iconv_convenience(global_loadparm), c, v); + push_codepoint(ic, c, v); return WERR_OK; } @@ -123,6 +123,7 @@ _PUBLIC_ WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename, * Load diff file */ _PUBLIC_ WERROR reg_preg_diff_load(int fd, + struct smb_iconv_convenience *iconv_convenience, const struct reg_diff_callbacks *callbacks, void *callback_data) { @@ -162,7 +163,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, while(1) { uint32_t value_type, length; - if (!W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr))) { + if (!W_ERROR_IS_OK(preg_read_utf16(iconv_convenience, fd, buf_ptr))) { break; } if (*buf_ptr != '[') { @@ -173,7 +174,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, /* Get the path */ buf_ptr = buf; - while (W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && + while (W_ERROR_IS_OK(preg_read_utf16(iconv_convenience, fd, buf_ptr)) && *buf_ptr != ';' && buf_ptr-buf < buf_size) { buf_ptr++; } @@ -181,7 +182,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, /* Get the name */ buf_ptr = buf; - while (W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && + while (W_ERROR_IS_OK(preg_read_utf16(iconv_convenience, fd, buf_ptr)) && *buf_ptr != ';' && buf_ptr-buf < buf_size) { buf_ptr++; } @@ -195,7 +196,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, } /* Read past delimiter */ buf_ptr = buf; - if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && + if (!(W_ERROR_IS_OK(preg_read_utf16(iconv_convenience, fd, buf_ptr)) && *buf_ptr == ';') && buf_ptr-buf < buf_size) { DEBUG(0, ("Error in PReg file.\n")); ret = WERR_GENERAL_FAILURE; @@ -209,7 +210,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, } /* Read past delimiter */ buf_ptr = buf; - if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && + if (!(W_ERROR_IS_OK(preg_read_utf16(iconv_convenience, fd, buf_ptr)) && *buf_ptr == ';') && buf_ptr-buf < buf_size) { DEBUG(0, ("Error in PReg file.\n")); ret = WERR_GENERAL_FAILURE; @@ -227,7 +228,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, /* Check if delimiter is in place (whine if it isn't) */ buf_ptr = buf; - if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && + if (!(W_ERROR_IS_OK(preg_read_utf16(iconv_convenience, fd, buf_ptr)) && *buf_ptr == ']') && buf_ptr-buf < buf_size) { DEBUG(0, ("Warning: Missing ']' in PReg file, expected ']', got '%c' 0x%x.\n", *buf_ptr, *buf_ptr)); diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 406eaeea3d..c94380efd2 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -126,7 +126,7 @@ int main(int argc, const char **argv) poptFreeContext(pc); - error = reg_dotreg_diff_save(ctx, outputfile, &callbacks, + error = reg_dotreg_diff_save(ctx, outputfile, lp_iconv_convenience(cmdline_lp_ctx), &callbacks, &callback_data); if (!W_ERROR_IS_OK(error)) { fprintf(stderr, "Problem saving registry diff to '%s': %s\n", -- cgit From c8af9559dc44b578d3b49620f690652a1676e9bd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 26 Feb 2008 15:11:47 +0100 Subject: Move manpage management out of the perl build system. (This used to be commit a660ab262e7202baccf16cb8b2bc47cb8efacc34) --- source4/lib/registry/config.mk | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 7a9c8fcff1..af5b1bc301 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -52,10 +52,11 @@ INSTALLDIR = BINDIR OBJ_FILES = tools/regdiff.o PRIVATE_DEPENDENCIES = \ LIBSAMBA-CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS -MANPAGE = man/regdiff.1 # End BINARY regdiff ################################################ +MANPAGES += lib/registry/man/regdiff.1 + ################################################ # Start BINARY regpatch [BINARY::regpatch] @@ -64,10 +65,11 @@ OBJ_FILES = tools/regpatch.o PRIVATE_DEPENDENCIES = \ LIBSAMBA-CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS \ registry_common -MANPAGE = man/regpatch.1 # End BINARY regpatch ################################################ +MANPAGES += lib/registry/man/regpatch.1 + ################################################ # Start BINARY regshell [BINARY::regshell] @@ -76,10 +78,11 @@ OBJ_FILES = tools/regshell.o PRIVATE_DEPENDENCIES = \ LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \ SMBREADLINE registry_common -MANPAGE = man/regshell.1 # End BINARY regshell ################################################ +MANPAGES += lib/registry/man/regshell.1 + ################################################ # Start BINARY regtree [BINARY::regtree] @@ -88,10 +91,11 @@ OBJ_FILES = tools/regtree.o PRIVATE_DEPENDENCIES = \ LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \ registry_common -MANPAGE = man/regtree.1 # End BINARY regtree ################################################ +MANPAGES += lib/registry/man/regtree.1 + [SUBSYSTEM::torture_registry] PRIVATE_DEPENDENCIES = registry PRIVATE_PROTO_HEADER = tests/proto.h -- cgit From c5d77a1c2414d930ccbedbe05e124df69242a144 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 26 Feb 2008 17:17:52 +0100 Subject: Move public header accumulation out of the perl code. (This used to be commit 89f7c74924965071981bbe7e05ff69847b0a3a03) --- source4/lib/registry/config.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index af5b1bc301..b2d7ce202e 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -36,10 +36,11 @@ OBJ_FILES = \ PUBLIC_DEPENDENCIES = \ LIBSAMBA-UTIL CHARSET TDR_REGF LIBLDB \ RPC_NDR_WINREG LDB_WRAP -PUBLIC_HEADERS = registry.h hive.h patchfile.h # End MODULE registry_ldb ################################################ +PUBLIC_HEADERS += $(addprefix lib/registry/, registry.h hive.h patchfile.h) + [SUBSYSTEM::registry_common] PUBLIC_DEPENDENCIES = registry OBJ_FILES = tools/common.o -- cgit From 7dac0598ec6edb63f15a7cce7c231f56f9ab7f7d Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Sat, 16 Feb 2008 15:08:28 -0600 Subject: registry: Implement recursive deletes for ldb-backed registry. When deleting a registry key that contains subkeys or values, Windows performs a recursive deletion that removes any subkeys or values. This update makes deletes for an ldb-backed registry consistent with Windows. Under ldb, the deletion is done using an explicit transaction. If an error occurs during the deletion the entire transaction is cancelled, leaving the registry as it was before the deletions started. (This used to be commit ca796c8fb10598674a5eef31d15863e79bcf3db8) --- source4/lib/registry/ldb.c | 143 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 116 insertions(+), 27 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 0c8a55396e..31b78d8246 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -440,33 +440,6 @@ static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent, return WERR_OK; } -static WERROR ldb_del_key(const struct hive_key *key, const char *name) -{ - int ret; - struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data); - struct ldb_dn *ldap_path; - TALLOC_CTX *mem_ctx = talloc_init("ldb_del_key"); - - ldap_path = reg_path_to_ldb(mem_ctx, key, name, NULL); - - ret = ldb_delete(parentkd->ldb, ldap_path); - - talloc_free(mem_ctx); - - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - return WERR_BADFILE; - } else if (ret != LDB_SUCCESS) { - DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(parentkd->ldb))); - return WERR_FOOBAR; - } - - /* reset cache */ - talloc_free(parentkd->subkeys); - parentkd->subkeys = NULL; - - return WERR_OK; -} - static WERROR ldb_del_value (struct hive_key *key, const char *child) { int ret; @@ -499,6 +472,122 @@ static WERROR ldb_del_value (struct hive_key *key, const char *child) return WERR_OK; } +static WERROR ldb_del_key(const struct hive_key *key, const char *name) +{ + int i, ret; + struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data); + struct ldb_dn *ldap_path; + TALLOC_CTX *mem_ctx = talloc_init("ldb_del_key"); + struct ldb_context *c = parentkd->ldb; + struct ldb_result *res_keys; + struct ldb_result *res_vals; + WERROR werr; + struct hive_key *hk; + + /* Verify key exists by opening it */ + werr = ldb_open_key(mem_ctx, key, name, &hk); + if (!W_ERROR_IS_OK(werr)) { + talloc_free(mem_ctx); + return werr; + } + + ldap_path = reg_path_to_ldb(mem_ctx, key, name, NULL); + if (!ldap_path) { + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + + /* Search for subkeys */ + ret = ldb_search(c, ldap_path, LDB_SCOPE_ONELEVEL, + "(key=*)", NULL, &res_keys); + + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Error getting subkeys for '%s': %s\n", + ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + + /* Search for values */ + ret = ldb_search(c, ldap_path, LDB_SCOPE_ONELEVEL, + "(value=*)", NULL, &res_vals); + + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Error getting values for '%s': %s\n", + ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + + /* Start an explicit transaction */ + ret = ldb_transaction_start(c); + + if (ret != LDB_SUCCESS) { + DEBUG(0, ("ldb_transaction_start: %s\n", ldb_errstring(c))); + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + + if (res_keys->count || res_vals->count) + { + /* Delete any subkeys */ + for (i = 0; i < res_keys->count; i++) + { + werr = ldb_del_key(hk, ldb_msg_find_attr_as_string( + res_keys->msgs[i], + "key", NULL)); + if (!W_ERROR_IS_OK(werr)) { + ret = ldb_transaction_cancel(c); + talloc_free(mem_ctx); + return werr; + } + } + + /* Delete any values */ + for (i = 0; i < res_vals->count; i++) + { + werr = ldb_del_value(hk, ldb_msg_find_attr_as_string( + res_vals->msgs[i], + "value", NULL)); + if (!W_ERROR_IS_OK(werr)) { + ret = ldb_transaction_cancel(c); + talloc_free(mem_ctx); + return werr; + } + } + } + + /* Delete the key itself */ + ret = ldb_delete(c, ldap_path); + + if (ret != LDB_SUCCESS) + { + DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(c))); + ret = ldb_transaction_cancel(c); + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + + /* Commit the transaction */ + ret = ldb_transaction_commit(c); + + if (ret != LDB_SUCCESS) + { + DEBUG(0, ("ldb_transaction_commit: %s\n", ldb_errstring(c))); + ret = ldb_transaction_cancel(c); + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + + talloc_free(mem_ctx); + + /* reset cache */ + talloc_free(parentkd->subkeys); + parentkd->subkeys = NULL; + + return WERR_OK; +} + static WERROR ldb_set_value(struct hive_key *parent, const char *name, uint32_t type, const DATA_BLOB data) -- cgit From 2bbd319cafe64935682799240b9c0aa9ff4d7e7a Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Sat, 16 Feb 2008 15:15:50 -0600 Subject: registry: Implement recursive deletes for dir-backed registry. When deleting a registry key that contains subkeys or values, Windows performs a recursive deletion that removes any subkeys or values. This update makes deletes for an dir-backed registry consistent with Windows. The dir-backed registry relies on the underlying filesystem, which does not generally have transactional integrity when performing multiple operations. Therefore, if an error occurs during the recursive deletion, the dir-backed registry may be left in an inconsistent state. (This used to be commit 6b5fbf7e4e38342bcd80e63f46cd295f89ab1ee9) --- source4/lib/registry/dir.c | 60 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 6 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/dir.c b/source4/lib/registry/dir.c index 27cae8c490..dc3717e886 100644 --- a/source4/lib/registry/dir.c +++ b/source4/lib/registry/dir.c @@ -55,18 +55,66 @@ static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx, return WERR_GENERAL_FAILURE; } +static WERROR reg_dir_delete_recursive(const char *name) +{ + DIR *d; + struct dirent *e; + WERROR werr; + + d = opendir(name); + if (d == NULL) { + DEBUG(3,("Unable to open '%s': %s\n", name, + strerror(errno))); + return WERR_BADFILE; + } + + while((e = readdir(d))) { + char *path; + struct stat stbuf; + + if (ISDOT(e->d_name) || ISDOTDOT(e->d_name)) + continue; + + path = talloc_asprintf(name, "%s/%s", name, e->d_name); + if (!path) + return WERR_NOMEM; + + stat(path, &stbuf); + + if (!S_ISDIR(stbuf.st_mode)) { + if (unlink(path) < 0) { + talloc_free(path); + closedir(d); + return WERR_GENERAL_FAILURE; + } + } else { + werr = reg_dir_delete_recursive(path); + if (!W_ERROR_IS_OK(werr)) { + talloc_free(path); + closedir(d); + return werr; + } + } + + talloc_free(path); + } + closedir(d); + + if (rmdir(name) == 0) + return WERR_OK; + else if (errno == ENOENT) + return WERR_BADFILE; + else + return WERR_GENERAL_FAILURE; +} + static WERROR reg_dir_del_key(const struct hive_key *k, const char *name) { struct dir_key *dk = talloc_get_type(k, struct dir_key); char *child = talloc_asprintf(NULL, "%s/%s", dk->path, name); WERROR ret; - if (rmdir(child) == 0) - ret = WERR_OK; - else if (errno == ENOENT) - ret = WERR_BADFILE; - else - ret = WERR_GENERAL_FAILURE; + ret = reg_dir_delete_recursive(child); talloc_free(child); -- cgit From 79eea32976d2991319c9d0ad32a150f34b029f99 Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Sat, 16 Feb 2008 15:19:00 -0600 Subject: registry: Implement recursive deletes for regf-backed registry. When deleting a registry key that contains subkeys or values, Windows performs a recursive deletion that removes any subkeys or values. This update makes deletes for an regf-backed registry consistent with Windows. The regf-backed registry does not have transactional integrity when performing multiple operations. Therefore, if an error occurs during the recursive deletion, the regf-backed registry may be left in an inconsistent state. (This used to be commit b0321bad290d1a9399b4aba140a622e3af6d7575) --- source4/lib/registry/regf.c | 53 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 15b60745f0..6a35799a7e 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -1618,10 +1618,55 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name) return WERR_BADFILE; } - if (key->nk->subkeys_offset != -1 || - key->nk->values_offset != -1) { - DEBUG(0, ("Key '%s' is not empty.\n", name)); - return WERR_FILE_EXISTS; + if (key->nk->subkeys_offset != -1) { + char *sk_name; + struct hive_key *sk = (struct hive_key *)key; + int i = key->nk->num_subkeys; + while (i--) { + /* Get subkey information. */ + error = regf_get_subkey_by_index(parent_nk, sk, 0, + (const char **)&sk_name, + NULL, NULL); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Can't retrieve subkey by index.\n")); + return error; + } + + /* Delete subkey. */ + error = regf_del_key(sk, sk_name); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Can't delete key '%s'.\n", sk_name)); + return error; + } + + talloc_free(sk_name); + } + } + + if (key->nk->values_offset != -1) { + char *val_name; + struct hive_key *sk = (struct hive_key *)key; + DATA_BLOB data; + int i = key->nk->num_values; + while (i--) { + /* Get value information. */ + error = regf_get_value(parent_nk, sk, 0, + (const char **)&val_name, + NULL, &data); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Can't retrieve value by index.\n")); + return error; + } + + /* Delete value. */ + error = regf_del_value(sk, val_name); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Can't delete value '%s'.\n", val_name)); + return error; + } + + talloc_free(val_name); + } } /* Delete it from the subkey list. */ -- cgit From a13395c8731db614e543e60d3da67873c3164ea2 Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Sat, 16 Feb 2008 15:21:26 -0600 Subject: registry: Add an explicit test for recursive deletion. (This used to be commit 5e905804993df4c2ac28090d056e6db6bb63ac44) --- source4/lib/registry/tests/hive.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index 4d27e83a74..915782694f 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -110,6 +110,38 @@ static bool test_add_subkey(struct torture_context *tctx, return true; } +static bool test_del_recursive(struct torture_context *tctx, + const void *test_data) +{ + WERROR error; + struct hive_key *subkey; + struct hive_key *subkey2; + const struct hive_key *root = (const struct hive_key *)test_data; + TALLOC_CTX *mem_ctx = tctx; + uint32_t data = 42; + + /* Create a new key under the root */ + error = hive_key_add_name(mem_ctx, root, "Parent Key", NULL, + NULL, &subkey); + torture_assert_werr_ok(tctx, error, "hive_key_add_name"); + + /* Create a new key under "Parent Key" */ + error = hive_key_add_name(mem_ctx, subkey, "Child Key", NULL, + NULL, &subkey2); + torture_assert_werr_ok(tctx, error, "hive_key_add_name"); + + /* Create a new value under "Child Key" */ + error = hive_key_set_value(subkey2, "Answer Recursive", REG_DWORD, + data_blob_talloc(mem_ctx, &data, sizeof(data))); + torture_assert_werr_ok(tctx, error, "hive_key_set_value"); + + /* Deleting "Parent Key" will also delete "Child Key" and the value. */ + error = hive_key_del(root, "Parent Key"); + torture_assert_werr_ok(tctx, error, "hive_key_del"); + + return true; +} + static bool test_flush_key(struct torture_context *tctx, void *test_data) { struct hive_key *root = (struct hive_key *)test_data; @@ -272,6 +304,11 @@ static void tcase_add_tests(struct torture_tcase *tcase) test_add_subkey); torture_tcase_add_simple_test(tcase, "flush_key", test_flush_key); + /* test_del_recursive() test must run before test_keyinfo_root(). + test_keyinfo_root() checks the number of subkeys, which verifies + the recursive delete worked properly. */ + torture_tcase_add_simple_test_const(tcase, "del_recursive", + test_del_recursive); torture_tcase_add_simple_test_const(tcase, "get_info", test_keyinfo_root); torture_tcase_add_simple_test(tcase, "get_info_nums", -- cgit From d8d9a6ef040b6c3e7946e6ae2cba2b28234c8baf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 26 Feb 2008 15:11:47 +0100 Subject: Move manpage management out of the perl build system. (This used to be commit 1dd6bea507f1f5e26cccf89148280721260a4673) --- source4/lib/registry/config.mk | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 7a9c8fcff1..af5b1bc301 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -52,10 +52,11 @@ INSTALLDIR = BINDIR OBJ_FILES = tools/regdiff.o PRIVATE_DEPENDENCIES = \ LIBSAMBA-CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS -MANPAGE = man/regdiff.1 # End BINARY regdiff ################################################ +MANPAGES += lib/registry/man/regdiff.1 + ################################################ # Start BINARY regpatch [BINARY::regpatch] @@ -64,10 +65,11 @@ OBJ_FILES = tools/regpatch.o PRIVATE_DEPENDENCIES = \ LIBSAMBA-CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS \ registry_common -MANPAGE = man/regpatch.1 # End BINARY regpatch ################################################ +MANPAGES += lib/registry/man/regpatch.1 + ################################################ # Start BINARY regshell [BINARY::regshell] @@ -76,10 +78,11 @@ OBJ_FILES = tools/regshell.o PRIVATE_DEPENDENCIES = \ LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \ SMBREADLINE registry_common -MANPAGE = man/regshell.1 # End BINARY regshell ################################################ +MANPAGES += lib/registry/man/regshell.1 + ################################################ # Start BINARY regtree [BINARY::regtree] @@ -88,10 +91,11 @@ OBJ_FILES = tools/regtree.o PRIVATE_DEPENDENCIES = \ LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \ registry_common -MANPAGE = man/regtree.1 # End BINARY regtree ################################################ +MANPAGES += lib/registry/man/regtree.1 + [SUBSYSTEM::torture_registry] PRIVATE_DEPENDENCIES = registry PRIVATE_PROTO_HEADER = tests/proto.h -- cgit From 1ada7108408f567f61cfbf2b625730ba898452db Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 29 Feb 2008 14:23:38 +0100 Subject: Move public header accumulation out of the perl code. Never install generated prototype files. It's easier to break the API when using them and they're not easily readable for 3rd party users. Conflicts: source/auth/config.mk source/auth/credentials/config.mk source/auth/gensec/config.mk source/build/smb_build/config_mk.pm source/build/smb_build/main.pl source/build/smb_build/makefile.pm source/dsdb/config.mk source/lib/charset/config.mk source/lib/tdr/config.mk source/lib/util/config.mk source/libcli/config.mk source/libcli/ldap/config.mk source/librpc/config.mk source/param/config.mk source/rpc_server/config.mk source/torture/config.mk (This used to be commit 6c659689ed4081f1d7a6253c538c7f01784197ba) --- source4/lib/registry/config.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index af5b1bc301..b2d7ce202e 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -36,10 +36,11 @@ OBJ_FILES = \ PUBLIC_DEPENDENCIES = \ LIBSAMBA-UTIL CHARSET TDR_REGF LIBLDB \ RPC_NDR_WINREG LDB_WRAP -PUBLIC_HEADERS = registry.h hive.h patchfile.h # End MODULE registry_ldb ################################################ +PUBLIC_HEADERS += $(addprefix lib/registry/, registry.h hive.h patchfile.h) + [SUBSYSTEM::registry_common] PUBLIC_DEPENDENCIES = registry OBJ_FILES = tools/common.o -- cgit From b29d47edcf2767d7f9e9f63332079c6e8e89946c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Mar 2008 18:25:28 +0100 Subject: Move object file lists to the Makefile. (This used to be commit a7e6d2a1832db388fdafa1279f84c9a8bbfc87d6) --- source4/lib/registry/config.mk | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index b2d7ce202e..728d64d552 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -1,6 +1,7 @@ [SUBSYSTEM::TDR_REGF] PUBLIC_DEPENDENCIES = TDR -OBJ_FILES = tdr_regf.o + +TDR_REGF_OBJ_FILES = lib/registry/tdr_regf.o # Special support for external builddirs lib/registry/regf.c: lib/registry/tdr_regf.c @@ -20,91 +21,84 @@ clean:: VERSION = 0.0.1 PC_FILE = registry.pc SO_VERSION = 0 -OBJ_FILES = \ - interface.o \ - util.o \ - samba.o \ - patchfile_dotreg.o \ - patchfile_preg.o \ - patchfile.o \ - regf.o \ - hive.o \ - local.o \ - ldb.o \ - dir.o \ - rpc.o PUBLIC_DEPENDENCIES = \ LIBSAMBA-UTIL CHARSET TDR_REGF LIBLDB \ RPC_NDR_WINREG LDB_WRAP # End MODULE registry_ldb ################################################ +registry_OBJ_FILES = $(addprefix lib/registry/, interface.o util.o samba.o \ + patchfile_dotreg.o patchfile_preg.o patchfile.o regf.o \ + hive.o local.o ldb.o dir.o rpc.o) + PUBLIC_HEADERS += $(addprefix lib/registry/, registry.h hive.h patchfile.h) [SUBSYSTEM::registry_common] PUBLIC_DEPENDENCIES = registry -OBJ_FILES = tools/common.o PRIVATE_PROTO_HEADER = tools/common.h +registry_common_OBJ_FILES = lib/registry/tools/common.o + ################################################ # Start BINARY regdiff [BINARY::regdiff] INSTALLDIR = BINDIR -OBJ_FILES = tools/regdiff.o PRIVATE_DEPENDENCIES = \ LIBSAMBA-CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS # End BINARY regdiff ################################################ +regdiff_OBJ_FILES = lib/registry/tools/regdiff.o + MANPAGES += lib/registry/man/regdiff.1 ################################################ # Start BINARY regpatch [BINARY::regpatch] INSTALLDIR = BINDIR -OBJ_FILES = tools/regpatch.o PRIVATE_DEPENDENCIES = \ LIBSAMBA-CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS \ registry_common # End BINARY regpatch ################################################ +regpatch_OBJ_FILES = lib/registry/tools/regpatch.o + MANPAGES += lib/registry/man/regpatch.1 ################################################ # Start BINARY regshell [BINARY::regshell] INSTALLDIR = BINDIR -OBJ_FILES = tools/regshell.o PRIVATE_DEPENDENCIES = \ LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \ SMBREADLINE registry_common # End BINARY regshell ################################################ +regshell_OBJ_FILES = lib/registry/tools/regshell.o + MANPAGES += lib/registry/man/regshell.1 ################################################ # Start BINARY regtree [BINARY::regtree] INSTALLDIR = BINDIR -OBJ_FILES = tools/regtree.o PRIVATE_DEPENDENCIES = \ LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \ registry_common # End BINARY regtree ################################################ +regtree_OBJ_FILES = lib/registry/tools/regtree.o + MANPAGES += lib/registry/man/regtree.1 [SUBSYSTEM::torture_registry] PRIVATE_DEPENDENCIES = registry PRIVATE_PROTO_HEADER = tests/proto.h -OBJ_FILES = \ - tests/generic.o \ - tests/hive.o \ - tests/diff.o \ - tests/registry.o + +torture_registry_OBJ_FILES = $(addprefix lib/registry/tests/, generic.o hive.o diff.o registry.o) [PYTHON::swig_registry] PUBLIC_DEPENDENCIES = registry -- cgit From 2d1c06c5781600a0efcf9becd3e2773dbbbf2cc7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 4 Mar 2008 00:43:24 +0100 Subject: Fix includes. (This used to be commit 99e61dade2bd9ae2a5dfe17f766528012c09e46c) --- source4/lib/registry/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 728d64d552..544201ad53 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -104,3 +104,4 @@ torture_registry_OBJ_FILES = $(addprefix lib/registry/tests/, generic.o hive.o d PUBLIC_DEPENDENCIES = registry SWIG_FILE = registry.i +swig_registry_OBJ_FILES = lib/registry/registry_wrap.o -- cgit From 2bf39edc9d0abf3306bd25b9c40d88aceb029be7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Mar 2008 15:28:12 +0100 Subject: Push SOVERSION and VERSION out of perl code. (This used to be commit 0ba8ac6a14c62ff9edfe9f0bf43b8a7406b85291) --- source4/lib/registry/config.mk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 544201ad53..72882bca93 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -18,15 +18,16 @@ clean:: ################################################ # Start SUBSYSTEM registry [LIBRARY::registry] -VERSION = 0.0.1 PC_FILE = registry.pc -SO_VERSION = 0 PUBLIC_DEPENDENCIES = \ LIBSAMBA-UTIL CHARSET TDR_REGF LIBLDB \ RPC_NDR_WINREG LDB_WRAP # End MODULE registry_ldb ################################################ +registry_VERSION = 0.0.1 +registry_SOVERSION = 0 + registry_OBJ_FILES = $(addprefix lib/registry/, interface.o util.o samba.o \ patchfile_dotreg.o patchfile_preg.o patchfile.o regf.o \ hive.o local.o ldb.o dir.o rpc.o) -- cgit From e3f6a9a0d4232d7ff41d2085641f35a0bf7b229f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 9 Mar 2008 02:53:54 +0100 Subject: Move PC_FILE out of the perl code. (This used to be commit ca8d4260ada9f74ebc406714ca70d20be09b194b) --- source4/lib/registry/config.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 72882bca93..16e9c62c57 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -18,13 +18,14 @@ clean:: ################################################ # Start SUBSYSTEM registry [LIBRARY::registry] -PC_FILE = registry.pc PUBLIC_DEPENDENCIES = \ LIBSAMBA-UTIL CHARSET TDR_REGF LIBLDB \ RPC_NDR_WINREG LDB_WRAP # End MODULE registry_ldb ################################################ +PC_FILES += lib/registry/registry.pc + registry_VERSION = 0.0.1 registry_SOVERSION = 0 -- cgit From 2fd59920381ea81734565637adcec96e5668ef86 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Mar 2008 14:33:18 +0100 Subject: swig: regenerate _wrap.c files metze (This used to be commit 08b41e10699c7bb8058ab0ab61f17a1bbfcc1ce4) --- source4/lib/registry/registry_wrap.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index c5741b7e2c..51c255e9f7 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -2950,7 +2950,7 @@ SWIGINTERN PyObject *_wrap_Registry(PyObject *SWIGUNUSEDPARM(self), PyObject *ar } result = reg_open_local(arg1,arg2,arg3,arg4); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3001,7 +3001,7 @@ SWIGINTERN PyObject *_wrap_reg_get_predefined_key_by_name(PyObject *SWIGUNUSEDPA arg3 = (struct registry_key **)(argp3); result = reg_get_predefined_key_by_name(arg1,(char const *)arg2,arg3); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3044,7 +3044,7 @@ SWIGINTERN PyObject *_wrap_reg_key_del_abs(PyObject *SWIGUNUSEDPARM(self), PyObj arg2 = (char *)(buf2); result = reg_key_del_abs(arg1,(char const *)arg2); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3095,7 +3095,7 @@ SWIGINTERN PyObject *_wrap_reg_get_predefined_key(PyObject *SWIGUNUSEDPARM(self) arg3 = (struct registry_key **)(argp3); result = reg_get_predefined_key(arg1,arg2,arg3); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3136,7 +3136,7 @@ SWIGINTERN PyObject *_wrap_reg_diff_apply(PyObject *SWIGUNUSEDPARM(self), PyObje arg2 = (char *)(buf2); result = reg_diff_apply(arg1,(char const *)arg2); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3194,7 +3194,7 @@ SWIGINTERN PyObject *_wrap_reg_generate_diff(PyObject *SWIGUNUSEDPARM(self), PyO } result = reg_generate_diff(arg1,arg2,(struct reg_diff_callbacks const *)arg3,arg4); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3260,7 +3260,7 @@ SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_0(PyObject *SWIGUNUSEDPARM(self) } result = reg_mount_hive(arg1,arg2,arg3,(char const **)arg4); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3373,7 +3373,7 @@ SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_1(PyObject *SWIGUNUSEDPARM(self) arg3 = (char *)(buf3); result = reg_mount_hive__SWIG_1(arg1,arg2,(char const *)arg3); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3524,7 +3524,7 @@ SWIGINTERN PyObject *_wrap_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *ar } result = reg_open_hive(arg1,(char const *)arg2,arg3,arg4,arg5,arg6); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3601,7 +3601,7 @@ SWIGINTERN PyObject *_wrap_open_ldb(PyObject *SWIGUNUSEDPARM(self), PyObject *ar } result = reg_open_ldb_file(arg1,(char const *)arg2,arg3,arg4,arg5,arg6); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3642,7 +3642,7 @@ SWIGINTERN PyObject *_wrap_create_dir(PyObject *SWIGUNUSEDPARM(self), PyObject * arg2 = (char *)(buf2); result = reg_create_directory(arg1,(char const *)arg2,arg3); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3683,7 +3683,7 @@ SWIGINTERN PyObject *_wrap_open_dir(PyObject *SWIGUNUSEDPARM(self), PyObject *ar arg2 = (char *)(buf2); result = reg_open_directory(arg1,(char const *)arg2,arg3); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { @@ -3750,7 +3750,7 @@ SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject * } result = reg_open_samba(arg1,arg2,arg3,arg4,arg5); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { -- cgit From 8f8c56bfbcbfe8f80afb09eb1d481a108b252bee Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Fri, 28 Mar 2008 01:08:49 -0500 Subject: Convert some more files to GPLv3. (This used to be commit ebe5e8399422eb7e2ff4deb546338823e2718907) --- source4/lib/registry/hive.c | 2 +- source4/lib/registry/hive.h | 2 +- source4/lib/registry/local.c | 2 +- source4/lib/registry/patchfile.h | 2 +- source4/lib/registry/patchfile_dotreg.c | 2 +- source4/lib/registry/patchfile_preg.c | 2 +- source4/lib/registry/tests/hive.c | 2 +- source4/lib/registry/tests/registry.c | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/hive.c b/source4/lib/registry/hive.c index ad6a6421ab..fc2d0fe869 100644 --- a/source4/lib/registry/hive.c +++ b/source4/lib/registry/hive.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source4/lib/registry/hive.h b/source4/lib/registry/hive.h index 87f335663d..2410885718 100644 --- a/source4/lib/registry/hive.h +++ b/source4/lib/registry/hive.h @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index 3e463100c9..5bf2d86588 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source4/lib/registry/patchfile.h b/source4/lib/registry/patchfile.h index 9289390685..d586aa4c31 100644 --- a/source4/lib/registry/patchfile.h +++ b/source4/lib/registry/patchfile.h @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source4/lib/registry/patchfile_dotreg.c b/source4/lib/registry/patchfile_dotreg.c index 6de642ecb8..5150c90291 100644 --- a/source4/lib/registry/patchfile_dotreg.c +++ b/source4/lib/registry/patchfile_dotreg.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c index 0d39e67450..8f02a0b5e3 100644 --- a/source4/lib/registry/patchfile_preg.c +++ b/source4/lib/registry/patchfile_preg.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index 1e56f125c5..70b0241b04 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 7d14b3a412..e5e34c11e0 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From f41b9a9dde0dcad17e3a137537548f9bd9ab3901 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 1 Apr 2008 15:08:30 +0200 Subject: Rename libsamba-config to libsamba-hostconfig. (This used to be commit c46b7e90e347da76156ddcae4866adb88e9fec21) --- source4/lib/registry/config.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index b2d7ce202e..70ffce020a 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -52,7 +52,7 @@ PRIVATE_PROTO_HEADER = tools/common.h INSTALLDIR = BINDIR OBJ_FILES = tools/regdiff.o PRIVATE_DEPENDENCIES = \ - LIBSAMBA-CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS + LIBSAMBA-HOSTCONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS # End BINARY regdiff ################################################ @@ -64,7 +64,7 @@ MANPAGES += lib/registry/man/regdiff.1 INSTALLDIR = BINDIR OBJ_FILES = tools/regpatch.o PRIVATE_DEPENDENCIES = \ - LIBSAMBA-CONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS \ + LIBSAMBA-HOSTCONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS \ registry_common # End BINARY regpatch ################################################ @@ -77,7 +77,7 @@ MANPAGES += lib/registry/man/regpatch.1 INSTALLDIR = BINDIR OBJ_FILES = tools/regshell.o PRIVATE_DEPENDENCIES = \ - LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \ + LIBSAMBA-HOSTCONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \ SMBREADLINE registry_common # End BINARY regshell ################################################ @@ -90,7 +90,7 @@ MANPAGES += lib/registry/man/regshell.1 INSTALLDIR = BINDIR OBJ_FILES = tools/regtree.o PRIVATE_DEPENDENCIES = \ - LIBSAMBA-CONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \ + LIBSAMBA-HOSTCONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \ registry_common # End BINARY regtree ################################################ -- cgit From afe3e8172ddaa5e4aa811faceecda4f943d6e2ef Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2008 04:53:27 +0200 Subject: Install public header files again and include required prototypes. (This used to be commit 47ffbbf67435904754469544390b67d34c958343) --- source4/lib/registry/tests/generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/generic.c b/source4/lib/registry/tests/generic.c index 145e599504..6eae26bc46 100644 --- a/source4/lib/registry/tests/generic.c +++ b/source4/lib/registry/tests/generic.c @@ -112,7 +112,7 @@ static bool test_reg_val_description_nullname(struct torture_context *ctx) return true; } -_PUBLIC_ struct torture_suite *torture_registry(TALLOC_CTX *mem_ctx) +struct torture_suite *torture_registry(TALLOC_CTX *mem_ctx) { struct torture_suite *suite = torture_suite_create(mem_ctx, "REGISTRY"); torture_suite_add_simple_test(suite, "str_regtype", -- cgit From 5be50a222facee943edae868e39ff11f7dd68965 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2008 13:58:05 +0200 Subject: Merge patchfile.h into registry.h (This used to be commit 7b434df67aefc667993f0ebd955af9c1c258f153) --- source4/lib/registry/config.mk | 2 +- source4/lib/registry/patchfile.c | 1 - source4/lib/registry/patchfile.h | 55 --------------------------------- source4/lib/registry/patchfile_dotreg.c | 1 - source4/lib/registry/patchfile_preg.c | 1 - source4/lib/registry/registry.h | 31 +++++++++++++++++-- 6 files changed, 30 insertions(+), 61 deletions(-) delete mode 100644 source4/lib/registry/patchfile.h (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 70ffce020a..1deac1dd46 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -39,7 +39,7 @@ PUBLIC_DEPENDENCIES = \ # End MODULE registry_ldb ################################################ -PUBLIC_HEADERS += $(addprefix lib/registry/, registry.h hive.h patchfile.h) +PUBLIC_HEADERS += $(addprefix lib/registry/, registry.h hive.h) [SUBSYSTEM::registry_common] PUBLIC_DEPENDENCIES = registry diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index 687fd4b91b..15e3a158f2 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -20,7 +20,6 @@ */ #include "includes.h" -#include "lib/registry/patchfile.h" #include "lib/registry/registry.h" #include "system/filesys.h" #include "param/param.h" diff --git a/source4/lib/registry/patchfile.h b/source4/lib/registry/patchfile.h deleted file mode 100644 index d586aa4c31..0000000000 --- a/source4/lib/registry/patchfile.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Patchfile interface - Copyright (C) Jelmer Vernooij 2006 - Copyright (C) Wilco Baan Hofman 2006 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef _PATCHFILE_H -#define _PATCHFILE_H - -#include "lib/registry/registry.h" - -struct reg_diff_callbacks { - WERROR (*add_key) (void *callback_data, const char *key_name); - WERROR (*set_value) (void *callback_data, const char *key_name, - const char *value_name, uint32_t value_type, - DATA_BLOB value); - WERROR (*del_value) (void *callback_data, const char *key_name, - const char *value_name); - WERROR (*del_key) (void *callback_data, const char *key_name); - WERROR (*del_all_values) (void *callback_data, const char *key_name); - WERROR (*done) (void *callback_data); -}; - -WERROR reg_diff_apply(struct registry_context *ctx, const char *filename); - -WERROR reg_generate_diff(struct registry_context *ctx1, - struct registry_context *ctx2, - const struct reg_diff_callbacks *callbacks, - void *callback_data); -WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, - struct smb_iconv_convenience *iconv_convenience, - struct reg_diff_callbacks **callbacks, - void **callback_data); -WERROR reg_generate_diff_key(struct registry_key *oldkey, - struct registry_key *newkey, - const char *path, - const struct reg_diff_callbacks *callbacks, - void *callback_data); - -#endif /* _PATCHFILE_H */ diff --git a/source4/lib/registry/patchfile_dotreg.c b/source4/lib/registry/patchfile_dotreg.c index 5150c90291..59f4044713 100644 --- a/source4/lib/registry/patchfile_dotreg.c +++ b/source4/lib/registry/patchfile_dotreg.c @@ -23,7 +23,6 @@ /* FIXME Newer .REG files, created by Windows XP and above use unicode UTF-16 */ #include "includes.h" -#include "lib/registry/patchfile.h" #include "lib/registry/registry.h" #include "system/filesys.h" #include "param/param.h" diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c index 8f02a0b5e3..0fa367bfcb 100644 --- a/source4/lib/registry/patchfile_preg.c +++ b/source4/lib/registry/patchfile_preg.c @@ -21,7 +21,6 @@ #include "includes.h" #include "lib/registry/registry.h" -#include "lib/registry/patchfile.h" #include "system/filesys.h" #include "param/param.h" diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 5e0b971a1d..b76f2c4bcc 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -66,8 +66,6 @@ struct registry_key struct registry_context *context; }; -#include "lib/registry/patchfile.h" - struct registry_value { const char *name; @@ -285,5 +283,34 @@ WERROR reg_get_security(TALLOC_CTX *mem_ctx, WERROR reg_set_security(struct registry_key *key, struct security_descriptor *security); +struct reg_diff_callbacks { + WERROR (*add_key) (void *callback_data, const char *key_name); + WERROR (*set_value) (void *callback_data, const char *key_name, + const char *value_name, uint32_t value_type, + DATA_BLOB value); + WERROR (*del_value) (void *callback_data, const char *key_name, + const char *value_name); + WERROR (*del_key) (void *callback_data, const char *key_name); + WERROR (*del_all_values) (void *callback_data, const char *key_name); + WERROR (*done) (void *callback_data); +}; + +WERROR reg_diff_apply(struct registry_context *ctx, const char *filename); + +WERROR reg_generate_diff(struct registry_context *ctx1, + struct registry_context *ctx2, + const struct reg_diff_callbacks *callbacks, + void *callback_data); +WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, + struct smb_iconv_convenience *iconv_convenience, + struct reg_diff_callbacks **callbacks, + void **callback_data); +WERROR reg_generate_diff_key(struct registry_key *oldkey, + struct registry_key *newkey, + const char *path, + const struct reg_diff_callbacks *callbacks, + void *callback_data); + + #endif /* _REGISTRY_H */ -- cgit From ec7394e7d2f589905044cff3cb1899f0815991d6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2008 13:59:48 +0200 Subject: Merge hive.h into registry.h (This used to be commit 3ca14fdf74d2510049bbdbbd2a5be341412cda1b) --- source4/lib/registry/dir.c | 2 +- source4/lib/registry/hive.c | 2 +- source4/lib/registry/hive.h | 209 ----------------------------------- source4/lib/registry/regf.c | 2 +- source4/lib/registry/registry.h | 183 +++++++++++++++++++++++++++++- source4/lib/registry/registry.i | 1 - source4/lib/registry/registry_wrap.c | 2 +- 7 files changed, 186 insertions(+), 215 deletions(-) delete mode 100644 source4/lib/registry/hive.h (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/dir.c b/source4/lib/registry/dir.c index dc3717e886..449ee0f6ee 100644 --- a/source4/lib/registry/dir.c +++ b/source4/lib/registry/dir.c @@ -18,7 +18,7 @@ */ #include "includes.h" -#include "hive.h" +#include "registry.h" #include "system/dir.h" #include "system/filesys.h" diff --git a/source4/lib/registry/hive.c b/source4/lib/registry/hive.c index fc2d0fe869..2a9b1a59ce 100644 --- a/source4/lib/registry/hive.c +++ b/source4/lib/registry/hive.c @@ -20,7 +20,7 @@ */ #include "includes.h" -#include "hive.h" +#include "registry.h" #include "system/filesys.h" #include "param/param.h" diff --git a/source4/lib/registry/hive.h b/source4/lib/registry/hive.h deleted file mode 100644 index 2410885718..0000000000 --- a/source4/lib/registry/hive.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Registry hive interface - Copyright (C) Jelmer Vernooij 2003-2007. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __REGISTRY_HIVE_H__ -#define __REGISTRY_HIVE_H__ - -#include -#include "libcli/util/werror.h" -#include "librpc/gen_ndr/security.h" -#include "libcli/util/ntstatus.h" - -/** - * This file contains the hive API. This API is generally used for - * reading a specific file that contains just one hive. - * - * Good examples are .DAT (NTUSER.DAT) files. - * - * This API does not have any notification support (that - * should be provided by the registry implementation), nor - * does it understand what predefined keys are. - */ - -struct hive_key { - const struct hive_operations *ops; -}; - -struct hive_operations { - const char *name; - - /** - * Open a specific subkey - */ - WERROR (*enum_key) (TALLOC_CTX *mem_ctx, - const struct hive_key *key, uint32_t idx, - const char **name, - const char **classname, - NTTIME *last_mod_time); - - /** - * Open a subkey by name - */ - WERROR (*get_key_by_name) (TALLOC_CTX *mem_ctx, - const struct hive_key *key, const char *name, - struct hive_key **subkey); - - /** - * Add a new key. - */ - WERROR (*add_key) (TALLOC_CTX *ctx, - const struct hive_key *parent_key, const char *name, - const char *classname, - struct security_descriptor *desc, - struct hive_key **key); - /** - * Remove an existing key. - */ - WERROR (*del_key) (const struct hive_key *key, const char *name); - - /** - * Force write of a key to disk. - */ - WERROR (*flush_key) (struct hive_key *key); - - /** - * Retrieve a registry value with a specific index. - */ - WERROR (*enum_value) (TALLOC_CTX *mem_ctx, - struct hive_key *key, int idx, - const char **name, uint32_t *type, - DATA_BLOB *data); - - /** - * Retrieve a registry value with the specified name - */ - WERROR (*get_value_by_name) (TALLOC_CTX *mem_ctx, - struct hive_key *key, const char *name, - uint32_t *type, DATA_BLOB *data); - - /** - * Set a value on the specified registry key. - */ - WERROR (*set_value) (struct hive_key *key, const char *name, - uint32_t type, const DATA_BLOB data); - - /** - * Remove a value. - */ - WERROR (*delete_value) (struct hive_key *key, const char *name); - - /* Security Descriptors */ - - /** - * Change the security descriptor on a registry key. - * - * This should return WERR_NOT_SUPPORTED if the underlying - * format does not have a mechanism for storing - * security descriptors. - */ - WERROR (*set_sec_desc) (struct hive_key *key, - const struct security_descriptor *desc); - - /** - * Retrieve the security descriptor on a registry key. - * - * This should return WERR_NOT_SUPPORTED if the underlying - * format does not have a mechanism for storing - * security descriptors. - */ - WERROR (*get_sec_desc) (TALLOC_CTX *ctx, - const struct hive_key *key, - struct security_descriptor **desc); - - /** - * Retrieve general information about a key. - */ - WERROR (*get_key_info) (TALLOC_CTX *mem_ctx, - const struct hive_key *key, - const char **classname, - uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_change_time, - uint32_t *max_subkeynamelen, - uint32_t *max_valnamelen, - uint32_t *max_valbufsize); -}; - -struct cli_credentials; -struct auth_session_info; - -WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - struct loadparm_context *lp_ctx, - struct hive_key **root); -WERROR hive_key_get_info(TALLOC_CTX *mem_ctx, const struct hive_key *key, - const char **classname, uint32_t *num_subkeys, - uint32_t *num_values, NTTIME *last_change_time, - uint32_t *max_subkeynamelen, - uint32_t *max_valnamelen, uint32_t *max_valbufsize); -WERROR hive_key_add_name(TALLOC_CTX *ctx, const struct hive_key *parent_key, - const char *name, const char *classname, - struct security_descriptor *desc, - struct hive_key **key); -WERROR hive_key_del(const struct hive_key *key, const char *name); -WERROR hive_get_key_by_name(TALLOC_CTX *mem_ctx, - const struct hive_key *key, const char *name, - struct hive_key **subkey); -WERROR hive_enum_key(TALLOC_CTX *mem_ctx, - const struct hive_key *key, uint32_t idx, - const char **name, - const char **classname, - NTTIME *last_mod_time); - -WERROR hive_key_set_value(struct hive_key *key, const char *name, - uint32_t type, const DATA_BLOB data); - -WERROR hive_get_value(TALLOC_CTX *mem_ctx, - struct hive_key *key, const char *name, - uint32_t *type, DATA_BLOB *data); -WERROR hive_get_value_by_index(TALLOC_CTX *mem_ctx, - struct hive_key *key, uint32_t idx, - const char **name, - uint32_t *type, DATA_BLOB *data); - -WERROR hive_key_del_value(struct hive_key *key, const char *name); - -WERROR hive_key_flush(struct hive_key *key); - - -/* Individual backends */ -WERROR reg_open_directory(TALLOC_CTX *parent_ctx, - const char *location, struct hive_key **key); -WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, - const char *location, struct smb_iconv_convenience *iconv_convenience, - struct hive_key **key); -WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - struct loadparm_context *lp_ctx, - struct hive_key **k); - - -WERROR reg_create_directory(TALLOC_CTX *parent_ctx, - const char *location, struct hive_key **key); -WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, - struct smb_iconv_convenience *iconv_convenience, - const char *location, - int major_version, - struct hive_key **key); - - -#endif /* __REGISTRY_HIVE_H__ */ diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index a192f3be4d..46ccca922b 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -18,13 +18,13 @@ along with this program. If not, see . */ #include "includes.h" -#include "lib/registry/hive.h" #include "system/filesys.h" #include "system/time.h" #include "lib/registry/tdr_regf.h" #include "librpc/gen_ndr/ndr_security.h" #include "librpc/gen_ndr/winreg.h" #include "param/param.h" +#include "lib/registry/registry.h" static struct hive_operations reg_backend_regf; diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index b76f2c4bcc..ff03f71eb2 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -24,10 +24,191 @@ struct registry_context; #include +#include "libcli/util/werror.h" #include "librpc/gen_ndr/security.h" -#include "lib/registry/hive.h" #include "libcli/util/ntstatus.h" +/** + * The hive API. This API is generally used for + * reading a specific file that contains just one hive. + * + * Good examples are .DAT (NTUSER.DAT) files. + * + * This API does not have any notification support (that + * should be provided by the registry implementation), nor + * does it understand what predefined keys are. + */ + +struct hive_key { + const struct hive_operations *ops; +}; + +struct hive_operations { + const char *name; + + /** + * Open a specific subkey + */ + WERROR (*enum_key) (TALLOC_CTX *mem_ctx, + const struct hive_key *key, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time); + + /** + * Open a subkey by name + */ + WERROR (*get_key_by_name) (TALLOC_CTX *mem_ctx, + const struct hive_key *key, const char *name, + struct hive_key **subkey); + + /** + * Add a new key. + */ + WERROR (*add_key) (TALLOC_CTX *ctx, + const struct hive_key *parent_key, const char *name, + const char *classname, + struct security_descriptor *desc, + struct hive_key **key); + /** + * Remove an existing key. + */ + WERROR (*del_key) (const struct hive_key *key, const char *name); + + /** + * Force write of a key to disk. + */ + WERROR (*flush_key) (struct hive_key *key); + + /** + * Retrieve a registry value with a specific index. + */ + WERROR (*enum_value) (TALLOC_CTX *mem_ctx, + struct hive_key *key, int idx, + const char **name, uint32_t *type, + DATA_BLOB *data); + + /** + * Retrieve a registry value with the specified name + */ + WERROR (*get_value_by_name) (TALLOC_CTX *mem_ctx, + struct hive_key *key, const char *name, + uint32_t *type, DATA_BLOB *data); + + /** + * Set a value on the specified registry key. + */ + WERROR (*set_value) (struct hive_key *key, const char *name, + uint32_t type, const DATA_BLOB data); + + /** + * Remove a value. + */ + WERROR (*delete_value) (struct hive_key *key, const char *name); + + /* Security Descriptors */ + + /** + * Change the security descriptor on a registry key. + * + * This should return WERR_NOT_SUPPORTED if the underlying + * format does not have a mechanism for storing + * security descriptors. + */ + WERROR (*set_sec_desc) (struct hive_key *key, + const struct security_descriptor *desc); + + /** + * Retrieve the security descriptor on a registry key. + * + * This should return WERR_NOT_SUPPORTED if the underlying + * format does not have a mechanism for storing + * security descriptors. + */ + WERROR (*get_sec_desc) (TALLOC_CTX *ctx, + const struct hive_key *key, + struct security_descriptor **desc); + + /** + * Retrieve general information about a key. + */ + WERROR (*get_key_info) (TALLOC_CTX *mem_ctx, + const struct hive_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, + uint32_t *max_valbufsize); +}; + +struct cli_credentials; +struct auth_session_info; + +WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + struct loadparm_context *lp_ctx, + struct hive_key **root); +WERROR hive_key_get_info(TALLOC_CTX *mem_ctx, const struct hive_key *key, + const char **classname, uint32_t *num_subkeys, + uint32_t *num_values, NTTIME *last_change_time, + uint32_t *max_subkeynamelen, + uint32_t *max_valnamelen, uint32_t *max_valbufsize); +WERROR hive_key_add_name(TALLOC_CTX *ctx, const struct hive_key *parent_key, + const char *name, const char *classname, + struct security_descriptor *desc, + struct hive_key **key); +WERROR hive_key_del(const struct hive_key *key, const char *name); +WERROR hive_get_key_by_name(TALLOC_CTX *mem_ctx, + const struct hive_key *key, const char *name, + struct hive_key **subkey); +WERROR hive_enum_key(TALLOC_CTX *mem_ctx, + const struct hive_key *key, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time); + +WERROR hive_key_set_value(struct hive_key *key, const char *name, + uint32_t type, const DATA_BLOB data); + +WERROR hive_get_value(TALLOC_CTX *mem_ctx, + struct hive_key *key, const char *name, + uint32_t *type, DATA_BLOB *data); +WERROR hive_get_value_by_index(TALLOC_CTX *mem_ctx, + struct hive_key *key, uint32_t idx, + const char **name, + uint32_t *type, DATA_BLOB *data); + +WERROR hive_key_del_value(struct hive_key *key, const char *name); + +WERROR hive_key_flush(struct hive_key *key); + + +/* Individual backends */ +WERROR reg_open_directory(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key); +WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, + const char *location, struct smb_iconv_convenience *iconv_convenience, + struct hive_key **key); +WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + struct loadparm_context *lp_ctx, + struct hive_key **k); + + +WERROR reg_create_directory(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key); +WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, + struct smb_iconv_convenience *iconv_convenience, + const char *location, + int major_version, + struct hive_key **key); + + + /* Handles for the predefined keys */ #define HKEY_CLASSES_ROOT 0x80000000 #define HKEY_CURRENT_USER 0x80000001 diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i index 20ae671c75..8ab402d57d 100644 --- a/source4/lib/registry/registry.i +++ b/source4/lib/registry/registry.i @@ -26,7 +26,6 @@ #include "includes.h" #include "registry.h" #include "param/param.h" -#include "hive.h" typedef struct registry_context reg; typedef struct hive_key hive_key; diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index 51c255e9f7..ded3acbbe6 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -2529,7 +2529,7 @@ static swig_module_info swig_module = {swig_types, 25, 0, 0, 0, 0}; #include "includes.h" #include "registry.h" #include "param/param.h" -#include "hive.h" +#include "registry.h" typedef struct registry_context reg; typedef struct hive_key hive_key; -- cgit From 4924446969b0f2a02b799fa9b2af14172310ebf0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2008 14:10:16 +0200 Subject: Trim down installed headers some more. (This used to be commit 71aa38842c270d52d39b805bf7ce29e25e062024) --- source4/lib/registry/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 1deac1dd46..77b4ece552 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -39,7 +39,7 @@ PUBLIC_DEPENDENCIES = \ # End MODULE registry_ldb ################################################ -PUBLIC_HEADERS += $(addprefix lib/registry/, registry.h hive.h) +PUBLIC_HEADERS += lib/registry/registry.h [SUBSYSTEM::registry_common] PUBLIC_DEPENDENCIES = registry -- cgit From 1cf8130e110c63a3bfc04ef8e21ca4343a4ab35c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2008 14:18:31 +0200 Subject: Move handle utility functions to public header, remove more public headers. (This used to be commit 92e71c19f4e1d3ca123a083942ec578d21f7012c) --- source4/lib/registry/registry_wrap.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index ded3acbbe6..da09ecbe08 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -2529,7 +2529,6 @@ static swig_module_info swig_module = {swig_types, 25, 0, 0, 0, 0}; #include "includes.h" #include "registry.h" #include "param/param.h" -#include "registry.h" typedef struct registry_context reg; typedef struct hive_key hive_key; -- cgit From 4e5e7a7c688d8a065994cb16fb1da7581bab081a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2008 16:47:17 +0200 Subject: Reintroduce header previously autogenerated but ignored by git. Also fixed extra include in regpatch. (This used to be commit 0e371cf169e9a607fcbb3e65437ab9413935dd52) --- source4/lib/registry/tools/regpatch.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 71837d1807..98443e6456 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -23,7 +23,6 @@ #include "lib/registry/registry.h" #include "lib/cmdline/popt_common.h" #include "lib/registry/tools/common.h" -#include "lib/registry/patchfile.h" #include "param/param.h" int main(int argc, char **argv) -- cgit From 8495d17c1a97489a75b777d79e69f9680267fd28 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 3 Apr 2008 01:36:03 +0200 Subject: Fix installation of dcerpc_atsvc and registry as required by samba-gtk. (This used to be commit 64a6887ecddc1599bde5dcb06d0b74ffea1def0c) --- source4/lib/registry/registry.pc.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.pc.in b/source4/lib/registry/registry.pc.in index 98943a0736..d981a45b2c 100644 --- a/source4/lib/registry/registry.pc.in +++ b/source4/lib/registry/registry.pc.in @@ -5,8 +5,8 @@ includedir=@includedir@ Name: registry Description: Windows-style registry library -Requires: ldb -Requires.private: +Requires: talloc +Requires.private: ldb Version: 0.0.1 Libs: -L${libdir} -lregistry Cflags: -I${includedir} -DHAVE_IMMEDIATE_STRUCTURES=1 -- cgit From adc09857420c4a9306148e8d15ff5faf633ba7a5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 3 Apr 2008 02:28:31 +0200 Subject: Install libevents since it's required by samba-gtk. (This used to be commit 2073346828ffa1d9c35105eadd7afddd3a76a045) --- source4/lib/registry/registry.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index ff03f71eb2..a86294bf46 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -22,11 +22,15 @@ #define _REGISTRY_H struct registry_context; +struct loadparm_context; +struct smb_iconv_convenience; #include #include "libcli/util/werror.h" #include "librpc/gen_ndr/security.h" #include "libcli/util/ntstatus.h" +#include "util/time.h" +#include "util/data_blob.h" /** * The hive API. This API is generally used for -- cgit From 225a65da2d3c675dba8bd2330dd56f949e21fa4b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Apr 2008 21:31:06 +0200 Subject: Attempt to fix get_value() test on sparc machines. (This used to be commit 10102d80d0f78777a69f6b3b1e5606d7d56b7254) --- source4/lib/registry/tests/hive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index 70b0241b04..a16736c761 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -220,7 +220,7 @@ static bool test_get_value(struct torture_context *tctx, const void *test_data) torture_assert_int_equal(tctx, value.length, 4, "value length"); torture_assert_int_equal(tctx, type, REG_DWORD, "value type"); - torture_assert_int_equal(tctx, data, IVAL(value.data, 0), + torture_assert_mem_equal(tctx, &data, value.data, sizeof(uint32_t), "value data"); return true; -- cgit From ae553dfcecdd605658dea73ccb6e577b059f478c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Apr 2008 21:33:59 +0200 Subject: Use new torture_assert_mem_equal. (This used to be commit b6319b64d7ef9c58f771f338317d4d525d39a8f2) --- source4/lib/registry/tests/registry.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index e5e34c11e0..1780b4e772 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -428,7 +428,7 @@ static bool test_get_value(struct torture_context *tctx, void *_data) torture_assert_werr_ok(tctx, error, "getting value"); torture_assert_int_equal(tctx, 4, data.length, "value length ok"); - torture_assert(tctx, memcmp(data.data, &value, 4) == 0, + torture_assert_mem_equal(tctx, data.data, &value, 4, "value content ok"); torture_assert_int_equal(tctx, REG_DWORD, type, "value type"); -- cgit From 148d3b170ae00d4001fa011450c7238052d32ae2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Apr 2008 22:00:36 +0200 Subject: Use torture_assert_mem_equal() in a couple more places. (This used to be commit e2c3fab9d1bf0482c15a115e7d373562ffe50b29) --- source4/lib/registry/tests/registry.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 1780b4e772..b19a6abffb 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -496,7 +496,7 @@ static bool test_list_values(struct torture_context *tctx, void *_data) torture_assert_str_equal(tctx, name, "bar", "value name"); torture_assert_int_equal(tctx, 4, data.length, "value length"); - torture_assert(tctx, memcmp(data.data, &value, 4) == 0, + torture_assert_mem_equal(tctx, data.data, &value, 4, "value content"); torture_assert_int_equal(tctx, REG_DWORD, type, "value type"); -- cgit From 212644b5a1107ad81e5ce3bc3118c8983d3f2a86 Mon Sep 17 00:00:00 2001 From: Wilco Baan Hofman Date: Mon, 14 Apr 2008 12:48:25 +0200 Subject: Attempt to fix the patchfile_preg backend for big endian machines. Update some functions to properly state what is not supported (yet). Registry .reg uses UCS-2, not UTF-16. (This used to be commit 664a035dd9fc6e3b50a771baa98f8d79360cc4c1) --- source4/lib/registry/patchfile_dotreg.c | 2 +- source4/lib/registry/patchfile_preg.c | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/patchfile_dotreg.c b/source4/lib/registry/patchfile_dotreg.c index 59f4044713..5aa7e2bab7 100644 --- a/source4/lib/registry/patchfile_dotreg.c +++ b/source4/lib/registry/patchfile_dotreg.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* FIXME Newer .REG files, created by Windows XP and above use unicode UTF-16 */ +/* FIXME Newer .REG files, created by Windows XP and above use unicode UCS-2 */ #include "includes.h" #include "lib/registry/registry.h" diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c index 0fa367bfcb..5216a04c8b 100644 --- a/source4/lib/registry/patchfile_preg.c +++ b/source4/lib/registry/patchfile_preg.c @@ -42,30 +42,30 @@ static WERROR preg_read_utf16(struct smb_iconv_convenience *ic, int fd, char *c) /* FIXME These functions need to be implemented */ static WERROR reg_preg_diff_add_key(void *_data, const char *key_name) { - return WERR_OK; + return WERR_NOT_SUPPORTED; } static WERROR reg_preg_diff_del_key(void *_data, const char *key_name) { - return WERR_OK; + return WERR_NOT_SUPPORTED; } static WERROR reg_preg_diff_set_value(void *_data, const char *key_name, const char *value_name, uint32_t value_type, DATA_BLOB value_data) { - return WERR_OK; + return WERR_NOT_SUPPORTED; } static WERROR reg_preg_diff_del_value(void *_data, const char *key_name, const char *value_name) { - return WERR_OK; + return WERR_NOT_SUPPORTED; } static WERROR reg_preg_diff_del_all_values(void *_data, const char *key_name) { - return WERR_OK; + return WERR_NOT_SUPPORTED; } static WERROR reg_preg_diff_done(void *_data) @@ -149,6 +149,8 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, ret = WERR_GENERAL_FAILURE; goto cleanup; } + preg_header.version = IVAL(&preg_header.version, 0); + if (strncmp(preg_header.hdr, "PReg", 4) != 0) { DEBUG(0, ("This file is not a valid preg registry file\n")); ret = WERR_GENERAL_FAILURE; @@ -193,6 +195,8 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, ret = WERR_GENERAL_FAILURE; goto cleanup; } + value_type = IVAL(&value_type, 0); + /* Read past delimiter */ buf_ptr = buf; if (!(W_ERROR_IS_OK(preg_read_utf16(iconv_convenience, fd, buf_ptr)) && -- cgit From ffc5cbfe803326a1c3bf55684717af910d091c5a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Apr 2008 16:53:00 +0200 Subject: Move object files lists to makefile rather than smb_build. (This used to be commit 5628d58990144463fd87f8c847c9384ac2193681) --- source4/lib/registry/config.mk | 43 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 24 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 77b4ece552..affc11d31c 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -1,6 +1,7 @@ [SUBSYSTEM::TDR_REGF] PUBLIC_DEPENDENCIES = TDR -OBJ_FILES = tdr_regf.o + +TDR_REGF_OBJ_FILES = lib/registry/tdr_regf.o # Special support for external builddirs lib/registry/regf.c: lib/registry/tdr_regf.c @@ -20,93 +21,87 @@ clean:: VERSION = 0.0.1 PC_FILE = registry.pc SO_VERSION = 0 -OBJ_FILES = \ - interface.o \ - util.o \ - samba.o \ - patchfile_dotreg.o \ - patchfile_preg.o \ - patchfile.o \ - regf.o \ - hive.o \ - local.o \ - ldb.o \ - dir.o \ - rpc.o PUBLIC_DEPENDENCIES = \ LIBSAMBA-UTIL CHARSET TDR_REGF LIBLDB \ RPC_NDR_WINREG LDB_WRAP # End MODULE registry_ldb ################################################ +registry_OBJ_FILES = $(addprefix lib/registry/, interface.o util.o samba.o \ + patchfile_dotreg.o patchfile_preg.o patchfile.o regf.o \ + hive.o local.o ldb.o dir.o rpc.o) + PUBLIC_HEADERS += lib/registry/registry.h [SUBSYSTEM::registry_common] PUBLIC_DEPENDENCIES = registry -OBJ_FILES = tools/common.o PRIVATE_PROTO_HEADER = tools/common.h +registry_common_OBJ_FILES = lib/registry/tools/common.o + ################################################ # Start BINARY regdiff [BINARY::regdiff] INSTALLDIR = BINDIR -OBJ_FILES = tools/regdiff.o PRIVATE_DEPENDENCIES = \ LIBSAMBA-HOSTCONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS # End BINARY regdiff ################################################ +regdiff_OBJ_FILES = lib/registry/tools/regdiff.o + MANPAGES += lib/registry/man/regdiff.1 ################################################ # Start BINARY regpatch [BINARY::regpatch] INSTALLDIR = BINDIR -OBJ_FILES = tools/regpatch.o PRIVATE_DEPENDENCIES = \ LIBSAMBA-HOSTCONFIG registry LIBPOPT POPT_SAMBA POPT_CREDENTIALS \ registry_common # End BINARY regpatch ################################################ +regpatch_OBJ_FILES = lib/registry/tools/regpatch.o + MANPAGES += lib/registry/man/regpatch.1 ################################################ # Start BINARY regshell [BINARY::regshell] INSTALLDIR = BINDIR -OBJ_FILES = tools/regshell.o PRIVATE_DEPENDENCIES = \ LIBSAMBA-HOSTCONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \ SMBREADLINE registry_common # End BINARY regshell ################################################ +regshell_OBJ_FILES = lib/registry/tools/regshell.o + MANPAGES += lib/registry/man/regshell.1 ################################################ # Start BINARY regtree [BINARY::regtree] INSTALLDIR = BINDIR -OBJ_FILES = tools/regtree.o PRIVATE_DEPENDENCIES = \ LIBSAMBA-HOSTCONFIG LIBPOPT registry POPT_SAMBA POPT_CREDENTIALS \ registry_common # End BINARY regtree ################################################ +regtree_OBJ_FILES = lib/registry/tools/regtree.o + MANPAGES += lib/registry/man/regtree.1 [SUBSYSTEM::torture_registry] PRIVATE_DEPENDENCIES = registry PRIVATE_PROTO_HEADER = tests/proto.h -OBJ_FILES = \ - tests/generic.o \ - tests/hive.o \ - tests/diff.o \ - tests/registry.o + +torture_registry_OBJ_FILES = $(addprefix lib/registry/tests/, generic.o hive.o diff.o registry.o) [PYTHON::swig_registry] PUBLIC_DEPENDENCIES = registry SWIG_FILE = registry.i +swig_registry_OBJ_FILES = lib/registry/registry_wrap.o -- cgit From 12147fca2b3acd37eb20db82996714320cd4e9b2 Mon Sep 17 00:00:00 2001 From: Wilco Baan Hofman Date: Mon, 14 Apr 2008 22:52:51 +0200 Subject: Add support for security descriptors. Also patched the regf backend to support this. Did not touch the ldb, dir and rpc backends yet. (This used to be commit c4626f21a898da27a051f2c67f8fd73f55d4fc7d) --- source4/lib/registry/hive.c | 18 ++++++++++ source4/lib/registry/interface.c | 23 +++---------- source4/lib/registry/local.c | 16 +++++++++ source4/lib/registry/regf.c | 64 +++++++++++++++++++++++++++++------ source4/lib/registry/registry.h | 21 +++++++----- source4/lib/registry/tests/hive.c | 56 +++++++++++++++++++++++++++++- source4/lib/registry/tests/registry.c | 8 ++--- 7 files changed, 164 insertions(+), 42 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/hive.c b/source4/lib/registry/hive.c index 2a9b1a59ce..3bb5b566c9 100644 --- a/source4/lib/registry/hive.c +++ b/source4/lib/registry/hive.c @@ -143,6 +143,24 @@ WERROR hive_get_value_by_index(TALLOC_CTX *mem_ctx, return key->ops->enum_value(mem_ctx, key, idx, name, type, data); } +WERROR hive_get_sec_desc(TALLOC_CTX *mem_ctx, + struct hive_key *key, + struct security_descriptor **security) +{ + if (key->ops->get_sec_desc == NULL) + return WERR_NOT_SUPPORTED; + + return key->ops->get_sec_desc(mem_ctx, key, security); +} + +WERROR hive_set_sec_desc(struct hive_key *key, + const struct security_descriptor *security) +{ + if (key->ops->set_sec_desc == NULL) + return WERR_NOT_SUPPORTED; + + return key->ops->set_sec_desc(key, security); +} WERROR hive_key_del_value(struct hive_key *key, const char *name) { diff --git a/source4/lib/registry/interface.c b/source4/lib/registry/interface.c index a18fd2c28c..06b002859d 100644 --- a/source4/lib/registry/interface.c +++ b/source4/lib/registry/interface.c @@ -249,10 +249,10 @@ _PUBLIC_ WERROR reg_get_sec_desc(TALLOC_CTX *ctx, return WERR_INVALID_PARAM; /* A 'real' set function has preference */ - if (key->context->ops->get_security == NULL) + if (key->context->ops->get_sec_desc == NULL) return WERR_NOT_SUPPORTED; - return key->context->ops->get_security(ctx, key, secdesc); + return key->context->ops->get_sec_desc(ctx, key, secdesc); } /** @@ -283,27 +283,14 @@ _PUBLIC_ WERROR reg_key_flush(struct registry_key *key) return key->context->ops->flush_key(key); } -_PUBLIC_ WERROR reg_get_security(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - struct security_descriptor **security) -{ - if (key == NULL) - return WERR_INVALID_PARAM; - - if (key->context->ops->get_security == NULL) - return WERR_NOT_SUPPORTED; - - return key->context->ops->get_security(mem_ctx, key, security); -} - -_PUBLIC_ WERROR reg_set_security(struct registry_key *key, +_PUBLIC_ WERROR reg_set_sec_desc(struct registry_key *key, struct security_descriptor *security) { if (key == NULL) return WERR_INVALID_PARAM; - if (key->context->ops->set_security == NULL) + if (key->context->ops->set_sec_desc == NULL) return WERR_NOT_SUPPORTED; - return key->context->ops->set_security(key, security); + return key->context->ops->set_sec_desc(key, security); } diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index 5bf2d86588..da381cfbff 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -278,7 +278,21 @@ static WERROR local_get_key_info(TALLOC_CTX *mem_ctx, last_change_time, max_subkeynamelen, max_valnamelen, max_valbufsize); } +static WERROR local_get_sec_desc(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + struct security_descriptor **security) +{ + const struct local_key *local = (const struct local_key *)key; + return hive_get_sec_desc(mem_ctx, local->hive_key, security); +} +static WERROR local_set_sec_desc(struct registry_key *key, + const struct security_descriptor *security) +{ + const struct local_key *local = (const struct local_key *)key; + + return hive_set_sec_desc(local->hive_key, security); +} const static struct registry_operations local_ops = { .name = "local", .open_key = local_open_key, @@ -292,6 +306,8 @@ const static struct registry_operations local_ops = { .delete_value = local_delete_value, .flush_key = local_flush_key, .get_key_info = local_get_key_info, + .get_sec_desc = local_get_sec_desc, + .set_sec_desc = local_set_sec_desc, }; WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx, diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index 46ccca922b..57a895aa00 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -25,6 +25,8 @@ #include "librpc/gen_ndr/winreg.h" #include "param/param.h" #include "lib/registry/registry.h" +#include "libcli/security/security.h" + static struct hive_operations reg_backend_regf; @@ -1915,9 +1917,12 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, { struct regf_data *regf; struct regf_hdr *regf_hdr; - int i; struct nk_block nk; + struct sk_block sk; WERROR error; + DATA_BLOB data; + struct security_descriptor *sd; + uint32_t sk_offset; regf = (struct regf_data *)talloc_zero(NULL, struct regf_data); @@ -1945,20 +1950,17 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, regf_hdr->version.minor = minor_version; regf_hdr->last_block = 0x1000; /* Block size */ regf_hdr->description = talloc_strdup(regf_hdr, - "registry created by Samba 4"); + "Registry created by Samba 4"); W_ERROR_HAVE_NO_MEMORY(regf_hdr->description); regf_hdr->chksum = 0; regf->header = regf_hdr; - i = 0; /* Create all hbin blocks */ regf->hbins = talloc_array(regf, struct hbin_block *, 1); W_ERROR_HAVE_NO_MEMORY(regf->hbins); regf->hbins[0] = NULL; - regf_hdr->data_offset = -1; /* FIXME */ - nk.header = "nk"; nk.type = REG_SUB_KEY; unix_to_nt_time(&nk.last_change, time(NULL)); @@ -1971,27 +1973,67 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, nk.num_values = 0; nk.values_offset = -1; memset(nk.unk3, 0, 5); - nk.clsname_offset = -1; /* FIXME: fill in */ + nk.clsname_offset = -1; nk.clsname_length = 0; - nk.key_name = ""; + nk.sk_offset = 0x80; + nk.key_name = "SambaRootKey"; + + /* + * It should be noted that changing the key_name to something shorter + * creates a shorter nk block, which makes the position of the sk block + * change. All Windows registries I've seen have the sk at 0x80. + * I therefore recommend that our regf files share that offset -- Wilco + */ + + /* Create a security descriptor. */ + sd = security_descriptor_dacl_create(regf, + 0, + NULL, NULL, + SID_NT_AUTHENTICATED_USERS, + SEC_ACE_TYPE_ACCESS_ALLOWED, + SEC_GENERIC_ALL, + SEC_ACE_FLAG_OBJECT_INHERIT, + NULL); + + /* Push the security descriptor to a blob */ + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(&data, regf, NULL, + sd, (ndr_push_flags_fn_t)ndr_push_security_descriptor))) { + DEBUG(0, ("Unable to push security descriptor\n")); + return WERR_GENERAL_FAILURE; + } - nk.sk_offset = -1; /* FIXME: fill in */ + ZERO_STRUCT(sk); + sk.header = "sk"; + sk.prev_offset = 0x80; + sk.next_offset = 0x80; + sk.ref_cnt = 1; + sk.rec_size = data.length; + sk.sec_desc = data.data; /* Store the new nk key */ regf->header->data_offset = hbin_store_tdr(regf, (tdr_push_fn_t)tdr_push_nk_block, &nk); + /* Store the sk block */ + sk_offset = hbin_store_tdr(regf, + (tdr_push_fn_t) tdr_push_sk_block, + &sk); + if (sk_offset != 0x80) { + DEBUG(0, ("Error storing sk block, should be at 0x80, stored at 0x%x\n", nk.sk_offset)); + return WERR_GENERAL_FAILURE; + } + *key = (struct hive_key *)regf_get_key(parent_ctx, regf, regf->header->data_offset); - /* We can drop our own reference now that *key will have created one */ - talloc_free(regf); - error = regf_save_hbin(regf); if (!W_ERROR_IS_OK(error)) { return error; } + + /* We can drop our own reference now that *key will have created one */ + talloc_free(regf); return WERR_OK; } diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index a86294bf46..1348d1121f 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -184,6 +184,12 @@ WERROR hive_get_value_by_index(TALLOC_CTX *mem_ctx, struct hive_key *key, uint32_t idx, const char **name, uint32_t *type, DATA_BLOB *data); +WERROR hive_get_sec_desc(TALLOC_CTX *mem_ctx, + struct hive_key *key, + struct security_descriptor **security); + +WERROR hive_set_sec_desc(struct hive_key *key, + const struct security_descriptor *security); WERROR hive_key_del_value(struct hive_key *key, const char *name); @@ -311,11 +317,11 @@ struct registry_operations { uint32_t *type, DATA_BLOB *data); - WERROR (*get_security) (TALLOC_CTX *mem_ctx, + WERROR (*get_sec_desc) (TALLOC_CTX *mem_ctx, const struct registry_key *key, struct security_descriptor **security); - WERROR (*set_security) (struct registry_key *key, + WERROR (*set_sec_desc) (struct registry_key *key, const struct security_descriptor *security); WERROR (*load_key) (struct registry_key *key, @@ -461,12 +467,8 @@ struct registry_key *reg_import_hive_key(struct registry_context *ctx, struct hive_key *hive, uint32_t predef_key, const char **elements); -WERROR reg_get_security(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - struct security_descriptor **security); - -WERROR reg_set_security(struct registry_key *key, - struct security_descriptor *security); +WERROR reg_set_sec_desc(struct registry_key *key, + const struct security_descriptor *security); struct reg_diff_callbacks { WERROR (*add_key) (void *callback_data, const char *key_name); @@ -490,6 +492,9 @@ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, struct smb_iconv_convenience *iconv_convenience, struct reg_diff_callbacks **callbacks, void **callback_data); +WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename, + struct reg_diff_callbacks **callbacks, + void **callback_data); WERROR reg_generate_diff_key(struct registry_key *oldkey, struct registry_key *newkey, const char *path, diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index a16736c761..4fe7f66c03 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -26,6 +26,7 @@ #include "librpc/gen_ndr/winreg.h" #include "system/filesys.h" #include "param/param.h" +#include "libcli/security/security.h" static bool test_del_nonexistant_key(struct torture_context *tctx, const void *test_data) @@ -297,6 +298,57 @@ static bool test_list_values(struct torture_context *tctx, return true; } +static bool test_hive_security(struct torture_context *tctx, const void *_data) +{ + struct hive_key *subkey = NULL; + const struct hive_key *root = _data; + WERROR error; + struct security_descriptor *osd, *nsd; + + osd = security_descriptor_dacl_create(tctx, + 0, + NULL, NULL, + SID_NT_AUTHENTICATED_USERS, + SEC_ACE_TYPE_ACCESS_ALLOWED, + SEC_GENERIC_ALL, + SEC_ACE_FLAG_OBJECT_INHERIT, + NULL); + + + error = hive_key_add_name(tctx, root, "SecurityKey", NULL, + osd, &subkey); + torture_assert_werr_ok(tctx, error, "hive_key_add_name"); + + error = hive_get_sec_desc(tctx, subkey, &nsd); + torture_assert_werr_ok (tctx, error, "getting security descriptor"); + + torture_assert(tctx, security_descriptor_equal(osd, nsd), + "security descriptor changed!"); + + /* Create a fresh security descriptor */ + talloc_free(osd); + osd = security_descriptor_dacl_create(tctx, + 0, + NULL, NULL, + SID_NT_AUTHENTICATED_USERS, + SEC_ACE_TYPE_ACCESS_ALLOWED, + SEC_GENERIC_ALL, + SEC_ACE_FLAG_OBJECT_INHERIT, + NULL); + + error = hive_set_sec_desc(subkey, osd); + torture_assert_werr_ok(tctx, error, "setting security descriptor"); + + printf("The second one is done.\n"); + error = hive_get_sec_desc(tctx, subkey, &nsd); + torture_assert_werr_ok (tctx, error, "getting security descriptor"); + + torture_assert(tctx, security_descriptor_equal(osd, nsd), + "security descriptor changed!"); + + return true; +} + static void tcase_add_tests(struct torture_tcase *tcase) { torture_tcase_add_simple_test_const(tcase, "del_nonexistant_key", @@ -324,6 +376,8 @@ static void tcase_add_tests(struct torture_tcase *tcase) test_del_key); torture_tcase_add_simple_test_const(tcase, "del_value", test_del_value); + torture_tcase_add_simple_test_const(tcase, "check hive security", + test_hive_security); } static bool hive_setup_dir(struct torture_context *tctx, void **data) @@ -381,7 +435,7 @@ static bool hive_setup_regf(struct torture_context *tctx, void **data) char *dirname; NTSTATUS status; - status = torture_temp_dir(tctx, "hive-dir", &dirname); + status = torture_temp_dir(tctx, "hive-regf", &dirname); if (!NT_STATUS_IS_OK(status)) return false; diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index b19a6abffb..97c1190a68 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -387,11 +387,11 @@ static bool test_security(struct torture_context *tctx, void *_data) SEC_ACE_FLAG_OBJECT_INHERIT, NULL); - error = reg_set_security(subkey, osd); - torture_assert_werr_ok(tctx, error, "setting security"); + error = reg_set_sec_desc(subkey, osd); + torture_assert_werr_ok(tctx, error, "setting security descriptor"); - error = reg_get_security(tctx, subkey, &nsd); - torture_assert_werr_ok (tctx, error, "setting security"); + error = reg_get_sec_desc(tctx, subkey, &nsd); + torture_assert_werr_ok (tctx, error, "getting security descriptor"); torture_assert(tctx, security_descriptor_equal(osd, nsd), "security descriptor changed!"); -- cgit From a31b6607f22f6b3e1b354db2f9f611b299a2f7ae Mon Sep 17 00:00:00 2001 From: Wilco Baan Hofman Date: Mon, 14 Apr 2008 22:56:14 +0200 Subject: Remove debug stuff. (This used to be commit 7ba2e5dc5b6d82457c298f7ecdb6baea43f04854) --- source4/lib/registry/tests/hive.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index 4fe7f66c03..474704b517 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -339,7 +339,6 @@ static bool test_hive_security(struct torture_context *tctx, const void *_data) error = hive_set_sec_desc(subkey, osd); torture_assert_werr_ok(tctx, error, "setting security descriptor"); - printf("The second one is done.\n"); error = hive_get_sec_desc(tctx, subkey, &nsd); torture_assert_werr_ok (tctx, error, "getting security descriptor"); -- cgit From 08baea013b73607df0c86f24506912c7e6af6f7e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Apr 2008 02:25:16 +0200 Subject: Move SOVERSION, VERSION and PC_FILE out of smb_build but use make variables directly instead. (This used to be commit 9d0ae012b0b463278cd054d06788aa998acc2da2) --- source4/lib/registry/config.mk | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index affc11d31c..ce19d8512e 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -18,15 +18,17 @@ clean:: ################################################ # Start SUBSYSTEM registry [LIBRARY::registry] -VERSION = 0.0.1 -PC_FILE = registry.pc -SO_VERSION = 0 PUBLIC_DEPENDENCIES = \ LIBSAMBA-UTIL CHARSET TDR_REGF LIBLDB \ RPC_NDR_WINREG LDB_WRAP # End MODULE registry_ldb ################################################ +PC_FILES += lib/registry/registry.pc + +registry_VERSION = 0.0.1 +registry_SOVERSION = 0 + registry_OBJ_FILES = $(addprefix lib/registry/, interface.o util.o samba.o \ patchfile_dotreg.o patchfile_preg.o patchfile.o regf.o \ hive.o local.o ldb.o dir.o rpc.o) -- cgit From 0b8d2b3cb779463a1e24039300ac2669862f9b64 Mon Sep 17 00:00:00 2001 From: Wilco Baan Hofman Date: Tue, 15 Apr 2008 11:52:33 +0200 Subject: Fixed the patchfile tests and tidy up the patchfile backends. (This used to be commit 6e9b1e35a269af2eda79356c1525f5413656d648) --- source4/lib/registry/patchfile.c | 4 +- source4/lib/registry/patchfile_dotreg.c | 8 +- source4/lib/registry/patchfile_preg.c | 10 +- source4/lib/registry/registry.h | 4 + source4/lib/registry/tests/diff.c | 232 +++++++++++++++++++++++++++++--- 5 files changed, 226 insertions(+), 32 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index 15e3a158f2..eaeef341bb 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -45,7 +45,7 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, void *callback_data) { int i; - struct registry_key *t1, *t2; + struct registry_key *t1 = NULL, *t2 = NULL; char *tmppath; const char *keyname1; WERROR error, error1, error2; @@ -295,7 +295,7 @@ _PUBLIC_ WERROR reg_diff_load(const char *filename, /* Reset position in file */ lseek(fd, 0, SEEK_SET); -#if 0 +#if 0 /* These backends are not supported yet. */ if (strncmp(hdr, "CREG", 4) == 0) { /* Must be a W9x CREG Config.pol file */ return reg_creg_diff_load(diff, fd); diff --git a/source4/lib/registry/patchfile_dotreg.c b/source4/lib/registry/patchfile_dotreg.c index 5aa7e2bab7..1bc9c60753 100644 --- a/source4/lib/registry/patchfile_dotreg.c +++ b/source4/lib/registry/patchfile_dotreg.c @@ -3,7 +3,7 @@ Reading .REG files Copyright (C) Jelmer Vernooij 2004-2007 - Copyright (C) Wilco Baan Hofman 2006 + Copyright (C) Wilco Baan Hofman 2006-2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -112,8 +112,8 @@ _PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, data->iconv_convenience = iconv_convenience; if (filename) { - data->fd = open(filename, O_CREAT, 0755); - if (data->fd == -1) { + data->fd = open(filename, O_CREAT|O_WRONLY, 0755); + if (data->fd < 0) { DEBUG(0, ("Unable to open %s\n", filename)); return WERR_BADFILE; } @@ -121,7 +121,7 @@ _PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, data->fd = STDOUT_FILENO; } - fdprintf(data->fd, "%s\n", HEADER_STRING); + fdprintf(data->fd, "%s\n\n", HEADER_STRING); *callbacks = talloc(ctx, struct reg_diff_callbacks); diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c index 5216a04c8b..a28096517c 100644 --- a/source4/lib/registry/patchfile_preg.c +++ b/source4/lib/registry/patchfile_preg.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. Reading Registry.pol PReg registry files - Copyright (C) Wilco Baan Hofman 2006 + Copyright (C) Wilco Baan Hofman 2006-2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -71,7 +71,7 @@ static WERROR reg_preg_diff_del_all_values(void *_data, const char *key_name) static WERROR reg_preg_diff_done(void *_data) { struct preg_data *data = (struct preg_data *)_data; - + close(data->fd); talloc_free(data); return WERR_OK; @@ -95,15 +95,15 @@ _PUBLIC_ WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename, *callback_data = data; if (filename) { - data->fd = open(filename, O_CREAT, 0755); - if (data->fd == -1) { + data->fd = open(filename, O_CREAT|O_WRONLY, 0755); + if (data->fd < 0) { DEBUG(0, ("Unable to open %s\n", filename)); return WERR_BADFILE; } } else { data->fd = STDOUT_FILENO; } - snprintf(preg_header.hdr, 4, "PReg"); + memcpy(preg_header.hdr, "PReg", 4); SIVAL(&preg_header, 4, 1); write(data->fd, (uint8_t *)&preg_header,8); diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 1348d1121f..573379aff5 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -500,6 +500,10 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, const char *path, const struct reg_diff_callbacks *callbacks, void *callback_data); +WERROR reg_diff_load(const char *filename, + struct smb_iconv_convenience *iconv_convenience, + const struct reg_diff_callbacks *callbacks, + void *callback_data); diff --git a/source4/lib/registry/tests/diff.c b/source4/lib/registry/tests/diff.c index 690f71fcf7..da62342124 100644 --- a/source4/lib/registry/tests/diff.c +++ b/source4/lib/registry/tests/diff.c @@ -4,6 +4,7 @@ local testing of registry diff functionality Copyright (C) Jelmer Vernooij 2007 + Copyright (C) Wilco Baan Hofman 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,27 +25,79 @@ #include "torture/torture.h" #include "librpc/gen_ndr/winreg.h" -static bool test_generate_diff(struct torture_context *test) +struct diff_tcase_data { + struct registry_context *r1_ctx; + struct registry_context *r2_ctx; + struct reg_diff_callbacks *callbacks; + void *callback_data; + char *tempdir; + char *filename; +}; + +static bool test_generate_diff(struct torture_context *tctx, void *tcase_data) { /* WERROR reg_generate_diff(struct registry_context *ctx1, struct registry_context *ctx2, const struct reg_diff_callbacks *callbacks, void *callback_data) */ + WERROR error; + struct diff_tcase_data *td = tcase_data; + + error = reg_generate_diff(td->r1_ctx, td->r2_ctx, + td->callbacks, + td->callback_data); + torture_assert_werr_ok(tctx, error, "reg_generate_diff"); + return true; } - -static bool test_diff_load(struct torture_context *test) +#if 0 +static bool test_diff_load(struct torture_context *tctx, void *tcase_data) { - /* WERROR reg_diff_load(const char *filename, const struct reg_diff_callbacks *callbacks, void *callback_data) */ + struct diff_tcase_data *td = tcase_data; + struct smb_iconv_convenience *iconv_convenience; + struct reg_diff_callbacks *callbacks; + void *data; + WERROR error; + + iconv_convenience = smb_iconv_convenience_init(tctx, "CP850", "UTF-8", 1); + + + error = reg_diff_load(td->filename, iconv_convenience, callbacks, data); + torture_assert_werr_ok(tctx, error, "reg_diff_load"); return true; } - -static bool test_diff_apply(struct torture_context *test) +#endif +static bool test_diff_apply(struct torture_context *tctx, void *tcase_data) { - /* _PUBLIC_ WERROR reg_diff_apply (const char *filename, struct registry_context *ctx) */ + struct diff_tcase_data *td = tcase_data; + struct registry_key *key; + WERROR error; + + error = reg_diff_apply(td->r1_ctx, td->filename); + torture_assert_werr_ok(tctx, error, "reg_diff_apply"); + + error = td->r1_ctx->ops->get_predefined_key(td->r1_ctx, HKEY_LOCAL_MACHINE, &key); + torture_assert_werr_ok(tctx, error, "Opening HKEY_LOCAL_MACHINE failed"); + + /* If this generates an error it could be that the apply doesn't work, + * but also that the reg_generate_diff didn't work. */ + error = td->r1_ctx->ops->open_key(td->r1_ctx, key, "Software", &key); + torture_assert_werr_ok(tctx, error, "Opening HKLM\\Software failed"); + error = td->r1_ctx->ops->open_key(td->r1_ctx, key, "Microsoft", &key); + torture_assert_werr_ok(tctx, error, "Opening HKLM\\Software\\Microsoft failed"); + error = td->r1_ctx->ops->open_key(td->r1_ctx, key, "Windows", &key); + torture_assert_werr_ok(tctx, error, "Opening HKLM\\..\\Microsoft\\Windows failed"); + error = td->r1_ctx->ops->open_key(td->r1_ctx, key, "CurrentVersion", &key); + torture_assert_werr_ok(tctx, error, "Opening HKLM\\..\\Windows\\CurrentVersion failed"); + error = td->r1_ctx->ops->open_key(td->r1_ctx, key, "Policies", &key); + torture_assert_werr_ok(tctx, error, "Opening HKLM\\..\\CurrentVersion\\Policies failed"); + error = td->r1_ctx->ops->open_key(td->r1_ctx, key, "Explorer", &key); + torture_assert_werr_ok(tctx, error, "Opening HKLM\\..\\Policies\\Explorer failed"); + + return true; } @@ -58,7 +111,7 @@ static WERROR test_add_key(void *callback_data, const char *key_name) return WERR_OK; } -static bool test_generate_diff_key_add(struct torture_context *test) +static bool test_generate_diff_key_add(struct torture_context *tctx, void *tcase_data) { struct reg_diff_callbacks cb; struct registry_key rk; @@ -69,15 +122,15 @@ static bool test_generate_diff_key_add(struct torture_context *test) cb.add_key = test_add_key; - if (W_ERROR_IS_OK(reg_generate_diff_key(&rk, NULL, "bla", &cb, test))) + if (W_ERROR_IS_OK(reg_generate_diff_key(&rk, NULL, "bla", &cb, tctx))) return false; - torture_assert_str_equal(test, added_key, "bla", "key added"); + torture_assert_str_equal(tctx, added_key, "bla", "key added"); return true; } -static bool test_generate_diff_key_null(struct torture_context *test) +static bool test_generate_diff_key_null(struct torture_context *tctx, void *tcase_data) { struct reg_diff_callbacks cb; @@ -88,19 +141,156 @@ static bool test_generate_diff_key_null(struct torture_context *test) return true; } +static void tcase_add_tests (struct torture_tcase *tcase) +{ + torture_tcase_add_simple_test(tcase, "test_generate_diff_key_add", + test_generate_diff_key_add); + torture_tcase_add_simple_test(tcase, "test_generate_diff_key_null", + test_generate_diff_key_null); + torture_tcase_add_simple_test(tcase, "test_generate_diff", + test_generate_diff); + torture_tcase_add_simple_test(tcase, "test_diff_apply", + test_diff_apply); +/* torture_tcase_add_simple_test(tcase, "test_diff_load", + test_diff_load); +*/ +} + +static bool diff_setup_tcase(struct torture_context *tctx, void **data) +{ + struct registry_context *r1_ctx, *r2_ctx; + WERROR error; + NTSTATUS status; + struct hive_key *r1_hklm, *r1_hkcu; + struct hive_key *r2_hklm, *r2_hkcu; + const char *filename; + struct diff_tcase_data *td; + struct registry_key *key, *newkey; + DATA_BLOB blob; + + td = talloc(tctx, struct diff_tcase_data); + + /* Create two registry contexts */ + error = reg_open_local(tctx, &r1_ctx, NULL, NULL); + torture_assert_werr_ok(tctx, error, "Opening registry 1 for patch tests failed"); + + error = reg_open_local(tctx, &r2_ctx, NULL, NULL); + torture_assert_werr_ok(tctx, error, "Opening registry 2 for patch tests failed"); + + /* Create temp directory */ + status = torture_temp_dir(tctx, "patchfile", &td->tempdir); + torture_assert_ntstatus_ok(tctx, status, "Creating temp dir failed"); + + /* Create and mount HKLM and HKCU hives for registry 1 */ + filename = talloc_asprintf(tctx, "%s/r1_local_machine.ldb", td->tempdir); + error = reg_open_ldb_file(tctx, filename, NULL, NULL, tctx->lp_ctx, &r1_hklm); + torture_assert_werr_ok(tctx, error, "Opening local machine file failed"); + + error = reg_mount_hive(r1_ctx, r1_hklm, HKEY_LOCAL_MACHINE, NULL); + torture_assert_werr_ok(tctx, error, "Mounting hive failed"); + + filename = talloc_asprintf(tctx, "%s/r1_current_user.ldb", td->tempdir); + error = reg_open_ldb_file(tctx, filename, NULL, NULL, tctx->lp_ctx, &r1_hkcu); + torture_assert_werr_ok(tctx, error, "Opening current user file failed"); + + error = reg_mount_hive(r1_ctx, r1_hkcu, HKEY_CURRENT_USER, NULL); + torture_assert_werr_ok(tctx, error, "Mounting hive failed"); + + /* Create and mount HKLM and HKCU hives for registry 2 */ + filename = talloc_asprintf(tctx, "%s/r2_local_machine.ldb", td->tempdir); + error = reg_open_ldb_file(tctx, filename, NULL, NULL, tctx->lp_ctx, &r2_hklm); + torture_assert_werr_ok(tctx, error, "Opening local machine file failed"); + + error = reg_mount_hive(r2_ctx, r2_hklm, HKEY_LOCAL_MACHINE, NULL); + torture_assert_werr_ok(tctx, error, "Mounting hive failed"); + + filename = talloc_asprintf(tctx, "%s/r2_current_user.ldb", td->tempdir); + error = reg_open_ldb_file(tctx, filename, NULL, NULL, tctx->lp_ctx, &r2_hkcu); + torture_assert_werr_ok(tctx, error, "Opening current user file failed"); + + error = reg_mount_hive(r2_ctx, r2_hkcu, HKEY_CURRENT_USER, NULL); + torture_assert_werr_ok(tctx, error, "Mounting hive failed"); + + error = r1_ctx->ops->get_predefined_key(r2_ctx, HKEY_LOCAL_MACHINE, &key); + torture_assert_werr_ok(tctx, error, "Opening HKEY_LOCAL_MACHINE failed"); + error = r1_ctx->ops->create_key(r2_ctx, key, "Software", NULL, NULL, &newkey); + torture_assert_werr_ok(tctx, error, "Creating HKLM\\Sofware failed"); + error = r1_ctx->ops->create_key(r2_ctx, newkey, "Microsoft", NULL, NULL, &newkey); + torture_assert_werr_ok(tctx, error, "Creating HKLM\\Software\\Microsoft failed"); + error = r1_ctx->ops->create_key(r2_ctx, newkey, "Windows", NULL, NULL, &newkey); + torture_assert_werr_ok(tctx, error, "Creating HKLM\\Software\\Microsoft\\Windows failed"); + error = r1_ctx->ops->create_key(r2_ctx, newkey, "CurrentVersion", NULL, NULL, &newkey); + torture_assert_werr_ok(tctx, error, "Creating HKLM\\..\\Windows\\CurrentVersion failed"); + error = r1_ctx->ops->create_key(r2_ctx, newkey, "Policies", NULL, NULL, &newkey); + torture_assert_werr_ok(tctx, error, "Creating HKLM\\..\\CurrentVersion\\Policies failed"); + error = r1_ctx->ops->create_key(r2_ctx, newkey, "Explorer", NULL, NULL, &newkey); + torture_assert_werr_ok(tctx, error, "Creating HKLM\\..\\Policies\\Explorer failed"); + + blob.data = (void *)talloc(r2_ctx, uint32_t); + SIVAL(blob.data, 0, 0x03ffffff); + blob.length = sizeof(uint32_t); + r1_ctx->ops->set_value(newkey, "NoDrives", REG_DWORD, blob); + + /* Set test case data */ + td->r1_ctx = r1_ctx; + td->r2_ctx = r2_ctx; + + *data = td; + + return true; +} + +static bool diff_setup_preg_tcase (struct torture_context *tctx, void **data) +{ + struct diff_tcase_data *td; + WERROR error; + + diff_setup_tcase(tctx, data); + td = *data; + + td->filename = talloc_asprintf(tctx, "%s/test.pol", td->tempdir); + error = reg_preg_diff_save(tctx, td->filename, &td->callbacks, &td->callback_data); + torture_assert_werr_ok(tctx, error, "reg_preg_diff_save"); + + return true; +} + +static bool diff_setup_dotreg_tcase (struct torture_context *tctx, void **data) +{ + struct diff_tcase_data *td; + struct smb_iconv_convenience *iconv_convenience; + WERROR error; + + diff_setup_tcase(tctx, data); + td = *data; + + iconv_convenience = smb_iconv_convenience_init(tctx, "CP850", "UTF-8", 1); + + td->filename = talloc_asprintf(tctx, "%s/test.reg", td->tempdir); + error = reg_dotreg_diff_save(tctx, td->filename, iconv_convenience, &td->callbacks, &td->callback_data); + torture_assert_werr_ok(tctx, error, "reg_dotreg_diff_save"); + + return true; +} +static bool diff_teardown_tcase (struct torture_context *tctx, void *data) +{ + /* Done is called by generate_diff itself! */ + + return true; +} struct torture_suite *torture_registry_diff(TALLOC_CTX *mem_ctx) { + struct torture_tcase *tcase; struct torture_suite *suite = torture_suite_create(mem_ctx, "DIFF"); - torture_suite_add_simple_test(suite, "test_generate_diff_key_add", - test_generate_diff_key_add); - torture_suite_add_simple_test(suite, "test_generate_diff_key_null", - test_generate_diff_key_null); - torture_suite_add_simple_test(suite, "test_diff_apply", - test_diff_apply); - torture_suite_add_simple_test(suite, "test_generate_diff", - test_generate_diff); - torture_suite_add_simple_test(suite, "test_diff_load", - test_diff_load); + + tcase = torture_suite_add_tcase(suite, "PReg"); + torture_tcase_set_fixture(tcase, diff_setup_preg_tcase, diff_teardown_tcase); + tcase_add_tests(tcase); + + tcase = torture_suite_add_tcase(suite, "dotreg"); + torture_tcase_set_fixture(tcase, diff_setup_dotreg_tcase, diff_teardown_tcase); + tcase_add_tests(tcase); + return suite; } -- cgit From 5e687d79533684949deb9bd9bc86f88eab4ae310 Mon Sep 17 00:00:00 2001 From: Wilco Baan Hofman Date: Tue, 15 Apr 2008 19:57:29 +0200 Subject: Fix PReg write support. Add tests for patch files (.REG and PReg). (This used to be commit 497977c36c621a4820be51cbcb7b78eac1e292b7) --- source4/lib/registry/patchfile.c | 23 ++++++++++- source4/lib/registry/patchfile_preg.c | 72 ++++++++++++++++++++++++++++++----- source4/lib/registry/registry.h | 1 + source4/lib/registry/tests/diff.c | 19 +++++---- 4 files changed, 97 insertions(+), 18 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index eaeef341bb..0ede3106f0 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -320,12 +320,33 @@ static WERROR reg_diff_apply_add_key(void *_ctx, const char *key_name) { struct registry_context *ctx = (struct registry_context *)_ctx; struct registry_key *tmp; + char *buf, *buf_ptr; WERROR error; + /* Recursively create the path */ + buf = talloc_strdup(ctx, key_name); + buf_ptr = buf; + + while (*buf_ptr++ != '\0' ) { + if (*buf_ptr == '\\') { + *buf_ptr = '\0'; + error = reg_key_add_abs(ctx, ctx, buf, 0, NULL, &tmp); + + if (!W_ERROR_EQUAL(error, WERR_ALREADY_EXISTS) && + !W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error adding new key '%s': %s\n", + key_name, win_errstr(error))); + return error; + } + *buf_ptr++ = '\\'; + } + } + + /* Add the key */ error = reg_key_add_abs(ctx, ctx, key_name, 0, NULL, &tmp); if (!W_ERROR_EQUAL(error, WERR_ALREADY_EXISTS) && - !W_ERROR_IS_OK(error)) { + !W_ERROR_IS_OK(error)) { DEBUG(0, ("Error adding new key '%s': %s\n", key_name, win_errstr(error))); return error; diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c index a28096517c..ea41a9e21b 100644 --- a/source4/lib/registry/patchfile_preg.c +++ b/source4/lib/registry/patchfile_preg.c @@ -23,9 +23,12 @@ #include "lib/registry/registry.h" #include "system/filesys.h" #include "param/param.h" +#include "librpc/gen_ndr/winreg.h" struct preg_data { int fd; + TALLOC_CTX *ctx; + struct smb_iconv_convenience *ic; }; static WERROR preg_read_utf16(struct smb_iconv_convenience *ic, int fd, char *c) @@ -38,25 +41,69 @@ static WERROR preg_read_utf16(struct smb_iconv_convenience *ic, int fd, char *c) push_codepoint(ic, c, v); return WERR_OK; } - -/* FIXME These functions need to be implemented */ -static WERROR reg_preg_diff_add_key(void *_data, const char *key_name) +static WERROR preg_write_utf16(struct smb_iconv_convenience *ic, int fd, const char *string) { - return WERR_NOT_SUPPORTED; + codepoint_t v; + uint16_t i; + size_t size; + + for (i = 0; i < strlen(string); i+=size) { + v = next_codepoint(ic, &string[i], &size); + if (write(fd, &v, 2) < 2) { + return WERR_GENERAL_FAILURE; + } + } + return WERR_OK; } - -static WERROR reg_preg_diff_del_key(void *_data, const char *key_name) +/* PReg does not support adding keys. */ +static WERROR reg_preg_diff_add_key(void *_data, const char *key_name) { - return WERR_NOT_SUPPORTED; + return WERR_OK; } static WERROR reg_preg_diff_set_value(void *_data, const char *key_name, const char *value_name, uint32_t value_type, DATA_BLOB value_data) { - return WERR_NOT_SUPPORTED; + struct preg_data *data = _data; + uint32_t buf; + + preg_write_utf16(data->ic, data->fd, "["); + preg_write_utf16(data->ic, data->fd, key_name); + preg_write_utf16(data->ic, data->fd, ";"); + preg_write_utf16(data->ic, data->fd, value_name); + preg_write_utf16(data->ic, data->fd, ";"); + SIVAL(&buf, 0, value_type); + write(data->fd, &buf, sizeof(uint32_t)); + preg_write_utf16(data->ic, data->fd, ";"); + SIVAL(&buf, 0, value_data.length); + write(data->fd, &buf, sizeof(uint32_t)); + preg_write_utf16(data->ic, data->fd, ";"); + write(data->fd, value_data.data, value_data.length); + preg_write_utf16(data->ic, data->fd, "]"); + + return WERR_OK; } +static WERROR reg_preg_diff_del_key(void *_data, const char *key_name) +{ + struct preg_data *data = _data; + char *parent_name; + DATA_BLOB blob; + + parent_name = talloc_strndup(data->ctx, key_name, strrchr(key_name, '\\')-key_name); + blob.data = (void *)talloc_strndup(data->ctx, key_name, + strlen(key_name)-(strrchr(key_name, '\\')-key_name)); + blob.length = strlen((char *)blob.data)+1; + + + /* FIXME: These values should be accumulated to be written at done(). */ + reg_preg_diff_set_value(_data, parent_name, "**DeleteKeys", REG_SZ, blob); + + return WERR_OK; +} + +/* FIXME These functions need to be implemented */ static WERROR reg_preg_diff_del_value(void *_data, const char *key_name, const char *value_name) { @@ -81,6 +128,7 @@ static WERROR reg_preg_diff_done(void *_data) * Save registry diff */ _PUBLIC_ WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename, + struct smb_iconv_convenience *ic, struct reg_diff_callbacks **callbacks, void **callback_data) { @@ -103,10 +151,14 @@ _PUBLIC_ WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename, } else { data->fd = STDOUT_FILENO; } + memcpy(preg_header.hdr, "PReg", 4); SIVAL(&preg_header, 4, 1); write(data->fd, (uint8_t *)&preg_header,8); + data->ctx = ctx; + data->ic = ic; + *callbacks = talloc(ctx, struct reg_diff_callbacks); (*callbacks)->add_key = reg_preg_diff_add_key; @@ -179,7 +231,8 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, *buf_ptr != ';' && buf_ptr-buf < buf_size) { buf_ptr++; } - key = talloc_asprintf(mem_ctx, "\\%s", buf); + buf[buf_ptr-buf] = '\0'; + key = talloc_strdup(mem_ctx, buf); /* Get the name */ buf_ptr = buf; @@ -187,6 +240,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, *buf_ptr != ';' && buf_ptr-buf < buf_size) { buf_ptr++; } + buf[buf_ptr-buf] = '\0'; value_name = talloc_strdup(mem_ctx, buf); /* Get the type */ diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 573379aff5..6a98a60633 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -493,6 +493,7 @@ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, struct reg_diff_callbacks **callbacks, void **callback_data); WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename, + struct smb_iconv_convenience *ic, struct reg_diff_callbacks **callbacks, void **callback_data); WERROR reg_generate_diff_key(struct registry_key *oldkey, diff --git a/source4/lib/registry/tests/diff.c b/source4/lib/registry/tests/diff.c index da62342124..4bd868ea51 100644 --- a/source4/lib/registry/tests/diff.c +++ b/source4/lib/registry/tests/diff.c @@ -24,6 +24,7 @@ #include "lib/registry/registry.h" #include "torture/torture.h" #include "librpc/gen_ndr/winreg.h" +#include "param/param.h" struct diff_tcase_data { struct registry_context *r1_ctx; @@ -56,13 +57,12 @@ static bool test_generate_diff(struct torture_context *tctx, void *tcase_data) static bool test_diff_load(struct torture_context *tctx, void *tcase_data) { struct diff_tcase_data *td = tcase_data; - struct smb_iconv_convenience *iconv_convenience; + struct smb_iconv_convenience *ic; struct reg_diff_callbacks *callbacks; void *data; WERROR error; - iconv_convenience = smb_iconv_convenience_init(tctx, "CP850", "UTF-8", 1); - + ic = lp_iconv_convenience(tctx->lp_ctx); error = reg_diff_load(td->filename, iconv_convenience, callbacks, data); torture_assert_werr_ok(tctx, error, "reg_diff_load"); @@ -244,13 +244,16 @@ static bool diff_setup_tcase(struct torture_context *tctx, void **data) static bool diff_setup_preg_tcase (struct torture_context *tctx, void **data) { struct diff_tcase_data *td; + struct smb_iconv_convenience *ic; WERROR error; diff_setup_tcase(tctx, data); td = *data; - + + ic = lp_iconv_convenience(tctx->lp_ctx); + td->filename = talloc_asprintf(tctx, "%s/test.pol", td->tempdir); - error = reg_preg_diff_save(tctx, td->filename, &td->callbacks, &td->callback_data); + error = reg_preg_diff_save(tctx, td->filename, ic, &td->callbacks, &td->callback_data); torture_assert_werr_ok(tctx, error, "reg_preg_diff_save"); return true; @@ -259,16 +262,16 @@ static bool diff_setup_preg_tcase (struct torture_context *tctx, void **data) static bool diff_setup_dotreg_tcase (struct torture_context *tctx, void **data) { struct diff_tcase_data *td; - struct smb_iconv_convenience *iconv_convenience; + struct smb_iconv_convenience *ic; WERROR error; diff_setup_tcase(tctx, data); td = *data; - iconv_convenience = smb_iconv_convenience_init(tctx, "CP850", "UTF-8", 1); + ic = lp_iconv_convenience(tctx->lp_ctx); td->filename = talloc_asprintf(tctx, "%s/test.reg", td->tempdir); - error = reg_dotreg_diff_save(tctx, td->filename, iconv_convenience, &td->callbacks, &td->callback_data); + error = reg_dotreg_diff_save(tctx, td->filename, ic, &td->callbacks, &td->callback_data); torture_assert_werr_ok(tctx, error, "reg_dotreg_diff_save"); return true; -- cgit From 439f75f522d241aa78f06572c47ff6b871289793 Mon Sep 17 00:00:00 2001 From: Wilco Baan Hofman Date: Tue, 15 Apr 2008 21:35:59 +0200 Subject: More patchfile fixes. Write support should work now. (This used to be commit cc38f2f086b92bbe65bd6e7f4e03fdf7f21ef2f6) --- source4/lib/registry/patchfile_preg.c | 27 ++++++++++++++++++++------- source4/lib/registry/tests/diff.c | 22 +++++++++++++++------- 2 files changed, 35 insertions(+), 14 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c index ea41a9e21b..c2bc8d10b3 100644 --- a/source4/lib/registry/patchfile_preg.c +++ b/source4/lib/registry/patchfile_preg.c @@ -92,27 +92,40 @@ static WERROR reg_preg_diff_del_key(void *_data, const char *key_name) DATA_BLOB blob; parent_name = talloc_strndup(data->ctx, key_name, strrchr(key_name, '\\')-key_name); - blob.data = (void *)talloc_strndup(data->ctx, key_name, + blob.data = (void *)talloc_strndup(data->ctx, key_name+(strrchr(key_name, '\\')-key_name)+1, strlen(key_name)-(strrchr(key_name, '\\')-key_name)); blob.length = strlen((char *)blob.data)+1; /* FIXME: These values should be accumulated to be written at done(). */ - reg_preg_diff_set_value(_data, parent_name, "**DeleteKeys", REG_SZ, blob); - - return WERR_OK; + return reg_preg_diff_set_value(data, parent_name, "**DeleteKeys", REG_SZ, blob); } -/* FIXME These functions need to be implemented */ static WERROR reg_preg_diff_del_value(void *_data, const char *key_name, const char *value_name) { - return WERR_NOT_SUPPORTED; + struct preg_data *data = _data; + char *val; + DATA_BLOB blob; + + val = talloc_asprintf(data->ctx, "**Del.%s", value_name); + + blob.data = (void *)talloc(data->ctx, uint32_t); + *(uint32_t *)blob.data = 0; + blob.length = 4; + return reg_preg_diff_set_value(data, key_name, val, REG_DWORD, blob); } static WERROR reg_preg_diff_del_all_values(void *_data, const char *key_name) { - return WERR_NOT_SUPPORTED; + struct preg_data *data = _data; + DATA_BLOB blob; + + blob.data = (void *)talloc(data->ctx, uint32_t); + *(uint32_t *)blob.data = 0; + blob.length = 4; + + return reg_preg_diff_set_value(data, key_name, "**DelVals.", REG_DWORD, blob); } static WERROR reg_preg_diff_done(void *_data) diff --git a/source4/lib/registry/tests/diff.c b/source4/lib/registry/tests/diff.c index 4bd868ea51..492f4de0b5 100644 --- a/source4/lib/registry/tests/diff.c +++ b/source4/lib/registry/tests/diff.c @@ -211,21 +211,29 @@ static bool diff_setup_tcase(struct torture_context *tctx, void **data) error = reg_mount_hive(r2_ctx, r2_hkcu, HKEY_CURRENT_USER, NULL); torture_assert_werr_ok(tctx, error, "Mounting hive failed"); - error = r1_ctx->ops->get_predefined_key(r2_ctx, HKEY_LOCAL_MACHINE, &key); + error = r1_ctx->ops->get_predefined_key(r1_ctx, HKEY_CURRENT_USER, &key); + torture_assert_werr_ok(tctx, error, "Opening HKEY_CURRENT_USER failed"); + error = r1_ctx->ops->create_key(r1_ctx, key, "Network", NULL, NULL, &newkey); + torture_assert_werr_ok(tctx, error, "Opening HKCU\\Network failed"); + error = r1_ctx->ops->create_key(r1_ctx, newkey, "L", NULL, NULL, &newkey); + torture_assert_werr_ok(tctx, error, "Opening HKCU\\Network\\L failed"); + + error = r2_ctx->ops->get_predefined_key(r2_ctx, HKEY_LOCAL_MACHINE, &key); torture_assert_werr_ok(tctx, error, "Opening HKEY_LOCAL_MACHINE failed"); - error = r1_ctx->ops->create_key(r2_ctx, key, "Software", NULL, NULL, &newkey); + error = r2_ctx->ops->create_key(r2_ctx, key, "Software", NULL, NULL, &newkey); torture_assert_werr_ok(tctx, error, "Creating HKLM\\Sofware failed"); - error = r1_ctx->ops->create_key(r2_ctx, newkey, "Microsoft", NULL, NULL, &newkey); + error = r2_ctx->ops->create_key(r2_ctx, newkey, "Microsoft", NULL, NULL, &newkey); torture_assert_werr_ok(tctx, error, "Creating HKLM\\Software\\Microsoft failed"); - error = r1_ctx->ops->create_key(r2_ctx, newkey, "Windows", NULL, NULL, &newkey); + error = r2_ctx->ops->create_key(r2_ctx, newkey, "Windows", NULL, NULL, &newkey); torture_assert_werr_ok(tctx, error, "Creating HKLM\\Software\\Microsoft\\Windows failed"); - error = r1_ctx->ops->create_key(r2_ctx, newkey, "CurrentVersion", NULL, NULL, &newkey); + error = r2_ctx->ops->create_key(r2_ctx, newkey, "CurrentVersion", NULL, NULL, &newkey); torture_assert_werr_ok(tctx, error, "Creating HKLM\\..\\Windows\\CurrentVersion failed"); - error = r1_ctx->ops->create_key(r2_ctx, newkey, "Policies", NULL, NULL, &newkey); + error = r2_ctx->ops->create_key(r2_ctx, newkey, "Policies", NULL, NULL, &newkey); torture_assert_werr_ok(tctx, error, "Creating HKLM\\..\\CurrentVersion\\Policies failed"); - error = r1_ctx->ops->create_key(r2_ctx, newkey, "Explorer", NULL, NULL, &newkey); + error = r2_ctx->ops->create_key(r2_ctx, newkey, "Explorer", NULL, NULL, &newkey); torture_assert_werr_ok(tctx, error, "Creating HKLM\\..\\Policies\\Explorer failed"); + blob.data = (void *)talloc(r2_ctx, uint32_t); SIVAL(blob.data, 0, 0x03ffffff); blob.length = sizeof(uint32_t); -- cgit From f01c377bc039b776ded213f455cdb79d682ae7b2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Apr 2008 22:08:31 +0200 Subject: Fix formatting, remove unused function. (This used to be commit 6ec206ba58777395b2d1251680b21648f4c0f78e) --- source4/lib/registry/tests/diff.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/diff.c b/source4/lib/registry/tests/diff.c index 492f4de0b5..c7726545f6 100644 --- a/source4/lib/registry/tests/diff.c +++ b/source4/lib/registry/tests/diff.c @@ -37,11 +37,6 @@ struct diff_tcase_data { static bool test_generate_diff(struct torture_context *tctx, void *tcase_data) { - /* WERROR reg_generate_diff(struct registry_context *ctx1, - struct registry_context *ctx2, - const struct reg_diff_callbacks *callbacks, - void *callback_data) - */ WERROR error; struct diff_tcase_data *td = tcase_data; @@ -97,8 +92,6 @@ static bool test_diff_apply(struct torture_context *tctx, void *tcase_data) error = td->r1_ctx->ops->open_key(td->r1_ctx, key, "Explorer", &key); torture_assert_werr_ok(tctx, error, "Opening HKLM\\..\\Policies\\Explorer failed"); - - return true; } @@ -141,6 +134,7 @@ static bool test_generate_diff_key_null(struct torture_context *tctx, void *tcas return true; } + static void tcase_add_tests (struct torture_tcase *tcase) { torture_tcase_add_simple_test(tcase, "test_generate_diff_key_add", @@ -284,23 +278,18 @@ static bool diff_setup_dotreg_tcase (struct torture_context *tctx, void **data) return true; } -static bool diff_teardown_tcase (struct torture_context *tctx, void *data) -{ - /* Done is called by generate_diff itself! */ - return true; -} struct torture_suite *torture_registry_diff(TALLOC_CTX *mem_ctx) { struct torture_tcase *tcase; struct torture_suite *suite = torture_suite_create(mem_ctx, "DIFF"); tcase = torture_suite_add_tcase(suite, "PReg"); - torture_tcase_set_fixture(tcase, diff_setup_preg_tcase, diff_teardown_tcase); + torture_tcase_set_fixture(tcase, diff_setup_preg_tcase, NULL); tcase_add_tests(tcase); tcase = torture_suite_add_tcase(suite, "dotreg"); - torture_tcase_set_fixture(tcase, diff_setup_dotreg_tcase, diff_teardown_tcase); + torture_tcase_set_fixture(tcase, diff_setup_dotreg_tcase, NULL); tcase_add_tests(tcase); return suite; -- cgit From fd01b27edd5a83306f4ce567e31d43641dd003b8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Apr 2008 22:19:05 +0200 Subject: Fix const. (This used to be commit b74fc23825a54eb101b413ee76b21ee605dfb16c) --- source4/lib/registry/interface.c | 2 +- source4/lib/registry/patchfile_preg.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/interface.c b/source4/lib/registry/interface.c index 06b002859d..0678af5237 100644 --- a/source4/lib/registry/interface.c +++ b/source4/lib/registry/interface.c @@ -284,7 +284,7 @@ _PUBLIC_ WERROR reg_key_flush(struct registry_key *key) } _PUBLIC_ WERROR reg_set_sec_desc(struct registry_key *key, - struct security_descriptor *security) + const struct security_descriptor *security) { if (key == NULL) return WERR_INVALID_PARAM; diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c index c2bc8d10b3..bb46495c19 100644 --- a/source4/lib/registry/patchfile_preg.c +++ b/source4/lib/registry/patchfile_preg.c @@ -165,7 +165,7 @@ _PUBLIC_ WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename, data->fd = STDOUT_FILENO; } - memcpy(preg_header.hdr, "PReg", 4); + strncpy(preg_header.hdr, "PReg", 4); SIVAL(&preg_header, 4, 1); write(data->fd, (uint8_t *)&preg_header,8); -- cgit From 2ef07ad551d398c39a595494aaa083a932ef79aa Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 16 Apr 2008 01:32:54 +0200 Subject: Remove unused arguments from reg_open_local(). (This used to be commit fee7ea7080ec40182efc6ffe57b267444eb9389a) --- source4/lib/registry/local.c | 9 +-- source4/lib/registry/registry.h | 4 +- source4/lib/registry/registry.i | 4 +- source4/lib/registry/registry.py | 2 +- source4/lib/registry/registry_wrap.c | 107 +++++++++++++++++----------------- source4/lib/registry/samba.c | 2 +- source4/lib/registry/tests/registry.c | 2 +- source4/lib/registry/tools/common.c | 2 +- source4/lib/registry/tools/regdiff.c | 2 +- 9 files changed, 63 insertions(+), 71 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index 5bf2d86588..903bbb0b80 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -37,9 +37,6 @@ struct registry_local { struct hive_key *key; struct mountpoint *prev, *next; } *mountpoints; - - struct auth_session_info *session_info; - struct cli_credentials *credentials; }; struct local_key { @@ -294,9 +291,7 @@ const static struct registry_operations local_ops = { .get_key_info = local_get_key_info, }; -WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials) +WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx) { struct registry_local *ret = talloc_zero(mem_ctx, struct registry_local); @@ -304,8 +299,6 @@ WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx, W_ERROR_HAVE_NO_MEMORY(ret); ret->ops = &local_ops; - ret->session_info = session_info; - ret->credentials = credentials; *ctx = (struct registry_context *)ret; diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index a86294bf46..d4c4a89c20 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -355,9 +355,7 @@ struct loadparm_context; * Open the locally defined registry. */ WERROR reg_open_local(TALLOC_CTX *mem_ctx, - struct registry_context **ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials); + struct registry_context **ctx); WERROR reg_open_samba(TALLOC_CTX *mem_ctx, struct registry_context **ctx, diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i index 8ab402d57d..1b3c1c281a 100644 --- a/source4/lib/registry/registry.i +++ b/source4/lib/registry/registry.i @@ -57,9 +57,7 @@ const char *str_regtype(int type); } %rename(Registry) reg_open_local; -WERROR reg_open_local(TALLOC_CTX *parent_ctx, struct registry_context **ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials); +WERROR reg_open_local(TALLOC_CTX *parent_ctx, struct registry_context **ctx); %typemap(in,noblock=1) const char ** { /* Check if is a list */ diff --git a/source4/lib/registry/registry.py b/source4/lib/registry/registry.py index bf8ac60498..9dab309f33 100644 --- a/source4/lib/registry/registry.py +++ b/source4/lib/registry/registry.py @@ -1,5 +1,5 @@ # This file was automatically generated by SWIG (http://www.swig.org). -# Version 1.3.33 +# Version 1.3.35 # # Don't modify this file, modify the SWIG interface instead. diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index da09ecbe08..4879b2e144 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -1,6 +1,6 @@ /* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). - * Version 1.3.33 + * Version 1.3.35 * * This file is not intended to be easily readable and contains a number of * coding conventions designed to improve portability and efficiency. Do not make @@ -126,7 +126,7 @@ /* This should only be incremented when either the layout of swig_type_info changes, or for whatever reason, the runtime changes incompatibly */ -#define SWIG_RUNTIME_VERSION "3" +#define SWIG_RUNTIME_VERSION "4" /* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ #ifdef SWIG_TYPE_TABLE @@ -161,6 +161,7 @@ /* Flags for pointer conversions */ #define SWIG_POINTER_DISOWN 0x1 +#define SWIG_CAST_NEW_MEMORY 0x2 /* Flags for new pointer objects */ #define SWIG_POINTER_OWN 0x1 @@ -301,10 +302,10 @@ SWIGINTERNINLINE int SWIG_CheckState(int r) { extern "C" { #endif -typedef void *(*swig_converter_func)(void *); +typedef void *(*swig_converter_func)(void *, int *); typedef struct swig_type_info *(*swig_dycast_func)(void **); -/* Structure to store inforomation on one type */ +/* Structure to store information on one type */ typedef struct swig_type_info { const char *name; /* mangled name of this type */ const char *str; /* human readable name of this type */ @@ -431,8 +432,8 @@ SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { Cast a pointer up an inheritance hierarchy */ SWIGRUNTIMEINLINE void * -SWIG_TypeCast(swig_cast_info *ty, void *ptr) { - return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr); +SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); } /* @@ -856,7 +857,7 @@ SWIG_Python_AddErrorMsg(const char* mesg) Py_DECREF(old_str); Py_DECREF(value); } else { - PyErr_Format(PyExc_RuntimeError, mesg); + PyErr_SetString(PyExc_RuntimeError, mesg); } } @@ -1416,7 +1417,7 @@ PySwigObject_dealloc(PyObject *v) { PySwigObject *sobj = (PySwigObject *) v; PyObject *next = sobj->next; - if (sobj->own) { + if (sobj->own == SWIG_POINTER_OWN) { swig_type_info *ty = sobj->ty; PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; PyObject *destroy = data ? data->destroy : 0; @@ -1434,12 +1435,13 @@ PySwigObject_dealloc(PyObject *v) res = ((*meth)(mself, v)); } Py_XDECREF(res); - } else { - const char *name = SWIG_TypePrettyName(ty); + } #if !defined(SWIG_PYTHON_SILENT_MEMLEAK) - printf("swig/python detected a memory leak of type '%s', no destructor found.\n", name); -#endif + else { + const char *name = SWIG_TypePrettyName(ty); + printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown")); } +#endif } Py_XDECREF(next); PyObject_DEL(v); @@ -1944,7 +1946,7 @@ SWIG_Python_GetSwigThis(PyObject *pyobj) SWIGRUNTIME int SWIG_Python_AcquirePtr(PyObject *obj, int own) { - if (own) { + if (own == SWIG_POINTER_OWN) { PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); if (sobj) { int oldown = sobj->own; @@ -1965,6 +1967,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int return SWIG_OK; } else { PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + if (own) + *own = 0; while (sobj) { void *vptr = sobj->ptr; if (ty) { @@ -1978,7 +1982,15 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int if (!tc) { sobj = (PySwigObject *)sobj->next; } else { - if (ptr) *ptr = SWIG_TypeCast(tc,vptr); + if (ptr) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + if (newmemory == SWIG_CAST_NEW_MEMORY) { + assert(own); + if (own) + *own = *own | SWIG_CAST_NEW_MEMORY; + } + } break; } } @@ -1988,7 +2000,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int } } if (sobj) { - if (own) *own = sobj->own; + if (own) + *own = *own | sobj->own; if (flags & SWIG_POINTER_DISOWN) { sobj->own = 0; } @@ -2053,8 +2066,13 @@ SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { } if (ty) { swig_cast_info *tc = SWIG_TypeCheck(desc,ty); - if (!tc) return SWIG_ERROR; - *ptr = SWIG_TypeCast(tc,vptr); + if (tc) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + assert(!newmemory); /* newmemory handling not yet implemented */ + } else { + return SWIG_ERROR; + } } else { *ptr = vptr; } @@ -2514,7 +2532,7 @@ static swig_module_info swig_module = {swig_types, 25, 0, 0, 0, 0}; #define SWIG_name "_registry" -#define SWIGVERSION 0x010333 +#define SWIGVERSION 0x010335 #define SWIG_VERSION SWIGVERSION @@ -2910,44 +2928,17 @@ fail: } -SWIGINTERN PyObject *_wrap_Registry(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { +SWIGINTERN PyObject *_wrap_Registry(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; struct registry_context **arg2 = (struct registry_context **) 0 ; - struct auth_session_info *arg3 = (struct auth_session_info *) 0 ; - struct cli_credentials *arg4 = (struct cli_credentials *) 0 ; WERROR result; struct registry_context *tmp2 ; - void *argp3 = 0 ; - int res3 = 0 ; - void *argp4 = 0 ; - int res4 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "session_info",(char *) "credentials", NULL - }; - arg3 = NULL; - arg4 = NULL; arg1 = NULL; arg2 = &tmp2; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|OO:Registry",kwnames,&obj0,&obj1)) SWIG_fail; - if (obj0) { - res3 = SWIG_ConvertPtr(obj0, &argp3,SWIGTYPE_p_auth_session_info, 0 | 0 ); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "Registry" "', argument " "3"" of type '" "struct auth_session_info *""'"); - } - arg3 = (struct auth_session_info *)(argp3); - } - if (obj1) { - res4 = SWIG_ConvertPtr(obj1, &argp4,SWIGTYPE_p_cli_credentials, 0 | 0 ); - if (!SWIG_IsOK(res4)) { - SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "Registry" "', argument " "4"" of type '" "struct cli_credentials *""'"); - } - arg4 = (struct cli_credentials *)(argp4); - } - result = reg_open_local(arg1,arg2,arg3,arg4); + if (!SWIG_Python_UnpackTuple(args,"Registry",0,0,0)) SWIG_fail; + result = reg_open_local(arg1,arg2); if (!W_ERROR_IS_OK(result)) { PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); @@ -3410,7 +3401,10 @@ check_1: } fail: - SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'reg_mount_hive'.\n Possible C/C++ prototypes are:\n"" mount_hive(reg *,struct hive_key *,uint32_t,char const **)\n"" mount_hive(reg *,struct hive_key *,char const *)\n"); + SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'reg_mount_hive'.\n" + " Possible C/C++ prototypes are:\n" + " mount_hive(reg *,struct hive_key *,uint32_t,char const **)\n" + " mount_hive(reg *,struct hive_key *,char const *)\n"); return NULL; } @@ -3420,7 +3414,7 @@ SWIGINTERN PyObject *_wrap_new_reg(PyObject *SWIGUNUSEDPARM(self), PyObject *arg reg *result = 0 ; if (!SWIG_Python_UnpackTuple(args,"new_reg",0,0,0)) SWIG_fail; - result = (reg *)(reg *) calloc(1, sizeof(reg)); + result = (reg *)calloc(1, sizeof(reg)); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_registry_context, SWIG_POINTER_NEW | 0 ); return resultobj; fail: @@ -3765,7 +3759,7 @@ fail: static PyMethodDef SwigMethods[] = { { (char *)"reg_get_predef_name", (PyCFunction) _wrap_reg_get_predef_name, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"str_regtype", (PyCFunction) _wrap_str_regtype, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"Registry", (PyCFunction) _wrap_Registry, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"Registry", (PyCFunction)_wrap_Registry, METH_NOARGS, NULL}, { (char *)"reg_get_predefined_key_by_name", (PyCFunction) _wrap_reg_get_predefined_key_by_name, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"reg_key_del_abs", (PyCFunction) _wrap_reg_key_del_abs, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"reg_get_predefined_key", (PyCFunction) _wrap_reg_get_predefined_key, METH_VARARGS | METH_KEYWORDS, NULL}, @@ -3962,7 +3956,7 @@ SWIGRUNTIME void SWIG_InitializeModule(void *clientdata) { size_t i; swig_module_info *module_head, *iter; - int found; + int found, init; clientdata = clientdata; @@ -3972,6 +3966,9 @@ SWIG_InitializeModule(void *clientdata) { swig_module.type_initial = swig_type_initial; swig_module.cast_initial = swig_cast_initial; swig_module.next = &swig_module; + init = 1; + } else { + init = 0; } /* Try and load any already created modules */ @@ -4000,6 +3997,12 @@ SWIG_InitializeModule(void *clientdata) { module_head->next = &swig_module; } + /* When multiple interpeters are used, a module could have already been initialized in + a different interpreter, but not yet have a pointer in this interpreter. + In this case, we do not want to continue adding types... everything should be + set up already */ + if (init == 0) return; + /* Now work on filling in swig_module.types */ #ifdef SWIGRUNTIME_DEBUG printf("SWIG_InitializeModule: size %d\n", swig_module.size); diff --git a/source4/lib/registry/samba.c b/source4/lib/registry/samba.c index 599385e73c..59693dde8e 100644 --- a/source4/lib/registry/samba.c +++ b/source4/lib/registry/samba.c @@ -61,7 +61,7 @@ _PUBLIC_ WERROR reg_open_samba(TALLOC_CTX *mem_ctx, { WERROR result; - result = reg_open_local(mem_ctx, ctx, session_info, credentials); + result = reg_open_local(mem_ctx, ctx); if (!W_ERROR_IS_OK(result)) { return result; } diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index b19a6abffb..33512a0c8c 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -517,7 +517,7 @@ static bool setup_local_registry(struct torture_context *tctx, void **data) struct hive_key *hive_key; const char *filename; - error = reg_open_local(tctx, &rctx, NULL, NULL); + error = reg_open_local(tctx, &rctx); torture_assert_werr_ok(tctx, error, "Opening local registry failed"); status = torture_temp_dir(tctx, "registry-local", &tempdir); diff --git a/source4/lib/registry/tools/common.c b/source4/lib/registry/tools/common.c index cec0f8b906..52f3c6f551 100644 --- a/source4/lib/registry/tools/common.c +++ b/source4/lib/registry/tools/common.c @@ -57,7 +57,7 @@ struct registry_key *reg_common_open_file(const char *path, return NULL; } - error = reg_open_local(NULL, &h, NULL, creds); + error = reg_open_local(NULL, &h); if (!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to initialize local registry: %s\n", win_errstr(error)); diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index c94380efd2..69fcfc2493 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -48,7 +48,7 @@ static struct registry_context *open_backend(poptContext pc, remote_host, NULL); break; case REG_NULL: - error = reg_open_local(NULL, &ctx, NULL, cmdline_credentials); + error = reg_open_local(NULL, &ctx); break; } -- cgit From 21fc7673780aa1d7c0caab7b17ff9171238913ba Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 17 Apr 2008 12:23:44 +0200 Subject: Specify event_context to ldb_wrap_connect explicitly. (This used to be commit b4e1ae07a284c044704322446c94351c2decff91) --- source4/lib/registry/hive.c | 3 +- source4/lib/registry/ldb.c | 3 +- source4/lib/registry/registry.h | 4 + source4/lib/registry/registry.i | 5 + source4/lib/registry/registry.py | 1 + source4/lib/registry/registry_wrap.c | 170 +++++++++++++++++++++------------- source4/lib/registry/samba.c | 14 +-- source4/lib/registry/tests/hive.c | 2 +- source4/lib/registry/tests/registry.c | 2 +- source4/lib/registry/tools/common.c | 9 +- source4/lib/registry/tools/regdiff.c | 10 +- source4/lib/registry/tools/regpatch.c | 6 +- source4/lib/registry/tools/regshell.c | 7 +- source4/lib/registry/tools/regtree.c | 7 +- 14 files changed, 158 insertions(+), 85 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/hive.c b/source4/lib/registry/hive.c index 2a9b1a59ce..4a2309faee 100644 --- a/source4/lib/registry/hive.c +++ b/source4/lib/registry/hive.c @@ -28,6 +28,7 @@ _PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, + struct event_context *ev_ctx, struct loadparm_context *lp_ctx, struct hive_key **root) { @@ -57,7 +58,7 @@ _PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, } else if (!strncmp(peek, "TDB file", 8)) { close(fd); return reg_open_ldb_file(parent_ctx, location, session_info, - credentials, lp_ctx, root); + credentials, ev_ctx, lp_ctx, root); } return WERR_BADFILE; diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index a764ca6235..a8a9ed597e 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -357,6 +357,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, + struct event_context *ev_ctx, struct loadparm_context *lp_ctx, struct hive_key **k) { @@ -367,7 +368,7 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, if (location == NULL) return WERR_INVALID_PARAM; - wrap = ldb_wrap_connect(parent_ctx, lp_ctx, + wrap = ldb_wrap_connect(parent_ctx, ev_ctx, lp_ctx, location, session_info, credentials, 0, NULL); if (wrap == NULL) { diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index d4c4a89c20..9c0f66b6d6 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -149,10 +149,12 @@ struct hive_operations { struct cli_credentials; struct auth_session_info; +struct event_context; WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, + struct event_context *ev_ctx, struct loadparm_context *lp_ctx, struct hive_key **root); WERROR hive_key_get_info(TALLOC_CTX *mem_ctx, const struct hive_key *key, @@ -199,6 +201,7 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, + struct event_context *ev_ctx, struct loadparm_context *lp_ctx, struct hive_key **k); @@ -359,6 +362,7 @@ WERROR reg_open_local(TALLOC_CTX *mem_ctx, WERROR reg_open_samba(TALLOC_CTX *mem_ctx, struct registry_context **ctx, + struct event_context *ev_ctx, struct loadparm_context *lp_ctx, struct auth_session_info *session_info, struct cli_credentials *credentials); diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i index 1b3c1c281a..5ffee4bb3d 100644 --- a/source4/lib/registry/registry.i +++ b/source4/lib/registry/registry.i @@ -26,6 +26,7 @@ #include "includes.h" #include "registry.h" #include "param/param.h" +#include "events/events.h" typedef struct registry_context reg; typedef struct hive_key hive_key; @@ -41,6 +42,7 @@ typedef struct hive_key hive_key; %import "../../auth/credentials/credentials.i" %import "../../libcli/util/errors.i" %import "../../param/param.i" +%import "../events/events.i" /* Utility functions */ @@ -132,6 +134,7 @@ typedef struct registry_context { WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, + struct event_context *ev_ctx, struct loadparm_context *lp_ctx, struct hive_key **root); @@ -139,6 +142,7 @@ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, struct cli_credentials *credentials, + struct event_context *ev_ctx, struct loadparm_context *lp_ctx, struct hive_key **k); @@ -165,6 +169,7 @@ typedef struct hive_key { WERROR reg_open_samba(TALLOC_CTX *mem_ctx, struct registry_context **ctx, + struct event_context *ev_ctx, struct loadparm_context *lp_ctx, struct auth_session_info *session_info, struct cli_credentials *credentials); diff --git a/source4/lib/registry/registry.py b/source4/lib/registry/registry.py index 9dab309f33..cb20d6039d 100644 --- a/source4/lib/registry/registry.py +++ b/source4/lib/registry/registry.py @@ -59,6 +59,7 @@ def _swig_setattr_nondynamic_method(set): import credentials import param +import events reg_get_predef_name = _registry.reg_get_predef_name str_regtype = _registry.str_regtype Registry = _registry.Registry diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index 4879b2e144..d9b85ee937 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -2478,29 +2478,30 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) #define SWIGTYPE_p_auth_session_info swig_types[1] #define SWIGTYPE_p_char swig_types[2] #define SWIGTYPE_p_cli_credentials swig_types[3] -#define SWIGTYPE_p_hive_key swig_types[4] -#define SWIGTYPE_p_int swig_types[5] -#define SWIGTYPE_p_loadparm_context swig_types[6] -#define SWIGTYPE_p_loadparm_service swig_types[7] -#define SWIGTYPE_p_long_long swig_types[8] -#define SWIGTYPE_p_p_char swig_types[9] -#define SWIGTYPE_p_p_hive_key swig_types[10] -#define SWIGTYPE_p_p_registry_context swig_types[11] -#define SWIGTYPE_p_p_registry_key swig_types[12] -#define SWIGTYPE_p_param_context swig_types[13] -#define SWIGTYPE_p_param_opt swig_types[14] -#define SWIGTYPE_p_param_section swig_types[15] -#define SWIGTYPE_p_reg_diff_callbacks swig_types[16] -#define SWIGTYPE_p_registry_context swig_types[17] -#define SWIGTYPE_p_registry_key swig_types[18] -#define SWIGTYPE_p_short swig_types[19] -#define SWIGTYPE_p_signed_char swig_types[20] -#define SWIGTYPE_p_unsigned_char swig_types[21] -#define SWIGTYPE_p_unsigned_int swig_types[22] -#define SWIGTYPE_p_unsigned_long_long swig_types[23] -#define SWIGTYPE_p_unsigned_short swig_types[24] -static swig_type_info *swig_types[26]; -static swig_module_info swig_module = {swig_types, 25, 0, 0, 0, 0}; +#define SWIGTYPE_p_event_context swig_types[4] +#define SWIGTYPE_p_hive_key swig_types[5] +#define SWIGTYPE_p_int swig_types[6] +#define SWIGTYPE_p_loadparm_context swig_types[7] +#define SWIGTYPE_p_loadparm_service swig_types[8] +#define SWIGTYPE_p_long_long swig_types[9] +#define SWIGTYPE_p_p_char swig_types[10] +#define SWIGTYPE_p_p_hive_key swig_types[11] +#define SWIGTYPE_p_p_registry_context swig_types[12] +#define SWIGTYPE_p_p_registry_key swig_types[13] +#define SWIGTYPE_p_param_context swig_types[14] +#define SWIGTYPE_p_param_opt swig_types[15] +#define SWIGTYPE_p_param_section swig_types[16] +#define SWIGTYPE_p_reg_diff_callbacks swig_types[17] +#define SWIGTYPE_p_registry_context swig_types[18] +#define SWIGTYPE_p_registry_key swig_types[19] +#define SWIGTYPE_p_short swig_types[20] +#define SWIGTYPE_p_signed_char swig_types[21] +#define SWIGTYPE_p_unsigned_char swig_types[22] +#define SWIGTYPE_p_unsigned_int swig_types[23] +#define SWIGTYPE_p_unsigned_long_long swig_types[24] +#define SWIGTYPE_p_unsigned_short swig_types[25] +static swig_type_info *swig_types[27]; +static swig_module_info swig_module = {swig_types, 26, 0, 0, 0, 0}; #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) @@ -2547,6 +2548,7 @@ static swig_module_info swig_module = {swig_types, 25, 0, 0, 0, 0}; #include "includes.h" #include "registry.h" #include "param/param.h" +#include "events/events.h" typedef struct registry_context reg; typedef struct hive_key hive_key; @@ -3462,8 +3464,9 @@ SWIGINTERN PyObject *_wrap_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *ar char *arg2 = (char *) 0 ; struct auth_session_info *arg3 = (struct auth_session_info *) 0 ; struct cli_credentials *arg4 = (struct cli_credentials *) 0 ; - struct loadparm_context *arg5 = (struct loadparm_context *) 0 ; - struct hive_key **arg6 = (struct hive_key **) 0 ; + struct event_context *arg5 = (struct event_context *) 0 ; + struct loadparm_context *arg6 = (struct loadparm_context *) 0 ; + struct hive_key **arg7 = (struct hive_key **) 0 ; WERROR result; int res2 ; char *buf2 = 0 ; @@ -3474,21 +3477,25 @@ SWIGINTERN PyObject *_wrap_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *ar int res4 = 0 ; void *argp5 = 0 ; int res5 = 0 ; - struct hive_key *tmp6 ; + void *argp6 = 0 ; + int res6 = 0 ; + struct hive_key *tmp7 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; PyObject * obj3 = 0 ; + PyObject * obj4 = 0 ; char * kwnames[] = { - (char *) "location",(char *) "session_info",(char *) "credentials",(char *) "lp_ctx", NULL + (char *) "location",(char *) "session_info",(char *) "credentials",(char *) "ev_ctx",(char *) "lp_ctx", NULL }; arg3 = NULL; arg4 = NULL; - arg5 = loadparm_init(NULL); + arg5 = event_context_init(NULL); + arg6 = loadparm_init(NULL); arg1 = NULL; - arg6 = &tmp6; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OOO:hive_key",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; + arg7 = &tmp7; + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OOOO:hive_key",kwnames,&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail; res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); if (!SWIG_IsOK(res2)) { SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "hive_key" "', argument " "2"" of type '" "char const *""'"); @@ -3509,13 +3516,20 @@ SWIGINTERN PyObject *_wrap_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *ar arg4 = (struct cli_credentials *)(argp4); } if (obj3) { - res5 = SWIG_ConvertPtr(obj3, &argp5,SWIGTYPE_p_loadparm_context, 0 | 0 ); + res5 = SWIG_ConvertPtr(obj3, &argp5,SWIGTYPE_p_event_context, 0 | 0 ); if (!SWIG_IsOK(res5)) { - SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "hive_key" "', argument " "5"" of type '" "struct loadparm_context *""'"); + SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "hive_key" "', argument " "5"" of type '" "struct event_context *""'"); } - arg5 = (struct loadparm_context *)(argp5); + arg5 = (struct event_context *)(argp5); } - result = reg_open_hive(arg1,(char const *)arg2,arg3,arg4,arg5,arg6); + if (obj4) { + res6 = SWIG_ConvertPtr(obj4, &argp6,SWIGTYPE_p_loadparm_context, 0 | 0 ); + if (!SWIG_IsOK(res6)) { + SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "hive_key" "', argument " "6"" of type '" "struct loadparm_context *""'"); + } + arg6 = (struct loadparm_context *)(argp6); + } + result = reg_open_hive(arg1,(char const *)arg2,arg3,arg4,arg5,arg6,arg7); if (!W_ERROR_IS_OK(result)) { PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); @@ -3524,7 +3538,7 @@ SWIGINTERN PyObject *_wrap_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *ar resultobj = Py_None; } Py_XDECREF(resultobj); - resultobj = SWIG_NewPointerObj(*arg6, SWIGTYPE_p_hive_key, 0); + resultobj = SWIG_NewPointerObj(*arg7, SWIGTYPE_p_hive_key, 0); if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); return resultobj; fail: @@ -3539,8 +3553,9 @@ SWIGINTERN PyObject *_wrap_open_ldb(PyObject *SWIGUNUSEDPARM(self), PyObject *ar char *arg2 = (char *) 0 ; struct auth_session_info *arg3 = (struct auth_session_info *) 0 ; struct cli_credentials *arg4 = (struct cli_credentials *) 0 ; - struct loadparm_context *arg5 = (struct loadparm_context *) 0 ; - struct hive_key **arg6 = (struct hive_key **) 0 ; + struct event_context *arg5 = (struct event_context *) 0 ; + struct loadparm_context *arg6 = (struct loadparm_context *) 0 ; + struct hive_key **arg7 = (struct hive_key **) 0 ; WERROR result; int res2 ; char *buf2 = 0 ; @@ -3551,21 +3566,25 @@ SWIGINTERN PyObject *_wrap_open_ldb(PyObject *SWIGUNUSEDPARM(self), PyObject *ar int res4 = 0 ; void *argp5 = 0 ; int res5 = 0 ; - struct hive_key *tmp6 ; + void *argp6 = 0 ; + int res6 = 0 ; + struct hive_key *tmp7 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; PyObject * obj3 = 0 ; + PyObject * obj4 = 0 ; char * kwnames[] = { - (char *) "location",(char *) "session_info",(char *) "credentials",(char *) "lp_ctx", NULL + (char *) "location",(char *) "session_info",(char *) "credentials",(char *) "ev_ctx",(char *) "lp_ctx", NULL }; arg3 = NULL; arg4 = NULL; - arg5 = loadparm_init(NULL); + arg5 = event_context_init(NULL); + arg6 = loadparm_init(NULL); arg1 = NULL; - arg6 = &tmp6; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OOO:open_ldb",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; + arg7 = &tmp7; + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OOOO:open_ldb",kwnames,&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail; res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); if (!SWIG_IsOK(res2)) { SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "open_ldb" "', argument " "2"" of type '" "char const *""'"); @@ -3586,13 +3605,20 @@ SWIGINTERN PyObject *_wrap_open_ldb(PyObject *SWIGUNUSEDPARM(self), PyObject *ar arg4 = (struct cli_credentials *)(argp4); } if (obj3) { - res5 = SWIG_ConvertPtr(obj3, &argp5,SWIGTYPE_p_loadparm_context, 0 | 0 ); + res5 = SWIG_ConvertPtr(obj3, &argp5,SWIGTYPE_p_event_context, 0 | 0 ); if (!SWIG_IsOK(res5)) { - SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "open_ldb" "', argument " "5"" of type '" "struct loadparm_context *""'"); + SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "open_ldb" "', argument " "5"" of type '" "struct event_context *""'"); } - arg5 = (struct loadparm_context *)(argp5); + arg5 = (struct event_context *)(argp5); } - result = reg_open_ldb_file(arg1,(char const *)arg2,arg3,arg4,arg5,arg6); + if (obj4) { + res6 = SWIG_ConvertPtr(obj4, &argp6,SWIGTYPE_p_loadparm_context, 0 | 0 ); + if (!SWIG_IsOK(res6)) { + SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "open_ldb" "', argument " "6"" of type '" "struct loadparm_context *""'"); + } + arg6 = (struct loadparm_context *)(argp6); + } + result = reg_open_ldb_file(arg1,(char const *)arg2,arg3,arg4,arg5,arg6,arg7); if (!W_ERROR_IS_OK(result)) { PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); @@ -3601,7 +3627,7 @@ SWIGINTERN PyObject *_wrap_open_ldb(PyObject *SWIGUNUSEDPARM(self), PyObject *ar resultobj = Py_None; } Py_XDECREF(resultobj); - resultobj = SWIG_NewPointerObj(*arg6, SWIGTYPE_p_hive_key, 0); + resultobj = SWIG_NewPointerObj(*arg7, SWIGTYPE_p_hive_key, 0); if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); return resultobj; fail: @@ -3696,9 +3722,10 @@ SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject * PyObject *resultobj = 0; TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; struct registry_context **arg2 = (struct registry_context **) 0 ; - struct loadparm_context *arg3 = (struct loadparm_context *) 0 ; - struct auth_session_info *arg4 = (struct auth_session_info *) 0 ; - struct cli_credentials *arg5 = (struct cli_credentials *) 0 ; + struct event_context *arg3 = (struct event_context *) 0 ; + struct loadparm_context *arg4 = (struct loadparm_context *) 0 ; + struct auth_session_info *arg5 = (struct auth_session_info *) 0 ; + struct cli_credentials *arg6 = (struct cli_credentials *) 0 ; WERROR result; struct registry_context *tmp2 ; void *argp3 = 0 ; @@ -3707,41 +3734,52 @@ SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject * int res4 = 0 ; void *argp5 = 0 ; int res5 = 0 ; + void *argp6 = 0 ; + int res6 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; + PyObject * obj3 = 0 ; char * kwnames[] = { - (char *) "lp_ctx",(char *) "session_info",(char *) "credentials", NULL + (char *) "ev_ctx",(char *) "lp_ctx",(char *) "session_info",(char *) "credentials", NULL }; - arg3 = loadparm_init(NULL); - arg4 = NULL; + arg3 = event_context_init(NULL); + arg4 = loadparm_init(NULL); arg5 = NULL; + arg6 = NULL; arg1 = NULL; arg2 = &tmp2; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|OOO:open_samba",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|OOOO:open_samba",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; if (obj0) { - res3 = SWIG_ConvertPtr(obj0, &argp3,SWIGTYPE_p_loadparm_context, 0 | 0 ); + res3 = SWIG_ConvertPtr(obj0, &argp3,SWIGTYPE_p_event_context, 0 | 0 ); if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "open_samba" "', argument " "3"" of type '" "struct loadparm_context *""'"); + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "open_samba" "', argument " "3"" of type '" "struct event_context *""'"); } - arg3 = (struct loadparm_context *)(argp3); + arg3 = (struct event_context *)(argp3); } if (obj1) { - res4 = SWIG_ConvertPtr(obj1, &argp4,SWIGTYPE_p_auth_session_info, 0 | 0 ); + res4 = SWIG_ConvertPtr(obj1, &argp4,SWIGTYPE_p_loadparm_context, 0 | 0 ); if (!SWIG_IsOK(res4)) { - SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "open_samba" "', argument " "4"" of type '" "struct auth_session_info *""'"); + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "open_samba" "', argument " "4"" of type '" "struct loadparm_context *""'"); } - arg4 = (struct auth_session_info *)(argp4); + arg4 = (struct loadparm_context *)(argp4); } if (obj2) { - res5 = SWIG_ConvertPtr(obj2, &argp5,SWIGTYPE_p_cli_credentials, 0 | 0 ); + res5 = SWIG_ConvertPtr(obj2, &argp5,SWIGTYPE_p_auth_session_info, 0 | 0 ); if (!SWIG_IsOK(res5)) { - SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "open_samba" "', argument " "5"" of type '" "struct cli_credentials *""'"); + SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "open_samba" "', argument " "5"" of type '" "struct auth_session_info *""'"); + } + arg5 = (struct auth_session_info *)(argp5); + } + if (obj3) { + res6 = SWIG_ConvertPtr(obj3, &argp6,SWIGTYPE_p_cli_credentials, 0 | 0 ); + if (!SWIG_IsOK(res6)) { + SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "open_samba" "', argument " "6"" of type '" "struct cli_credentials *""'"); } - arg5 = (struct cli_credentials *)(argp5); + arg6 = (struct cli_credentials *)(argp6); } - result = reg_open_samba(arg1,arg2,arg3,arg4,arg5); + result = reg_open_samba(arg1,arg2,arg3,arg4,arg5,arg6); if (!W_ERROR_IS_OK(result)) { PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); @@ -3786,6 +3824,7 @@ static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0 static swig_type_info _swigt__p_auth_session_info = {"_p_auth_session_info", "struct auth_session_info *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_cli_credentials = {"_p_cli_credentials", "struct cli_credentials *|cli_credentials *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_event_context = {"_p_event_context", "struct event_context *|event *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_hive_key = {"_p_hive_key", "struct hive_key *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_loadparm_context = {"_p_loadparm_context", "struct loadparm_context *|loadparm_context *", 0, 0, (void*)0, 0}; @@ -3813,6 +3852,7 @@ static swig_type_info *swig_type_initial[] = { &_swigt__p_auth_session_info, &_swigt__p_char, &_swigt__p_cli_credentials, + &_swigt__p_event_context, &_swigt__p_hive_key, &_swigt__p_int, &_swigt__p_loadparm_context, @@ -3840,6 +3880,7 @@ static swig_cast_info _swigc__p_TALLOC_CTX[] = { {&_swigt__p_TALLOC_CTX, 0, 0, static swig_cast_info _swigc__p_auth_session_info[] = { {&_swigt__p_auth_session_info, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_cli_credentials[] = { {&_swigt__p_cli_credentials, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_event_context[] = { {&_swigt__p_event_context, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_hive_key[] = { {&_swigt__p_hive_key, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_loadparm_context[] = { {&_swigt__p_loadparm_context, 0, 0, 0},{0, 0, 0, 0}}; @@ -3867,6 +3908,7 @@ static swig_cast_info *swig_cast_initial[] = { _swigc__p_auth_session_info, _swigc__p_char, _swigc__p_cli_credentials, + _swigc__p_event_context, _swigc__p_hive_key, _swigc__p_int, _swigc__p_loadparm_context, diff --git a/source4/lib/registry/samba.c b/source4/lib/registry/samba.c index 59693dde8e..84a8112f17 100644 --- a/source4/lib/registry/samba.c +++ b/source4/lib/registry/samba.c @@ -26,6 +26,7 @@ */ static WERROR mount_samba_hive(struct registry_context *ctx, + struct event_context *event_ctx, struct loadparm_context *lp_ctx, struct auth_session_info *auth_info, struct cli_credentials *creds, @@ -40,11 +41,11 @@ static WERROR mount_samba_hive(struct registry_context *ctx, lp_private_dir(lp_ctx), name); - error = reg_open_hive(ctx, location, auth_info, creds, lp_ctx, &hive); + error = reg_open_hive(ctx, location, auth_info, creds, event_ctx, lp_ctx, &hive); if (W_ERROR_EQUAL(error, WERR_BADFILE)) error = reg_open_ldb_file(ctx, location, auth_info, - creds, lp_ctx, &hive); + creds, event_ctx, lp_ctx, &hive); if (!W_ERROR_IS_OK(error)) return error; @@ -55,6 +56,7 @@ static WERROR mount_samba_hive(struct registry_context *ctx, _PUBLIC_ WERROR reg_open_samba(TALLOC_CTX *mem_ctx, struct registry_context **ctx, + struct event_context *ev_ctx, struct loadparm_context *lp_ctx, struct auth_session_info *session_info, struct cli_credentials *credentials) @@ -66,18 +68,18 @@ _PUBLIC_ WERROR reg_open_samba(TALLOC_CTX *mem_ctx, return result; } - mount_samba_hive(*ctx, lp_ctx, session_info, credentials, + mount_samba_hive(*ctx, ev_ctx, lp_ctx, session_info, credentials, "hklm", HKEY_LOCAL_MACHINE); - mount_samba_hive(*ctx, lp_ctx, session_info, credentials, + mount_samba_hive(*ctx, ev_ctx, lp_ctx, session_info, credentials, "hkcr", HKEY_CLASSES_ROOT); /* FIXME: Should be mounted from NTUSER.DAT in the home directory of the * current user */ - mount_samba_hive(*ctx, lp_ctx, session_info, credentials, + mount_samba_hive(*ctx, ev_ctx, lp_ctx, session_info, credentials, "hkcu", HKEY_CURRENT_USER); - mount_samba_hive(*ctx, lp_ctx, session_info, credentials, + mount_samba_hive(*ctx, ev_ctx, lp_ctx, session_info, credentials, "hku", HKEY_USERS); /* FIXME: Different hive backend for HKEY_CLASSES_ROOT: merged view of HKEY_LOCAL_MACHINE\Software\Classes diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index a16736c761..83abdd793d 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -363,7 +363,7 @@ static bool hive_setup_ldb(struct torture_context *tctx, void **data) rmdir(dirname); - error = reg_open_ldb_file(tctx, dirname, NULL, NULL, tctx->lp_ctx, &key); + error = reg_open_ldb_file(tctx, dirname, NULL, NULL, tctx->ev, tctx->lp_ctx, &key); if (!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to initialize ldb hive\n"); return false; diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 33512a0c8c..ec7873a111 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -524,7 +524,7 @@ static bool setup_local_registry(struct torture_context *tctx, void **data) torture_assert_ntstatus_ok(tctx, status, "Creating temp dir failed"); filename = talloc_asprintf(tctx, "%s/classes_root.ldb", tempdir); - error = reg_open_ldb_file(tctx, filename, NULL, NULL, tctx->lp_ctx, &hive_key); + error = reg_open_ldb_file(tctx, filename, NULL, NULL, tctx->ev, tctx->lp_ctx, &hive_key); torture_assert_werr_ok(tctx, error, "Opening classes_root file failed"); error = reg_mount_hive(rctx, hive_key, HKEY_CLASSES_ROOT, NULL); diff --git a/source4/lib/registry/tools/common.c b/source4/lib/registry/tools/common.c index 52f3c6f551..3ea780de60 100644 --- a/source4/lib/registry/tools/common.c +++ b/source4/lib/registry/tools/common.c @@ -42,6 +42,7 @@ struct registry_context *reg_common_open_remote(const char *remote, } struct registry_key *reg_common_open_file(const char *path, + struct event_context *ev_ctx, struct loadparm_context *lp_ctx, struct cli_credentials *creds) { @@ -49,7 +50,7 @@ struct registry_key *reg_common_open_file(const char *path, struct registry_context *h = NULL; WERROR error; - error = reg_open_hive(NULL, path, NULL, creds, lp_ctx, &hive_root); + error = reg_open_hive(NULL, path, NULL, creds, ev_ctx, lp_ctx, &hive_root); if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open '%s': %s \n", @@ -67,12 +68,14 @@ struct registry_key *reg_common_open_file(const char *path, return reg_import_hive_key(h, hive_root, -1, NULL); } -struct registry_context *reg_common_open_local(struct cli_credentials *creds, struct loadparm_context *lp_ctx) +struct registry_context *reg_common_open_local(struct cli_credentials *creds, + struct event_context *ev_ctx, + struct loadparm_context *lp_ctx) { WERROR error; struct registry_context *h = NULL; - error = reg_open_samba(NULL, &h, lp_ctx, NULL, creds); + error = reg_open_samba(NULL, &h, ev_ctx, lp_ctx, NULL, creds); if(!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open local registry:%s \n", diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 69fcfc2493..9b49799bed 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -29,6 +29,7 @@ enum reg_backend { REG_UNKNOWN, REG_LOCAL, REG_REMOTE, REG_NULL }; static struct registry_context *open_backend(poptContext pc, + struct event_context *ev_ctx, struct loadparm_context *lp_ctx, enum reg_backend backend, const char *remote_host) @@ -41,7 +42,7 @@ static struct registry_context *open_backend(poptContext pc, poptPrintUsage(pc, stderr, 0); return NULL; case REG_LOCAL: - error = reg_open_samba(NULL, &ctx, lp_ctx, NULL, cmdline_credentials); + error = reg_open_samba(NULL, &ctx, ev_ctx, lp_ctx, NULL, cmdline_credentials); break; case REG_REMOTE: error = reg_open_remote(&ctx, NULL, cmdline_credentials, lp_ctx, @@ -82,6 +83,7 @@ int main(int argc, const char **argv) }; TALLOC_CTX *ctx; void *callback_data; + struct event_context *ev_ctx; struct reg_diff_callbacks *callbacks; ctx = talloc_init("regdiff"); @@ -116,11 +118,13 @@ int main(int argc, const char **argv) } - h1 = open_backend(pc, cmdline_lp_ctx, backend1, remote1); + ev_ctx = event_context_init(NULL); + + h1 = open_backend(pc, ev_ctx, cmdline_lp_ctx, backend1, remote1); if (h1 == NULL) return 1; - h2 = open_backend(pc, cmdline_lp_ctx, backend2, remote2); + h2 = open_backend(pc, ev_ctx, cmdline_lp_ctx, backend2, remote2); if (h2 == NULL) return 1; diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 98443e6456..9285459d85 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -24,6 +24,7 @@ #include "lib/cmdline/popt_common.h" #include "lib/registry/tools/common.h" #include "param/param.h" +#include "events/events.h" int main(int argc, char **argv) { @@ -33,6 +34,7 @@ int main(int argc, char **argv) struct registry_context *h; const char *file = NULL; const char *remote = NULL; + struct event_context *ev; struct poptOption long_options[] = { POPT_AUTOHELP {"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL}, @@ -47,10 +49,12 @@ int main(int argc, char **argv) while((opt = poptGetNextOpt(pc)) != -1) { } + ev = event_context_init(NULL); + if (remote) { h = reg_common_open_remote (remote, cmdline_lp_ctx, cmdline_credentials); } else { - h = reg_common_open_local (cmdline_credentials, cmdline_lp_ctx); + h = reg_common_open_local (cmdline_credentials, ev, cmdline_lp_ctx); } if (h == NULL) diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 58f64cb049..80eafcc4a2 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -498,6 +498,7 @@ int main(int argc, char **argv) poptContext pc; const char *remote = NULL; struct regshell_context *ctx; + struct event_context *ev_ctx; bool ret = true; struct poptOption long_options[] = { POPT_AUTOHELP @@ -516,17 +517,19 @@ int main(int argc, char **argv) ctx = talloc_zero(NULL, struct regshell_context); + ev_ctx = event_context_init(ctx); + if (remote != NULL) { ctx->registry = reg_common_open_remote(remote, cmdline_lp_ctx, cmdline_credentials); } else if (file != NULL) { - ctx->current = reg_common_open_file(file, cmdline_lp_ctx, cmdline_credentials); + ctx->current = reg_common_open_file(file, ev_ctx, cmdline_lp_ctx, cmdline_credentials); if (ctx->current == NULL) return 1; ctx->registry = ctx->current->context; ctx->path = talloc_strdup(ctx, ""); } else { - ctx->registry = reg_common_open_local(cmdline_credentials, cmdline_lp_ctx); + ctx->registry = reg_common_open_local(cmdline_credentials, ev_ctx, cmdline_lp_ctx); } if (ctx->registry == NULL) diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 424d3515e0..440399f764 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -109,6 +109,7 @@ int main(int argc, char **argv) poptContext pc; struct registry_context *h = NULL; struct registry_key *start_key = NULL; + struct event_context *ev_ctx; WERROR error; bool fullpath = false, no_values = false; struct poptOption long_options[] = { @@ -128,12 +129,14 @@ int main(int argc, char **argv) while((opt = poptGetNextOpt(pc)) != -1) { } + ev_ctx = event_context_init(NULL); + if (remote != NULL) { h = reg_common_open_remote(remote, cmdline_lp_ctx, cmdline_credentials); } else if (file != NULL) { - start_key = reg_common_open_file(file, cmdline_lp_ctx, cmdline_credentials); + start_key = reg_common_open_file(file, ev_ctx, cmdline_lp_ctx, cmdline_credentials); } else { - h = reg_common_open_local(cmdline_credentials, cmdline_lp_ctx); + h = reg_common_open_local(cmdline_credentials, ev_ctx, cmdline_lp_ctx); } if (h == NULL && start_key == NULL) -- cgit From e739fe91cfdbb7c8a792c4bdc6c5f18603507fc6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 17 Apr 2008 15:54:22 +0200 Subject: Fix bug in registry test on big-endian machines. Andrew Bartlett (This used to be commit c74c67c38383b43efd707934e8c457b757e49db1) --- source4/lib/registry/tests/hive.c | 35 ++++++++++++++++++++++------------- source4/lib/registry/tests/registry.c | 16 ++++++++++------ 2 files changed, 32 insertions(+), 19 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index 83abdd793d..29f7e685c1 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -68,14 +68,15 @@ static bool test_keyinfo_nums(struct torture_context *tctx, void *test_data) struct hive_key *root = (struct hive_key *)test_data; WERROR error; struct hive_key *subkey; - uint32_t data = 42; + char data[4]; + SIVAL(data, 0, 42); error = hive_key_add_name(tctx, root, "Nested Keyll", NULL, NULL, &subkey); torture_assert_werr_ok(tctx, error, "hive_key_add_name"); error = hive_key_set_value(root, "Answer", REG_DWORD, - data_blob_talloc(tctx, &data, sizeof(data))); + data_blob_talloc(tctx, data, sizeof(data))); torture_assert_werr_ok(tctx, error, "hive_key_set_value"); /* This is a new backend. There should be no subkeys and no @@ -119,7 +120,8 @@ static bool test_del_recursive(struct torture_context *tctx, struct hive_key *subkey2; const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; - uint32_t data = 42; + char data[4]; + SIVAL(data, 0, 42); /* Create a new key under the root */ error = hive_key_add_name(mem_ctx, root, "Parent Key", NULL, @@ -133,7 +135,7 @@ static bool test_del_recursive(struct torture_context *tctx, /* Create a new value under "Child Key" */ error = hive_key_set_value(subkey2, "Answer Recursive", REG_DWORD, - data_blob_talloc(mem_ctx, &data, sizeof(data))); + data_blob_talloc(mem_ctx, data, sizeof(data))); torture_assert_werr_ok(tctx, error, "hive_key_set_value"); /* Deleting "Parent Key" will also delete "Child Key" and the value. */ @@ -179,14 +181,15 @@ static bool test_set_value(struct torture_context *tctx, struct hive_key *subkey; const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; - uint32_t data = 42; + char data[4]; + SIVAL(data, 0, 42); error = hive_key_add_name(mem_ctx, root, "YA Nested Key", NULL, NULL, &subkey); torture_assert_werr_ok(tctx, error, "hive_key_add_name"); error = hive_key_set_value(subkey, "Answer", REG_DWORD, - data_blob_talloc(mem_ctx, &data, sizeof(data))); + data_blob_talloc(mem_ctx, data, sizeof(data))); torture_assert_werr_ok(tctx, error, "hive_key_set_value"); return true; @@ -198,10 +201,12 @@ static bool test_get_value(struct torture_context *tctx, const void *test_data) struct hive_key *subkey; const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; - uint32_t data = 42; + char data[4]; uint32_t type; DATA_BLOB value; + SIVAL(data, 0, 42); + error = hive_key_add_name(mem_ctx, root, "EYA Nested Key", NULL, NULL, &subkey); torture_assert_werr_ok(tctx, error, "hive_key_add_name"); @@ -211,7 +216,7 @@ static bool test_get_value(struct torture_context *tctx, const void *test_data) "getting missing value"); error = hive_key_set_value(subkey, "Answer", REG_DWORD, - data_blob_talloc(mem_ctx, &data, sizeof(data))); + data_blob_talloc(mem_ctx, data, sizeof(data))); torture_assert_werr_ok(tctx, error, "hive_key_set_value"); error = hive_get_value(mem_ctx, subkey, "Answer", &type, &value); @@ -232,16 +237,18 @@ static bool test_del_value(struct torture_context *tctx, const void *test_data) struct hive_key *subkey; const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; - uint32_t data = 42; + char data[4]; uint32_t type; DATA_BLOB value; + SIVAL(data, 0, 42); + error = hive_key_add_name(mem_ctx, root, "EEYA Nested Key", NULL, NULL, &subkey); torture_assert_werr_ok(tctx, error, "hive_key_add_name"); error = hive_key_set_value(subkey, "Answer", REG_DWORD, - data_blob_talloc(mem_ctx, &data, sizeof(data))); + data_blob_talloc(mem_ctx, data, sizeof(data))); torture_assert_werr_ok(tctx, error, "hive_key_set_value"); error = hive_key_del_value(subkey, "Answer"); @@ -264,17 +271,19 @@ static bool test_list_values(struct torture_context *tctx, struct hive_key *subkey; const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; - uint32_t data = 42; + char data[4]; uint32_t type; DATA_BLOB value; const char *name; + int data_val = 42; + SIVAL(data, 0, data_val); error = hive_key_add_name(mem_ctx, root, "AYAYA Nested Key", NULL, NULL, &subkey); torture_assert_werr_ok(tctx, error, "hive_key_add_name"); error = hive_key_set_value(subkey, "Answer", REG_DWORD, - data_blob_talloc(mem_ctx, &data, sizeof(data))); + data_blob_talloc(mem_ctx, data, sizeof(data))); torture_assert_werr_ok(tctx, error, "hive_key_set_value"); error = hive_get_value_by_index(mem_ctx, subkey, 0, &name, @@ -287,7 +296,7 @@ static bool test_list_values(struct torture_context *tctx, torture_assert_int_equal(tctx, type, REG_DWORD, "value type"); - torture_assert_int_equal(tctx, data, IVAL(value.data, 0), "value data"); + torture_assert_int_equal(tctx, data_val, IVAL(value.data, 0), "value data"); error = hive_get_value_by_index(mem_ctx, subkey, 1, &name, &type, &value); diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index ec7873a111..ac812823b2 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -281,7 +281,8 @@ static bool test_query_key_nums(struct torture_context *tctx, void *_data) struct registry_key *root, *subkey1, *subkey2; WERROR error; uint32_t num_subkeys, num_values; - uint32_t data = 42; + char data[4]; + SIVAL(data, 0, 42); if (!create_test_key(tctx, rctx, "Berlin", &root, &subkey1)) return false; @@ -353,13 +354,15 @@ static bool test_set_value(struct torture_context *tctx, void *_data) struct registry_context *rctx = (struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; - uint32_t data = 42; + char data[4]; + + SIVAL(data, 0, 42); if (!create_test_key(tctx, rctx, "Dusseldorf", &root, &subkey)) return false; error = reg_val_set(subkey, "Answer", REG_DWORD, - data_blob_talloc(tctx, &data, sizeof(data))); + data_blob_talloc(tctx, data, sizeof(data))); torture_assert_werr_ok (tctx, error, "setting value"); return true; @@ -408,8 +411,9 @@ static bool test_get_value(struct torture_context *tctx, void *_data) struct registry_key *subkey = NULL, *root; WERROR error; DATA_BLOB data; - uint32_t value = 42; + char value[4]; uint32_t type; + SIVAL(value, 0, 42); if (!create_test_key(tctx, rctx, "Duisburg", &root, &subkey)) return false; @@ -420,7 +424,7 @@ static bool test_get_value(struct torture_context *tctx, void *_data) "getting missing value"); error = reg_val_set(subkey, __FUNCTION__, REG_DWORD, - data_blob_talloc(tctx, &value, 4)); + data_blob_talloc(tctx, value, sizeof(value))); torture_assert_werr_ok(tctx, error, "setting value"); error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, @@ -428,7 +432,7 @@ static bool test_get_value(struct torture_context *tctx, void *_data) torture_assert_werr_ok(tctx, error, "getting value"); torture_assert_int_equal(tctx, 4, data.length, "value length ok"); - torture_assert_mem_equal(tctx, data.data, &value, 4, + torture_assert_mem_equal(tctx, data.data, value, 4, "value content ok"); torture_assert_int_equal(tctx, REG_DWORD, type, "value type"); -- cgit From 8582063e9120932e598afbba00d0257e5e9a428f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 17 Apr 2008 16:38:53 +0200 Subject: More work to avoid endian bugs in registry tests. Andrew Bartlett (This used to be commit 500544f4127d4042ab5ea8e3800156246982c297) --- source4/lib/registry/tests/registry.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index ac812823b2..7fad219752 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -448,8 +448,9 @@ static bool test_del_value(struct torture_context *tctx, void *_data) struct registry_key *subkey = NULL, *root; WERROR error; DATA_BLOB data; - uint32_t value = 42; uint32_t type; + char value[4]; + SIVAL(value, 0, 42); if (!create_test_key(tctx, rctx, "Warschau", &root, &subkey)) return false; @@ -460,7 +461,7 @@ static bool test_del_value(struct torture_context *tctx, void *_data) "getting missing value"); error = reg_val_set(subkey, __FUNCTION__, REG_DWORD, - data_blob_talloc(tctx, &value, 4)); + data_blob_talloc(tctx, value, sizeof(value))); torture_assert_werr_ok (tctx, error, "setting value"); error = reg_del_value(subkey, __FUNCTION__); @@ -483,15 +484,16 @@ static bool test_list_values(struct torture_context *tctx, void *_data) struct registry_key *subkey = NULL, *root; WERROR error; DATA_BLOB data; - uint32_t value = 42; uint32_t type; const char *name; + char value[4]; + SIVAL(value, 0, 42); if (!create_test_key(tctx, rctx, "Bonn", &root, &subkey)) return false; error = reg_val_set(subkey, "bar", REG_DWORD, - data_blob_talloc(tctx, &value, 4)); + data_blob_talloc(tctx, value, sizeof(val))); torture_assert_werr_ok (tctx, error, "setting value"); error = reg_key_get_value_by_index(tctx, subkey, 0, &name, @@ -500,7 +502,7 @@ static bool test_list_values(struct torture_context *tctx, void *_data) torture_assert_str_equal(tctx, name, "bar", "value name"); torture_assert_int_equal(tctx, 4, data.length, "value length"); - torture_assert_mem_equal(tctx, data.data, &value, 4, + torture_assert_mem_equal(tctx, data.data, &value, sizeof(value), "value content"); torture_assert_int_equal(tctx, REG_DWORD, type, "value type"); -- cgit From d0525ff0c2c9ae6d7e39c0fda1d4ab956763b585 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 17 Apr 2008 16:44:55 +0200 Subject: Fix typo (This used to be commit ba6546504505f19abaa5aa35fe3e469ddfd3d619) --- source4/lib/registry/tests/registry.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 7fad219752..85b68ac8a2 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -493,7 +493,7 @@ static bool test_list_values(struct torture_context *tctx, void *_data) return false; error = reg_val_set(subkey, "bar", REG_DWORD, - data_blob_talloc(tctx, value, sizeof(val))); + data_blob_talloc(tctx, value, sizeof(value))); torture_assert_werr_ok (tctx, error, "setting value"); error = reg_key_get_value_by_index(tctx, subkey, 0, &name, -- cgit From c9a12fa55d63e4bccb5b453186022dae1da39032 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 17 Apr 2008 18:40:56 +0200 Subject: More endian fixes in the registry (This used to be commit b26662be196a84237543eb90d6e08809489df3a9) --- source4/lib/registry/tests/registry.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index 85b68ac8a2..661d7c2c69 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -431,9 +431,9 @@ static bool test_get_value(struct torture_context *tctx, void *_data) &data); torture_assert_werr_ok(tctx, error, "getting value"); - torture_assert_int_equal(tctx, 4, data.length, "value length ok"); - torture_assert_mem_equal(tctx, data.data, value, 4, - "value content ok"); + torture_assert_int_equal(tctx, sizeof(value), data.length, "value length ok"); + torture_assert_mem_equal(tctx, data.data, value, sizeof(value), + "value content ok"); torture_assert_int_equal(tctx, REG_DWORD, type, "value type"); return true; @@ -501,8 +501,8 @@ static bool test_list_values(struct torture_context *tctx, void *_data) torture_assert_werr_ok(tctx, error, "getting value"); torture_assert_str_equal(tctx, name, "bar", "value name"); - torture_assert_int_equal(tctx, 4, data.length, "value length"); - torture_assert_mem_equal(tctx, data.data, &value, sizeof(value), + torture_assert_int_equal(tctx, sizeof(value), data.length, "value length"); + torture_assert_mem_equal(tctx, data.data, value, sizeof(value), "value content"); torture_assert_int_equal(tctx, REG_DWORD, type, "value type"); -- cgit From 333c169529a3f64a28fcaff1056069867fd56a90 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 20:30:46 +0200 Subject: Use variables for source directory in remaining subsystems. (This used to be commit 6b6b2196a8a8d9e741f5c399185ded7a16938da0) --- source4/lib/registry/config.mk | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index ce19d8512e..fcfbd0437f 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -1,19 +1,19 @@ [SUBSYSTEM::TDR_REGF] PUBLIC_DEPENDENCIES = TDR -TDR_REGF_OBJ_FILES = lib/registry/tdr_regf.o +TDR_REGF_OBJ_FILES = $(libregistrysrcdir)/tdr_regf.o # Special support for external builddirs -lib/registry/regf.c: lib/registry/tdr_regf.c -$(srcdir)/lib/registry/regf.c: lib/registry/tdr_regf.c -lib/registry/tdr_regf.h: lib/registry/tdr_regf.c -lib/registry/tdr_regf.c: $(srcdir)/lib/registry/regf.idl +$(libregistrysrcdir)/regf.c: $(libregistrysrcdir)/tdr_regf.c +$(srcdir)/$(libregistrysrcdir)/regf.c: $(libregistrysrcdir)/tdr_regf.c +$(libregistrysrcdir)/tdr_regf.h: $(libregistrysrcdir)/tdr_regf.c +$(libregistrysrcdir)/tdr_regf.c: $(srcdir)/$(libregistrysrcdir)/regf.idl @CPP="$(CPP)" srcdir="$(srcdir)" $(PERL) $(srcdir)/pidl/pidl $(PIDL_ARGS) \ --header --outputdir=lib/registry \ - --tdr-parser -- $(srcdir)/lib/registry/regf.idl + --tdr-parser -- $(srcdir)/$(libregistrysrcdir)/regf.idl clean:: - @-rm -f lib/registry/regf.h lib/registry/tdr_regf* + @-rm -f $(libregistrysrcdir)/regf.h $(libregistrysrcdir)/tdr_regf* ################################################ # Start SUBSYSTEM registry @@ -24,22 +24,22 @@ PUBLIC_DEPENDENCIES = \ # End MODULE registry_ldb ################################################ -PC_FILES += lib/registry/registry.pc +PC_FILES += $(libregistrysrcdir)/registry.pc registry_VERSION = 0.0.1 registry_SOVERSION = 0 -registry_OBJ_FILES = $(addprefix lib/registry/, interface.o util.o samba.o \ +registry_OBJ_FILES = $(addprefix $(libregistrysrcdir)/, interface.o util.o samba.o \ patchfile_dotreg.o patchfile_preg.o patchfile.o regf.o \ hive.o local.o ldb.o dir.o rpc.o) -PUBLIC_HEADERS += lib/registry/registry.h +PUBLIC_HEADERS += $(libregistrysrcdir)/registry.h [SUBSYSTEM::registry_common] PUBLIC_DEPENDENCIES = registry PRIVATE_PROTO_HEADER = tools/common.h -registry_common_OBJ_FILES = lib/registry/tools/common.o +registry_common_OBJ_FILES = $(libregistrysrcdir)/tools/common.o ################################################ # Start BINARY regdiff @@ -50,9 +50,9 @@ PRIVATE_DEPENDENCIES = \ # End BINARY regdiff ################################################ -regdiff_OBJ_FILES = lib/registry/tools/regdiff.o +regdiff_OBJ_FILES = $(libregistrysrcdir)/tools/regdiff.o -MANPAGES += lib/registry/man/regdiff.1 +MANPAGES += $(libregistrysrcdir)/man/regdiff.1 ################################################ # Start BINARY regpatch @@ -64,9 +64,9 @@ PRIVATE_DEPENDENCIES = \ # End BINARY regpatch ################################################ -regpatch_OBJ_FILES = lib/registry/tools/regpatch.o +regpatch_OBJ_FILES = $(libregistrysrcdir)/tools/regpatch.o -MANPAGES += lib/registry/man/regpatch.1 +MANPAGES += $(libregistrysrcdir)/man/regpatch.1 ################################################ # Start BINARY regshell @@ -78,9 +78,9 @@ PRIVATE_DEPENDENCIES = \ # End BINARY regshell ################################################ -regshell_OBJ_FILES = lib/registry/tools/regshell.o +regshell_OBJ_FILES = $(libregistrysrcdir)/tools/regshell.o -MANPAGES += lib/registry/man/regshell.1 +MANPAGES += $(libregistrysrcdir)/man/regshell.1 ################################################ # Start BINARY regtree @@ -92,18 +92,18 @@ PRIVATE_DEPENDENCIES = \ # End BINARY regtree ################################################ -regtree_OBJ_FILES = lib/registry/tools/regtree.o +regtree_OBJ_FILES = $(libregistrysrcdir)/tools/regtree.o -MANPAGES += lib/registry/man/regtree.1 +MANPAGES += $(libregistrysrcdir)/man/regtree.1 [SUBSYSTEM::torture_registry] PRIVATE_DEPENDENCIES = registry PRIVATE_PROTO_HEADER = tests/proto.h -torture_registry_OBJ_FILES = $(addprefix lib/registry/tests/, generic.o hive.o diff.o registry.o) +torture_registry_OBJ_FILES = $(addprefix $(libregistrysrcdir)/tests/, generic.o hive.o diff.o registry.o) [PYTHON::swig_registry] PUBLIC_DEPENDENCIES = registry SWIG_FILE = registry.i -swig_registry_OBJ_FILES = lib/registry/registry_wrap.o +swig_registry_OBJ_FILES = $(libregistrysrcdir)/registry_wrap.o -- cgit From 4c8756f147f8b9a2806fd76e4cb06bb99d391516 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 22:30:08 +0200 Subject: Create prototype headers from Makefile directory, without smb_build in the middle. (This used to be commit f4a77b96f9c17d853348b70794026e5b9e384942) --- source4/lib/registry/config.mk | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index fcfbd0437f..8c6a76fb19 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -37,10 +37,11 @@ PUBLIC_HEADERS += $(libregistrysrcdir)/registry.h [SUBSYSTEM::registry_common] PUBLIC_DEPENDENCIES = registry -PRIVATE_PROTO_HEADER = tools/common.h registry_common_OBJ_FILES = $(libregistrysrcdir)/tools/common.o +$(call proto_header_template,$(libregistrysrcdir)/tools/common.h,$(registry_common_OBJ_FILES:.o=.c)) + ################################################ # Start BINARY regdiff [BINARY::regdiff] @@ -98,10 +99,11 @@ MANPAGES += $(libregistrysrcdir)/man/regtree.1 [SUBSYSTEM::torture_registry] PRIVATE_DEPENDENCIES = registry -PRIVATE_PROTO_HEADER = tests/proto.h torture_registry_OBJ_FILES = $(addprefix $(libregistrysrcdir)/tests/, generic.o hive.o diff.o registry.o) +$(call proto_header_template,$(libregistrysrcdir)/tests/proto.h,$(torture_registry_OBJ_FILES:.o=.c)) + [PYTHON::swig_registry] PUBLIC_DEPENDENCIES = registry SWIG_FILE = registry.i -- cgit From 4c70cda986c86fe536327321d04c29eca81b6409 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 23:02:47 +0200 Subject: Fix a couple (well, little more than that..) of typos. (This used to be commit a6b52119940a900fb0de3864b8bca94e2965cc24) --- source4/lib/registry/config.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 8c6a76fb19..c0ad613c52 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -40,7 +40,7 @@ PUBLIC_DEPENDENCIES = registry registry_common_OBJ_FILES = $(libregistrysrcdir)/tools/common.o -$(call proto_header_template,$(libregistrysrcdir)/tools/common.h,$(registry_common_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(libregistrysrcdir)/tools/common.h,$(registry_common_OBJ_FILES:.o=.c))) ################################################ # Start BINARY regdiff @@ -102,7 +102,7 @@ PRIVATE_DEPENDENCIES = registry torture_registry_OBJ_FILES = $(addprefix $(libregistrysrcdir)/tests/, generic.o hive.o diff.o registry.o) -$(call proto_header_template,$(libregistrysrcdir)/tests/proto.h,$(torture_registry_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(libregistrysrcdir)/tests/proto.h,$(torture_registry_OBJ_FILES:.o=.c))) [PYTHON::swig_registry] PUBLIC_DEPENDENCIES = registry -- cgit From 2914b0ca04355f6f175b603a1de6030b20ce0830 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 May 2008 21:24:48 +0200 Subject: Remove support for .py files from smb_build - deal with it only in the makefiles. (This used to be commit b865249efaa58d0fc87fa25491fda3b970af81c3) --- source4/lib/registry/config.mk | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index c0ad613c52..bb939be0c5 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -109,3 +109,5 @@ PUBLIC_DEPENDENCIES = registry SWIG_FILE = registry.i swig_registry_OBJ_FILES = $(libregistrysrcdir)/registry_wrap.o + +$(eval $(call python_py_module_template,registry.py,lib/registry/registry.py)) -- cgit From 82bcf967b79321706cd19c759ea54c4465fe0d96 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 May 2008 21:32:53 +0200 Subject: Move CFLAGS overrides for SWIG modules to Makefile. (This used to be commit 58665a8a8e4b10435aebbf2c95b6a8e50db232d6) --- source4/lib/registry/config.mk | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index bb939be0c5..077d96ab30 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -111,3 +111,5 @@ SWIG_FILE = registry.i swig_registry_OBJ_FILES = $(libregistrysrcdir)/registry_wrap.o $(eval $(call python_py_module_template,registry.py,lib/registry/registry.py)) + +$(swig_registry_OBJ_FILES): CFLAGS+="$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)" -- cgit From 49706ab19bd3ffd6125639e6a7753b2350cf54e1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 May 2008 23:59:34 +0200 Subject: Move more modules inside of the samba package. (This used to be commit 9b39e99f48266a54ed0b8890c2efde218b4b118a) --- source4/lib/registry/config.mk | 4 ++-- source4/lib/registry/tests/bindings.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 077d96ab30..90618ffc31 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -105,11 +105,11 @@ torture_registry_OBJ_FILES = $(addprefix $(libregistrysrcdir)/tests/, generic.o $(eval $(call proto_header_template,$(libregistrysrcdir)/tests/proto.h,$(torture_registry_OBJ_FILES:.o=.c))) [PYTHON::swig_registry] +LIBRARY_REALNAME = samba/_registry.$(SHLIBEXT) PUBLIC_DEPENDENCIES = registry -SWIG_FILE = registry.i swig_registry_OBJ_FILES = $(libregistrysrcdir)/registry_wrap.o -$(eval $(call python_py_module_template,registry.py,lib/registry/registry.py)) +$(eval $(call python_py_module_template,samba/registry.py,lib/registry/registry.py)) $(swig_registry_OBJ_FILES): CFLAGS+="$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)" diff --git a/source4/lib/registry/tests/bindings.py b/source4/lib/registry/tests/bindings.py index 314cf778a1..1fb5c70b70 100644 --- a/source4/lib/registry/tests/bindings.py +++ b/source4/lib/registry/tests/bindings.py @@ -19,7 +19,7 @@ import os import unittest -import registry +from samba import registry import samba.tests class HelperTests(unittest.TestCase): -- cgit From 5ce59419a07c8e147daf51b77ffe2117f3d6a505 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 22 May 2008 02:13:26 +0200 Subject: Fix CFLAGS for SWIG files. (This used to be commit 8ee4f075046e0b181ec8a4ac1eaf3ea5621a56bf) --- source4/lib/registry/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 90618ffc31..44adc53524 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -112,4 +112,4 @@ swig_registry_OBJ_FILES = $(libregistrysrcdir)/registry_wrap.o $(eval $(call python_py_module_template,samba/registry.py,lib/registry/registry.py)) -$(swig_registry_OBJ_FILES): CFLAGS+="$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)" +$(swig_registry_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL) -- cgit From 985d6d8dddd1e9ff1328575e068338ad43211643 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 22 May 2008 18:24:10 +0200 Subject: add more docstrings to registry python module (This used to be commit 606f92db874c139ba532df53a87cc5b826215d9e) --- source4/lib/registry/registry.i | 24 +++++++++++++++ source4/lib/registry/registry.py | 60 +++++++++++++++++++++++++++++++++--- source4/lib/registry/registry_wrap.c | 30 ++++++++++++------ 3 files changed, 100 insertions(+), 14 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i index 5ffee4bb3d..7dd02b344c 100644 --- a/source4/lib/registry/registry.i +++ b/source4/lib/registry/registry.i @@ -93,11 +93,20 @@ WERROR reg_open_local(TALLOC_CTX *parent_ctx, struct registry_context **ctx); typedef struct registry_context { %extend { + %feature("docstring") get_predefined_key_by_name "S.get_predefined_key_by_name(name) -> key\n" + "Find a predefined key by name"; WERROR get_predefined_key_by_name(const char *name, struct registry_key **key); + %feature("docstring") key_del_abs "S.key_del_abs(name) -> None\n" + "Delete a key by absolute path."; WERROR key_del_abs(const char *path); + %feature("docstring") get_predefined_key "S.get_predefined_key(hkey_id) -> key\n" + "Find a predefined key by id"; WERROR get_predefined_key(uint32_t hkey_id, struct registry_key **key); + %feature("docstring") diff_apply "S.diff_apply(filename) -> None\n" + "Apply the diff from the specified file"; + WERROR diff_apply(const char *filename); WERROR generate_diff(struct registry_context *ctx2, const struct reg_diff_callbacks *callbacks, void *callback_data); @@ -106,6 +115,8 @@ typedef struct registry_context { const char **elements=NULL); struct registry_key *import_hive_key(struct hive_key *hive, uint32_t predef_key, const char **elements); + %feature("docstring") mount_hive "S.mount_hive(key, predef_name) -> None\n" + "Mount the specified key at the specified path."; WERROR mount_hive(struct hive_key *key, const char *predef_name) { int i; @@ -130,6 +141,7 @@ typedef struct registry_context { $result = SWIG_NewPointerObj(*$1, SWIGTYPE_p_hive_key, 0); } +%feature("docstring") reg_open_hive "S.__init__(location, session_info=None, credentials=None, loadparm_context=None)"; %rename(hive_key) reg_open_hive; WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, @@ -138,6 +150,7 @@ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, struct loadparm_context *lp_ctx, struct hive_key **root); +%feature("docstring") reg_open_ldb_file "open_ldb(location, session_info=None, credentials=None, loadparm_context=None) -> key"; %rename(open_ldb) reg_open_ldb_file; WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, struct auth_session_info *session_info, @@ -146,10 +159,12 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, struct loadparm_context *lp_ctx, struct hive_key **k); +%feature("docstring") reg_create_directory "create_dir(location) -> key"; %rename(create_dir) reg_create_directory; WERROR reg_create_directory(TALLOC_CTX *parent_ctx, const char *location, struct hive_key **key); +%feature("docstring") reg_open_directory "open_dir(location) -> key"; %rename(open_dir) reg_open_directory; WERROR reg_open_directory(TALLOC_CTX *parent_ctx, const char *location, struct hive_key **key); @@ -158,15 +173,24 @@ WERROR reg_open_directory(TALLOC_CTX *parent_ctx, typedef struct hive_key { %extend { + %feature("docstring") del "S.del(name) -> None\n" + "Delete a subkey"; WERROR del(const char *name); + %feature("docstring") flush "S.flush() -> None\n" + "Flush this key to disk"; WERROR flush(void); + %feature("docstring") del_value "S.del_value(name) -> None\n" + "Delete a value"; WERROR del_value(const char *name); + %feature("docstring") set_value "S.set_value(name, type, data) -> None\n" + "Set a value"; WERROR set_value(const char *name, uint32_t type, const DATA_BLOB data); } } hive_key; %rename(open_samba) reg_open_samba; +%feature("docstring") reg_open_samba "open_samba() -> reg"; WERROR reg_open_samba(TALLOC_CTX *mem_ctx, struct registry_context **ctx, struct event_context *ev_ctx, diff --git a/source4/lib/registry/registry.py b/source4/lib/registry/registry.py index cb20d6039d..4c6e735414 100644 --- a/source4/lib/registry/registry.py +++ b/source4/lib/registry/registry.py @@ -66,6 +66,41 @@ Registry = _registry.Registry class reg(object): thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') __repr__ = _swig_repr + def get_predefined_key_by_name(*args, **kwargs): + """ + S.get_predefined_key_by_name(name) -> key + Find a predefined key by name + """ + return _registry.reg_get_predefined_key_by_name(*args, **kwargs) + + def key_del_abs(*args, **kwargs): + """ + S.key_del_abs(name) -> None + Delete a key by absolute path. + """ + return _registry.reg_key_del_abs(*args, **kwargs) + + def get_predefined_key(*args, **kwargs): + """ + S.get_predefined_key(hkey_id) -> key + Find a predefined key by id + """ + return _registry.reg_get_predefined_key(*args, **kwargs) + + def diff_apply(*args, **kwargs): + """ + S.diff_apply(filename) -> None + Apply the diff from the specified file + """ + return _registry.reg_diff_apply(*args, **kwargs) + + def mount_hive(*args): + """ + S.mount_hive(key, predef_name) -> None + Mount the specified key at the specified path. + """ + return _registry.reg_mount_hive(*args) + def __init__(self, *args, **kwargs): _registry.reg_swiginit(self,_registry.new_reg(*args, **kwargs)) __swig_destroy__ = _registry.delete_reg @@ -79,11 +114,26 @@ reg.mount_hive = new_instancemethod(_registry.reg_mount_hive,None,reg) reg_swigregister = _registry.reg_swigregister reg_swigregister(reg) -hive_key = _registry.hive_key -open_ldb = _registry.open_ldb -create_dir = _registry.create_dir -open_dir = _registry.open_dir -open_samba = _registry.open_samba + +def hive_key(*args, **kwargs): + """S.__init__(location, session_info=None, credentials=None, loadparm_context=None)""" + return _registry.hive_key(*args, **kwargs) + +def open_ldb(*args, **kwargs): + """open_ldb(location, session_info=None, credentials=None, loadparm_context=None) -> key""" + return _registry.open_ldb(*args, **kwargs) + +def create_dir(*args, **kwargs): + """create_dir(location) -> key""" + return _registry.create_dir(*args, **kwargs) + +def open_dir(*args, **kwargs): + """open_dir(location) -> key""" + return _registry.open_dir(*args, **kwargs) + +def open_samba(*args, **kwargs): + """open_samba() -> reg""" + return _registry.open_samba(*args, **kwargs) HKEY_CLASSES_ROOT = _registry.HKEY_CLASSES_ROOT HKEY_CURRENT_USER = _registry.HKEY_CURRENT_USER HKEY_LOCAL_MACHINE = _registry.HKEY_LOCAL_MACHINE diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index d9b85ee937..b066e42b41 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -3798,10 +3798,22 @@ static PyMethodDef SwigMethods[] = { { (char *)"reg_get_predef_name", (PyCFunction) _wrap_reg_get_predef_name, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"str_regtype", (PyCFunction) _wrap_str_regtype, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"Registry", (PyCFunction)_wrap_Registry, METH_NOARGS, NULL}, - { (char *)"reg_get_predefined_key_by_name", (PyCFunction) _wrap_reg_get_predefined_key_by_name, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"reg_key_del_abs", (PyCFunction) _wrap_reg_key_del_abs, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"reg_get_predefined_key", (PyCFunction) _wrap_reg_get_predefined_key, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"reg_diff_apply", (PyCFunction) _wrap_reg_diff_apply, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"reg_get_predefined_key_by_name", (PyCFunction) _wrap_reg_get_predefined_key_by_name, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.get_predefined_key_by_name(name) -> key\n" + "Find a predefined key by name\n" + ""}, + { (char *)"reg_key_del_abs", (PyCFunction) _wrap_reg_key_del_abs, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.key_del_abs(name) -> None\n" + "Delete a key by absolute path.\n" + ""}, + { (char *)"reg_get_predefined_key", (PyCFunction) _wrap_reg_get_predefined_key, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.get_predefined_key(hkey_id) -> key\n" + "Find a predefined key by id\n" + ""}, + { (char *)"reg_diff_apply", (PyCFunction) _wrap_reg_diff_apply, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.diff_apply(filename) -> None\n" + "Apply the diff from the specified file\n" + ""}, { (char *)"reg_generate_diff", (PyCFunction) _wrap_reg_generate_diff, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"reg_import_hive_key", (PyCFunction) _wrap_reg_import_hive_key, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"reg_mount_hive", _wrap_reg_mount_hive, METH_VARARGS, NULL}, @@ -3809,11 +3821,11 @@ static PyMethodDef SwigMethods[] = { { (char *)"delete_reg", (PyCFunction)_wrap_delete_reg, METH_O, NULL}, { (char *)"reg_swigregister", reg_swigregister, METH_VARARGS, NULL}, { (char *)"reg_swiginit", reg_swiginit, METH_VARARGS, NULL}, - { (char *)"hive_key", (PyCFunction) _wrap_hive_key, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"open_ldb", (PyCFunction) _wrap_open_ldb, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"create_dir", (PyCFunction) _wrap_create_dir, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"open_dir", (PyCFunction) _wrap_open_dir, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"open_samba", (PyCFunction) _wrap_open_samba, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"hive_key", (PyCFunction) _wrap_hive_key, METH_VARARGS | METH_KEYWORDS, (char *)"S.__init__(location, session_info=None, credentials=None, loadparm_context=None)"}, + { (char *)"open_ldb", (PyCFunction) _wrap_open_ldb, METH_VARARGS | METH_KEYWORDS, (char *)"open_ldb(location, session_info=None, credentials=None, loadparm_context=None) -> key"}, + { (char *)"create_dir", (PyCFunction) _wrap_create_dir, METH_VARARGS | METH_KEYWORDS, (char *)"create_dir(location) -> key"}, + { (char *)"open_dir", (PyCFunction) _wrap_open_dir, METH_VARARGS | METH_KEYWORDS, (char *)"open_dir(location) -> key"}, + { (char *)"open_samba", (PyCFunction) _wrap_open_samba, METH_VARARGS | METH_KEYWORDS, (char *)"open_samba() -> reg"}, { NULL, NULL, 0, NULL } }; -- cgit From a255c9399518419b1028abac09fb9e0c1d572403 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 23 May 2008 16:17:58 +0200 Subject: Cope with new event context parameter in API and removed parameters to reg_open_local(). (This used to be commit 0d5752c940360a0ceb5e23cd6f71cbc61271137a) --- source4/lib/registry/tests/diff.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tests/diff.c b/source4/lib/registry/tests/diff.c index c7726545f6..44ea090527 100644 --- a/source4/lib/registry/tests/diff.c +++ b/source4/lib/registry/tests/diff.c @@ -165,10 +165,10 @@ static bool diff_setup_tcase(struct torture_context *tctx, void **data) td = talloc(tctx, struct diff_tcase_data); /* Create two registry contexts */ - error = reg_open_local(tctx, &r1_ctx, NULL, NULL); + error = reg_open_local(tctx, &r1_ctx); torture_assert_werr_ok(tctx, error, "Opening registry 1 for patch tests failed"); - error = reg_open_local(tctx, &r2_ctx, NULL, NULL); + error = reg_open_local(tctx, &r2_ctx); torture_assert_werr_ok(tctx, error, "Opening registry 2 for patch tests failed"); /* Create temp directory */ @@ -177,14 +177,14 @@ static bool diff_setup_tcase(struct torture_context *tctx, void **data) /* Create and mount HKLM and HKCU hives for registry 1 */ filename = talloc_asprintf(tctx, "%s/r1_local_machine.ldb", td->tempdir); - error = reg_open_ldb_file(tctx, filename, NULL, NULL, tctx->lp_ctx, &r1_hklm); + error = reg_open_ldb_file(tctx, filename, NULL, NULL, tctx->ev, tctx->lp_ctx, &r1_hklm); torture_assert_werr_ok(tctx, error, "Opening local machine file failed"); error = reg_mount_hive(r1_ctx, r1_hklm, HKEY_LOCAL_MACHINE, NULL); torture_assert_werr_ok(tctx, error, "Mounting hive failed"); filename = talloc_asprintf(tctx, "%s/r1_current_user.ldb", td->tempdir); - error = reg_open_ldb_file(tctx, filename, NULL, NULL, tctx->lp_ctx, &r1_hkcu); + error = reg_open_ldb_file(tctx, filename, NULL, NULL, tctx->ev, tctx->lp_ctx, &r1_hkcu); torture_assert_werr_ok(tctx, error, "Opening current user file failed"); error = reg_mount_hive(r1_ctx, r1_hkcu, HKEY_CURRENT_USER, NULL); @@ -192,14 +192,14 @@ static bool diff_setup_tcase(struct torture_context *tctx, void **data) /* Create and mount HKLM and HKCU hives for registry 2 */ filename = talloc_asprintf(tctx, "%s/r2_local_machine.ldb", td->tempdir); - error = reg_open_ldb_file(tctx, filename, NULL, NULL, tctx->lp_ctx, &r2_hklm); + error = reg_open_ldb_file(tctx, filename, NULL, NULL, tctx->ev, tctx->lp_ctx, &r2_hklm); torture_assert_werr_ok(tctx, error, "Opening local machine file failed"); error = reg_mount_hive(r2_ctx, r2_hklm, HKEY_LOCAL_MACHINE, NULL); torture_assert_werr_ok(tctx, error, "Mounting hive failed"); filename = talloc_asprintf(tctx, "%s/r2_current_user.ldb", td->tempdir); - error = reg_open_ldb_file(tctx, filename, NULL, NULL, tctx->lp_ctx, &r2_hkcu); + error = reg_open_ldb_file(tctx, filename, NULL, NULL, tctx->ev, tctx->lp_ctx, &r2_hkcu); torture_assert_werr_ok(tctx, error, "Opening current user file failed"); error = reg_mount_hive(r2_ctx, r2_hkcu, HKEY_CURRENT_USER, NULL); -- cgit From 73b789b6d25698dba15c867c71d0cdd8c264f352 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 24 May 2008 04:01:57 +0200 Subject: Add docstrings to a couple more python modules. (This used to be commit b4560c90e5e8d3a35367d3a21d361dc4c9c0de23) --- source4/lib/registry/registry.i | 6 +++++- source4/lib/registry/registry.py | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i index 7dd02b344c..9420ba2014 100644 --- a/source4/lib/registry/registry.i +++ b/source4/lib/registry/registry.i @@ -16,7 +16,11 @@ along with this program. If not, see . */ -%module registry +%define DOCSTRING +"Access to various registry formats and the Samba registry." +%enddef + +%module(docstring=DOCSTRING) registry %{ /* Include headers */ diff --git a/source4/lib/registry/registry.py b/source4/lib/registry/registry.py index 4c6e735414..0aeefb86c1 100644 --- a/source4/lib/registry/registry.py +++ b/source4/lib/registry/registry.py @@ -3,6 +3,10 @@ # # Don't modify this file, modify the SWIG interface instead. +""" +Access to various registry formats and the Samba registry. +""" + import _registry import new new_instancemethod = new.instancemethod -- cgit From fd03ce3ac31c95ccd6128f4db6ff753c347d18b8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 May 2008 18:46:05 +0200 Subject: Allow external use of regf idl. (This used to be commit 7b9b3ec02b27852cc32689a44c7f3fbbe43b7c6b) --- source4/lib/registry/config.mk | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 44adc53524..fd1fd01a09 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -5,12 +5,11 @@ TDR_REGF_OBJ_FILES = $(libregistrysrcdir)/tdr_regf.o # Special support for external builddirs $(libregistrysrcdir)/regf.c: $(libregistrysrcdir)/tdr_regf.c -$(srcdir)/$(libregistrysrcdir)/regf.c: $(libregistrysrcdir)/tdr_regf.c $(libregistrysrcdir)/tdr_regf.h: $(libregistrysrcdir)/tdr_regf.c -$(libregistrysrcdir)/tdr_regf.c: $(srcdir)/$(libregistrysrcdir)/regf.idl - @CPP="$(CPP)" srcdir="$(srcdir)" $(PERL) $(srcdir)/pidl/pidl $(PIDL_ARGS) \ - --header --outputdir=lib/registry \ - --tdr-parser -- $(srcdir)/$(libregistrysrcdir)/regf.idl +$(libregistrysrcdir)/tdr_regf.c: $(libregistrysrcdir)/regf.idl + @CPP="$(CPP)" $(PERL) $(pidldir)/pidl $(PIDL_ARGS) \ + --header --outputdir=$(libregistrysrcdir) \ + --tdr-parser -- $(libregistrysrcdir)/regf.idl clean:: @-rm -f $(libregistrysrcdir)/regf.h $(libregistrysrcdir)/tdr_regf* -- cgit From 3443954c2bf971c3506aa40667989a10d5769706 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 14 Jun 2008 12:20:12 +0200 Subject: Use proper python errors. (This used to be commit f54084b65fce67457cb838544c83ceb17c7d88db) --- source4/lib/registry/registry.i | 2 +- source4/lib/registry/registry_wrap.c | 42 ++++++++++++++---------------------- 2 files changed, 17 insertions(+), 27 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i index 9420ba2014..c55197c3d0 100644 --- a/source4/lib/registry/registry.i +++ b/source4/lib/registry/registry.i @@ -35,6 +35,7 @@ typedef struct registry_context reg; typedef struct hive_key hive_key; %} +%include "../../libcli/util/errors.i" /* FIXME: This should be in another file */ %typemap(default,noblock=1) struct auth_session_info * { @@ -44,7 +45,6 @@ typedef struct hive_key hive_key; %import "stdint.i" %import "../../lib/talloc/talloc.i" %import "../../auth/credentials/credentials.i" -%import "../../libcli/util/errors.i" %import "../../param/param.i" %import "../events/events.i" diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index b066e42b41..e939e4101d 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -2554,6 +2554,9 @@ typedef struct registry_context reg; typedef struct hive_key hive_key; +#include "libcli/util/pyerrors.h" + + #include #if !defined(SWIG_NO_LLONG_MAX) # if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) @@ -2942,8 +2945,7 @@ SWIGINTERN PyObject *_wrap_Registry(PyObject *SWIGUNUSEDPARM(self), PyObject *ar if (!SWIG_Python_UnpackTuple(args,"Registry",0,0,0)) SWIG_fail; result = reg_open_local(arg1,arg2); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetWERROR(result); SWIG_fail; } else if (resultobj == NULL) { resultobj = Py_None; @@ -2993,8 +2995,7 @@ SWIGINTERN PyObject *_wrap_reg_get_predefined_key_by_name(PyObject *SWIGUNUSEDPA arg3 = (struct registry_key **)(argp3); result = reg_get_predefined_key_by_name(arg1,(char const *)arg2,arg3); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetWERROR(result); SWIG_fail; } else if (resultobj == NULL) { resultobj = Py_None; @@ -3036,8 +3037,7 @@ SWIGINTERN PyObject *_wrap_reg_key_del_abs(PyObject *SWIGUNUSEDPARM(self), PyObj arg2 = (char *)(buf2); result = reg_key_del_abs(arg1,(char const *)arg2); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetWERROR(result); SWIG_fail; } else if (resultobj == NULL) { resultobj = Py_None; @@ -3087,8 +3087,7 @@ SWIGINTERN PyObject *_wrap_reg_get_predefined_key(PyObject *SWIGUNUSEDPARM(self) arg3 = (struct registry_key **)(argp3); result = reg_get_predefined_key(arg1,arg2,arg3); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetWERROR(result); SWIG_fail; } else if (resultobj == NULL) { resultobj = Py_None; @@ -3128,8 +3127,7 @@ SWIGINTERN PyObject *_wrap_reg_diff_apply(PyObject *SWIGUNUSEDPARM(self), PyObje arg2 = (char *)(buf2); result = reg_diff_apply(arg1,(char const *)arg2); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetWERROR(result); SWIG_fail; } else if (resultobj == NULL) { resultobj = Py_None; @@ -3186,8 +3184,7 @@ SWIGINTERN PyObject *_wrap_reg_generate_diff(PyObject *SWIGUNUSEDPARM(self), PyO } result = reg_generate_diff(arg1,arg2,(struct reg_diff_callbacks const *)arg3,arg4); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetWERROR(result); SWIG_fail; } else if (resultobj == NULL) { resultobj = Py_None; @@ -3252,8 +3249,7 @@ SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_0(PyObject *SWIGUNUSEDPARM(self) } result = reg_mount_hive(arg1,arg2,arg3,(char const **)arg4); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetWERROR(result); SWIG_fail; } else if (resultobj == NULL) { resultobj = Py_None; @@ -3365,8 +3361,7 @@ SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_1(PyObject *SWIGUNUSEDPARM(self) arg3 = (char *)(buf3); result = reg_mount_hive__SWIG_1(arg1,arg2,(char const *)arg3); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetWERROR(result); SWIG_fail; } else if (resultobj == NULL) { resultobj = Py_None; @@ -3531,8 +3526,7 @@ SWIGINTERN PyObject *_wrap_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *ar } result = reg_open_hive(arg1,(char const *)arg2,arg3,arg4,arg5,arg6,arg7); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetWERROR(result); SWIG_fail; } else if (resultobj == NULL) { resultobj = Py_None; @@ -3620,8 +3614,7 @@ SWIGINTERN PyObject *_wrap_open_ldb(PyObject *SWIGUNUSEDPARM(self), PyObject *ar } result = reg_open_ldb_file(arg1,(char const *)arg2,arg3,arg4,arg5,arg6,arg7); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetWERROR(result); SWIG_fail; } else if (resultobj == NULL) { resultobj = Py_None; @@ -3661,8 +3654,7 @@ SWIGINTERN PyObject *_wrap_create_dir(PyObject *SWIGUNUSEDPARM(self), PyObject * arg2 = (char *)(buf2); result = reg_create_directory(arg1,(char const *)arg2,arg3); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetWERROR(result); SWIG_fail; } else if (resultobj == NULL) { resultobj = Py_None; @@ -3702,8 +3694,7 @@ SWIGINTERN PyObject *_wrap_open_dir(PyObject *SWIGUNUSEDPARM(self), PyObject *ar arg2 = (char *)(buf2); result = reg_open_directory(arg1,(char const *)arg2,arg3); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetWERROR(result); SWIG_fail; } else if (resultobj == NULL) { resultobj = Py_None; @@ -3781,8 +3772,7 @@ SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject * } result = reg_open_samba(arg1,arg2,arg3,arg4,arg5,arg6); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetWERROR(result); SWIG_fail; } else if (resultobj == NULL) { resultobj = Py_None; -- cgit From 2daf2897d5c70c0efbeba9b827c62700b9a9537c Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 14 Jun 2008 13:00:53 -0400 Subject: Use a custom init function for samba4 that sets a samba4 specific debug function. By default do not debug, this is the most appropriate action for a library as we cannot assume what stderr is use for in the main app. The main app is responsible to set ev_debug_stderr if they so desire. (This used to be commit e566a2f308ac6fb4b526a744f7059b565670aea5) --- source4/lib/registry/registry_wrap.c | 6 +++--- source4/lib/registry/tools/regdiff.c | 2 +- source4/lib/registry/tools/regpatch.c | 2 +- source4/lib/registry/tools/regshell.c | 2 +- source4/lib/registry/tools/regtree.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index e939e4101d..3fc34b1fe3 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -3486,7 +3486,7 @@ SWIGINTERN PyObject *_wrap_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *ar arg3 = NULL; arg4 = NULL; - arg5 = event_context_init(NULL); + arg5 = s4_event_context_init(NULL); arg6 = loadparm_init(NULL); arg1 = NULL; arg7 = &tmp7; @@ -3574,7 +3574,7 @@ SWIGINTERN PyObject *_wrap_open_ldb(PyObject *SWIGUNUSEDPARM(self), PyObject *ar arg3 = NULL; arg4 = NULL; - arg5 = event_context_init(NULL); + arg5 = s4_event_context_init(NULL); arg6 = loadparm_init(NULL); arg1 = NULL; arg7 = &tmp7; @@ -3735,7 +3735,7 @@ SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject * (char *) "ev_ctx",(char *) "lp_ctx",(char *) "session_info",(char *) "credentials", NULL }; - arg3 = event_context_init(NULL); + arg3 = s4_event_context_init(NULL); arg4 = loadparm_init(NULL); arg5 = NULL; arg6 = NULL; diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c index 9b49799bed..240c582340 100644 --- a/source4/lib/registry/tools/regdiff.c +++ b/source4/lib/registry/tools/regdiff.c @@ -118,7 +118,7 @@ int main(int argc, const char **argv) } - ev_ctx = event_context_init(NULL); + ev_ctx = s4_event_context_init(NULL); h1 = open_backend(pc, ev_ctx, cmdline_lp_ctx, backend1, remote1); if (h1 == NULL) diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 9285459d85..1170fbadb4 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -49,7 +49,7 @@ int main(int argc, char **argv) while((opt = poptGetNextOpt(pc)) != -1) { } - ev = event_context_init(NULL); + ev = s4_event_context_init(NULL); if (remote) { h = reg_common_open_remote (remote, cmdline_lp_ctx, cmdline_credentials); diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 80eafcc4a2..4e859df3f6 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -517,7 +517,7 @@ int main(int argc, char **argv) ctx = talloc_zero(NULL, struct regshell_context); - ev_ctx = event_context_init(ctx); + ev_ctx = s4_event_context_init(ctx); if (remote != NULL) { ctx->registry = reg_common_open_remote(remote, cmdline_lp_ctx, diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index 440399f764..daca6957a1 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -129,7 +129,7 @@ int main(int argc, char **argv) while((opt = poptGetNextOpt(pc)) != -1) { } - ev_ctx = event_context_init(NULL); + ev_ctx = s4_event_context_init(NULL); if (remote != NULL) { h = reg_common_open_remote(remote, cmdline_lp_ctx, cmdline_credentials); -- cgit From 9817f3d785ceb67819a9def0e8030272e4ba9e14 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 30 Aug 2008 07:32:44 +1000 Subject: Add a setexpiry operation in samdb.py This makes it easy to set the expiry (or no expiry) for a samdb user (This used to be commit 25171f18a4b242b5a731f4ac1eefc51cc82efd74) --- source4/lib/registry/registry.py | 2 +- source4/lib/registry/registry_wrap.c | 49 ++++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 23 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/registry.py b/source4/lib/registry/registry.py index 0aeefb86c1..e086a6ad37 100644 --- a/source4/lib/registry/registry.py +++ b/source4/lib/registry/registry.py @@ -1,5 +1,5 @@ # This file was automatically generated by SWIG (http://www.swig.org). -# Version 1.3.35 +# Version 1.3.36 # # Don't modify this file, modify the SWIG interface instead. diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c index 3fc34b1fe3..809610fd1d 100644 --- a/source4/lib/registry/registry_wrap.c +++ b/source4/lib/registry/registry_wrap.c @@ -1,6 +1,6 @@ /* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). - * Version 1.3.35 + * Version 1.3.36 * * This file is not intended to be easily readable and contains a number of * coding conventions designed to improve portability and efficiency. Do not make @@ -52,6 +52,12 @@ # endif #endif +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + #ifndef SWIGUNUSEDPARM # ifdef __cplusplus # define SWIGUNUSEDPARM(p) @@ -2533,7 +2539,7 @@ static swig_module_info swig_module = {swig_types, 26, 0, 0, 0, 0}; #define SWIG_name "_registry" -#define SWIGVERSION 0x010335 +#define SWIGVERSION 0x010336 #define SWIG_VERSION SWIGVERSION @@ -2886,13 +2892,13 @@ extern "C" { SWIGINTERN PyObject *_wrap_reg_get_predef_name(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; uint32_t arg1 ; - char *result = 0 ; unsigned int val1 ; int ecode1 = 0 ; PyObject * obj0 = 0 ; char * kwnames[] = { (char *) "hkey", NULL }; + char *result = 0 ; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:reg_get_predef_name",kwnames,&obj0)) SWIG_fail; ecode1 = SWIG_AsVal_unsigned_SS_int(obj0, &val1); @@ -2911,13 +2917,13 @@ fail: SWIGINTERN PyObject *_wrap_str_regtype(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; int arg1 ; - char *result = 0 ; int val1 ; int ecode1 = 0 ; PyObject * obj0 = 0 ; char * kwnames[] = { (char *) "type", NULL }; + char *result = 0 ; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:str_regtype",kwnames,&obj0)) SWIG_fail; ecode1 = SWIG_AsVal_int(obj0, &val1); @@ -2937,8 +2943,8 @@ SWIGINTERN PyObject *_wrap_Registry(PyObject *SWIGUNUSEDPARM(self), PyObject *ar PyObject *resultobj = 0; TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; struct registry_context **arg2 = (struct registry_context **) 0 ; - WERROR result; struct registry_context *tmp2 ; + WERROR result; arg1 = NULL; arg2 = &tmp2; @@ -2962,7 +2968,6 @@ SWIGINTERN PyObject *_wrap_reg_get_predefined_key_by_name(PyObject *SWIGUNUSEDPA reg *arg1 = (reg *) 0 ; char *arg2 = (char *) 0 ; struct registry_key **arg3 = (struct registry_key **) 0 ; - WERROR result; void *argp1 = 0 ; int res1 = 0 ; int res2 ; @@ -2976,6 +2981,7 @@ SWIGINTERN PyObject *_wrap_reg_get_predefined_key_by_name(PyObject *SWIGUNUSEDPA char * kwnames[] = { (char *) "self",(char *) "name",(char *) "key", NULL }; + WERROR result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:reg_get_predefined_key_by_name",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); @@ -3012,7 +3018,6 @@ SWIGINTERN PyObject *_wrap_reg_key_del_abs(PyObject *SWIGUNUSEDPARM(self), PyObj PyObject *resultobj = 0; reg *arg1 = (reg *) 0 ; char *arg2 = (char *) 0 ; - WERROR result; void *argp1 = 0 ; int res1 = 0 ; int res2 ; @@ -3023,6 +3028,7 @@ SWIGINTERN PyObject *_wrap_reg_key_del_abs(PyObject *SWIGUNUSEDPARM(self), PyObj char * kwnames[] = { (char *) "self",(char *) "path", NULL }; + WERROR result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:reg_key_del_abs",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); @@ -3055,7 +3061,6 @@ SWIGINTERN PyObject *_wrap_reg_get_predefined_key(PyObject *SWIGUNUSEDPARM(self) reg *arg1 = (reg *) 0 ; uint32_t arg2 ; struct registry_key **arg3 = (struct registry_key **) 0 ; - WERROR result; void *argp1 = 0 ; int res1 = 0 ; unsigned int val2 ; @@ -3068,6 +3073,7 @@ SWIGINTERN PyObject *_wrap_reg_get_predefined_key(PyObject *SWIGUNUSEDPARM(self) char * kwnames[] = { (char *) "self",(char *) "hkey_id",(char *) "key", NULL }; + WERROR result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:reg_get_predefined_key",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); @@ -3102,7 +3108,6 @@ SWIGINTERN PyObject *_wrap_reg_diff_apply(PyObject *SWIGUNUSEDPARM(self), PyObje PyObject *resultobj = 0; reg *arg1 = (reg *) 0 ; char *arg2 = (char *) 0 ; - WERROR result; void *argp1 = 0 ; int res1 = 0 ; int res2 ; @@ -3113,6 +3118,7 @@ SWIGINTERN PyObject *_wrap_reg_diff_apply(PyObject *SWIGUNUSEDPARM(self), PyObje char * kwnames[] = { (char *) "self",(char *) "filename", NULL }; + WERROR result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:reg_diff_apply",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); @@ -3146,7 +3152,6 @@ SWIGINTERN PyObject *_wrap_reg_generate_diff(PyObject *SWIGUNUSEDPARM(self), PyO struct registry_context *arg2 = (struct registry_context *) 0 ; struct reg_diff_callbacks *arg3 = (struct reg_diff_callbacks *) 0 ; void *arg4 = (void *) 0 ; - WERROR result; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; @@ -3161,6 +3166,7 @@ SWIGINTERN PyObject *_wrap_reg_generate_diff(PyObject *SWIGUNUSEDPARM(self), PyO char * kwnames[] = { (char *) "self",(char *) "ctx2",(char *) "callbacks",(char *) "callback_data", NULL }; + WERROR result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOOO:reg_generate_diff",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); @@ -3201,13 +3207,13 @@ SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_0(PyObject *SWIGUNUSEDPARM(self) struct hive_key *arg2 = (struct hive_key *) 0 ; uint32_t arg3 ; char **arg4 = (char **) NULL ; - WERROR result; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; int res2 = 0 ; unsigned int val3 ; int ecode3 = 0 ; + WERROR result; if ((nobjs < 3) || (nobjs > 4)) SWIG_fail; res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); @@ -3268,7 +3274,6 @@ SWIGINTERN PyObject *_wrap_reg_import_hive_key(PyObject *SWIGUNUSEDPARM(self), P struct hive_key *arg2 = (struct hive_key *) 0 ; uint32_t arg3 ; char **arg4 = (char **) 0 ; - struct registry_key *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; @@ -3282,6 +3287,7 @@ SWIGINTERN PyObject *_wrap_reg_import_hive_key(PyObject *SWIGUNUSEDPARM(self), P char * kwnames[] = { (char *) "self",(char *) "hive",(char *) "predef_key",(char *) "elements", NULL }; + struct registry_key *result = 0 ; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOOO:reg_import_hive_key",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); @@ -3334,7 +3340,6 @@ SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_1(PyObject *SWIGUNUSEDPARM(self) reg *arg1 = (reg *) 0 ; struct hive_key *arg2 = (struct hive_key *) 0 ; char *arg3 = (char *) 0 ; - WERROR result; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; @@ -3342,6 +3347,7 @@ SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_1(PyObject *SWIGUNUSEDPARM(self) int res3 ; char *buf3 = 0 ; int alloc3 = 0 ; + WERROR result; if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); @@ -3434,7 +3440,6 @@ SWIGINTERN PyObject *_wrap_delete_reg(PyObject *SWIGUNUSEDPARM(self), PyObject * } arg1 = (reg *)(argp1); free((char *) arg1); - resultobj = SWIG_Py_Void(); return resultobj; fail: @@ -3462,7 +3467,6 @@ SWIGINTERN PyObject *_wrap_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *ar struct event_context *arg5 = (struct event_context *) 0 ; struct loadparm_context *arg6 = (struct loadparm_context *) 0 ; struct hive_key **arg7 = (struct hive_key **) 0 ; - WERROR result; int res2 ; char *buf2 = 0 ; int alloc2 = 0 ; @@ -3483,10 +3487,11 @@ SWIGINTERN PyObject *_wrap_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *ar char * kwnames[] = { (char *) "location",(char *) "session_info",(char *) "credentials",(char *) "ev_ctx",(char *) "lp_ctx", NULL }; + WERROR result; arg3 = NULL; arg4 = NULL; - arg5 = s4_event_context_init(NULL); + arg5 = event_context_init(NULL); arg6 = loadparm_init(NULL); arg1 = NULL; arg7 = &tmp7; @@ -3550,7 +3555,6 @@ SWIGINTERN PyObject *_wrap_open_ldb(PyObject *SWIGUNUSEDPARM(self), PyObject *ar struct event_context *arg5 = (struct event_context *) 0 ; struct loadparm_context *arg6 = (struct loadparm_context *) 0 ; struct hive_key **arg7 = (struct hive_key **) 0 ; - WERROR result; int res2 ; char *buf2 = 0 ; int alloc2 = 0 ; @@ -3571,10 +3575,11 @@ SWIGINTERN PyObject *_wrap_open_ldb(PyObject *SWIGUNUSEDPARM(self), PyObject *ar char * kwnames[] = { (char *) "location",(char *) "session_info",(char *) "credentials",(char *) "ev_ctx",(char *) "lp_ctx", NULL }; + WERROR result; arg3 = NULL; arg4 = NULL; - arg5 = s4_event_context_init(NULL); + arg5 = event_context_init(NULL); arg6 = loadparm_init(NULL); arg1 = NULL; arg7 = &tmp7; @@ -3634,7 +3639,6 @@ SWIGINTERN PyObject *_wrap_create_dir(PyObject *SWIGUNUSEDPARM(self), PyObject * TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; char *arg2 = (char *) 0 ; struct hive_key **arg3 = (struct hive_key **) 0 ; - WERROR result; int res2 ; char *buf2 = 0 ; int alloc2 = 0 ; @@ -3643,6 +3647,7 @@ SWIGINTERN PyObject *_wrap_create_dir(PyObject *SWIGUNUSEDPARM(self), PyObject * char * kwnames[] = { (char *) "location", NULL }; + WERROR result; arg1 = NULL; arg3 = &tmp3; @@ -3674,7 +3679,6 @@ SWIGINTERN PyObject *_wrap_open_dir(PyObject *SWIGUNUSEDPARM(self), PyObject *ar TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; char *arg2 = (char *) 0 ; struct hive_key **arg3 = (struct hive_key **) 0 ; - WERROR result; int res2 ; char *buf2 = 0 ; int alloc2 = 0 ; @@ -3683,6 +3687,7 @@ SWIGINTERN PyObject *_wrap_open_dir(PyObject *SWIGUNUSEDPARM(self), PyObject *ar char * kwnames[] = { (char *) "location", NULL }; + WERROR result; arg1 = NULL; arg3 = &tmp3; @@ -3717,7 +3722,6 @@ SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject * struct loadparm_context *arg4 = (struct loadparm_context *) 0 ; struct auth_session_info *arg5 = (struct auth_session_info *) 0 ; struct cli_credentials *arg6 = (struct cli_credentials *) 0 ; - WERROR result; struct registry_context *tmp2 ; void *argp3 = 0 ; int res3 = 0 ; @@ -3734,8 +3738,9 @@ SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject * char * kwnames[] = { (char *) "ev_ctx",(char *) "lp_ctx",(char *) "session_info",(char *) "credentials", NULL }; + WERROR result; - arg3 = s4_event_context_init(NULL); + arg3 = event_context_init(NULL); arg4 = loadparm_init(NULL); arg5 = NULL; arg6 = NULL; -- cgit From 8b6b8513909fb0c5acabea060921ed2034b3284d Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 9 Sep 2008 18:01:20 +0200 Subject: Two useful "regshell" improvements This patch corrects the "change key" command (Follow up isn't supported yet) and adds a newline in a error message. (This used to be commit d1052dc42ef591208cfbf7059b28a078f6d4f0bf) --- source4/lib/registry/tools/regshell.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 4e859df3f6..ee8f366e6e 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -162,9 +162,7 @@ static WERROR cmd_ck(struct regshell_context *ctx, int argc, char **argv) struct registry_key *new = NULL; WERROR error; - if(argc < 2) { - new = ctx->current; - } else { + if(argc == 2) { error = reg_open_key(ctx->registry, ctx->current, argv[1], &new); if(!W_ERROR_IS_OK(error)) { @@ -172,11 +170,11 @@ static WERROR cmd_ck(struct regshell_context *ctx, int argc, char **argv) win_errstr(error))); return error; } - } - ctx->path = talloc_asprintf(ctx, "%s\\%s", ctx->path, argv[1]); - printf("Current path is: %s\n", ctx->path); - ctx->current = new; + ctx->path = talloc_asprintf(ctx, "%s\\%s", ctx->path, argv[1]); + ctx->current = new; + } + printf("New path is: %s\n", ctx->path); return WERR_OK; } @@ -188,7 +186,7 @@ static WERROR cmd_print(struct regshell_context *ctx, int argc, char **argv) WERROR error; if (argc != 2) { - fprintf(stderr, "Usage: print "); + fprintf(stderr, "Usage: print \n"); return WERR_INVALID_PARAM; } -- cgit From 3911808323c964c36c2639f68d59d7aca1a2a96b Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 9 Sep 2008 18:03:54 +0200 Subject: Fix up the "reg_common_open_remote" call This fixes up the "reg_common_open_remote" call because it didn't work anymore without the event context. (This used to be commit 42ab865fc937a625d1eece45abe96bf354ddff8b) --- source4/lib/registry/tools/common.c | 3 ++- source4/lib/registry/tools/regpatch.c | 8 ++++---- source4/lib/registry/tools/regshell.c | 4 ++-- source4/lib/registry/tools/regtree.c | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) (limited to 'source4/lib/registry') diff --git a/source4/lib/registry/tools/common.c b/source4/lib/registry/tools/common.c index 3ea780de60..f770f6a3ca 100644 --- a/source4/lib/registry/tools/common.c +++ b/source4/lib/registry/tools/common.c @@ -24,13 +24,14 @@ #include "lib/registry/tools/common.h" struct registry_context *reg_common_open_remote(const char *remote, + struct event_context *ev_ctx, struct loadparm_context *lp_ctx, struct cli_credentials *creds) { struct registry_context *h = NULL; WERROR error; - error = reg_open_remote(&h, NULL, creds, lp_ctx, remote, NULL); + error = reg_open_remote(&h, NULL, creds, lp_ctx, remote, ev_ctx); if (!W_ERROR_IS_OK(error)) { fprintf(stderr, "Unable to open remote registry at %s:%s \n", diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c index 1170fbadb4..add59a5e64 100644 --- a/source4/lib/registry/tools/regpatch.c +++ b/source4/lib/registry/tools/regpatch.c @@ -34,7 +34,7 @@ int main(int argc, char **argv) struct registry_context *h; const char *file = NULL; const char *remote = NULL; - struct event_context *ev; + struct event_context *ev_ctx; struct poptOption long_options[] = { POPT_AUTOHELP {"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL}, @@ -49,12 +49,12 @@ int main(int argc, char **argv) while((opt = poptGetNextOpt(pc)) != -1) { } - ev = s4_event_context_init(NULL); + ev_ctx = s4_event_context_init(NULL); if (remote) { - h = reg_common_open_remote (remote, cmdline_lp_ctx, cmdline_credentials); + h = reg_common_open_remote (remote, ev_ctx, cmdline_lp_ctx, cmdline_credentials); } else { - h = reg_common_open_local (cmdline_credentials, ev, cmdline_lp_ctx); + h = reg_common_open_local (cmdline_credentials, ev_ctx, cmdline_lp_ctx); } if (h == NULL) diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index ee8f366e6e..98f7f02c38 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -518,8 +518,8 @@ int main(int argc, char **argv) ev_ctx = s4_event_context_init(ctx); if (remote != NULL) { - ctx->registry = reg_common_open_remote(remote, cmdline_lp_ctx, - cmdline_credentials); + ctx->registry = reg_common_open_remote(remote, ev_ctx, + cmdline_lp_ctx, cmdline_credentials); } else if (file != NULL) { ctx->current = reg_common_open_file(file, ev_ctx, cmdline_lp_ctx, cmdline_credentials); if (ctx->current == NULL) diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c index daca6957a1..19e4a010b4 100644 --- a/source4/lib/registry/tools/regtree.c +++ b/source4/lib/registry/tools/regtree.c @@ -132,7 +132,7 @@ int main(int argc, char **argv) ev_ctx = s4_event_context_init(NULL); if (remote != NULL) { - h = reg_common_open_remote(remote, cmdline_lp_ctx, cmdline_credentials); + h = reg_common_open_remote(remote, ev_ctx, cmdline_lp_ctx, cmdline_credentials); } else if (file != NULL) { start_key = reg_common_open_file(file, ev_ctx, cmdline_lp_ctx, cmdline_credentials); } else { -- cgit