summaryrefslogtreecommitdiff
path: root/source4/lib/registry/common
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/registry/common')
-rw-r--r--source4/lib/registry/common/reg_interface.c493
-rw-r--r--source4/lib/registry/common/reg_objects.c213
-rw-r--r--source4/lib/registry/common/reg_util.c64
-rw-r--r--source4/lib/registry/common/registry.h142
4 files changed, 244 insertions, 668 deletions
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<reg_val_size(v); i++) {
- int str_rem = reg_val_size(v) * 3 - (asciip - ret);
- asciip += snprintf(asciip, str_rem, "%02x", *(uint8_t *)(reg_val_data_blk(v)+i));
- if (i < reg_val_size(v) && str_rem > 0)
+ for (i=0; i<v->data_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):"<No Name>", str_regtype(reg_val_type(val)), ds);
- free(ds);
- return ret;
+ return talloc_asprintf(mem_ctx, "%s = %s : %s", val->name?val->name:"<No Name>", str_regtype(val->data_type), reg_val_data_string(mem_ctx, val));
}
-BOOL reg_val_set_string(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 */