r12528: Add seperate proto headers for ntvfs, tdr, smb_server and nbt_server.
[samba.git] / source4 / lib / registry / common / reg_interface.c
index dea88617451d8a6579afd4de409b9d181d885556..00fa42d34277366df98af09da69c8950d9a809d3 100644 (file)
 
 #include "includes.h"
 #include "dlinklist.h"
-#include "registry.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_REGISTRY
+#include "lib/registry/registry.h"
+#include "smb_build.h"
 
 /* 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);
 
-#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)  
+_PUBLIC_ 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(sizeof(struct reg_init_function_entry));
-       entry->functions = functions;
+       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", functions->name));
+       DEBUG(5,("Successfully added registry backend '%s'\n", hive_ops->name));
        return NT_STATUS_OK;
 }
 
@@ -67,98 +58,103 @@ 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;
        }
 
        return NULL;
 }
 
+_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 */
 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_t handle;
+       const char *name;
+} predef_names[] = 
 {
-       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)
+       {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 }
+};
+
+_PUBLIC_ int reg_list_predefs(TALLOC_CTX *mem_ctx, char ***predefs, 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;
+       *predefs = talloc_array(mem_ctx, char *, ARRAY_SIZE(predef_names));
+       *hkeys = talloc_array(mem_ctx, uint32_t, ARRAY_SIZE(predef_names));
 
-       if(!entry->functions->list_available_hives) {
-               return WERR_NOT_SUPPORTED;
+       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 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_predef_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; predef_names[i].name; i++) {
+               if (predef_names[i].handle == hkey) return predef_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_predefined_key_by_name(struct registry_context *ctx, const char *name, struct registry_key **key)
+{
+       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);
        }
 
-       return reterror;
+       DEBUG(1, ("No predefined key with name '%s'\n", name));
+       
+       return WERR_BADFILE;
 }
 
-WERROR reg_close (struct registry_context *ctx)
+WERROR reg_get_predefined_key(struct registry_context *ctx, uint32_t hkey, struct registry_key **key)
 {
-       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]);
-               }
+       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 = ""; 
        }
-       talloc_destroy(ctx);
 
-       return WERR_OK;
+       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)
+_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 *ret;
-       TALLOC_CTX *mem_ctx;
+       struct registry_hive *rethive;
+       struct registry_key *retkey = NULL;
        struct reg_init_function_entry *entry;
        WERROR werr;
 
@@ -169,75 +165,47 @@ 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->backend_data = NULL;
-       ret->reg_ctx = h;
-       ret->name = NULL;
-
-       werr = entry->functions->open_hive(mem_ctx, ret, &ret->root);
-
-       if(!W_ERROR_IS_OK(werr)) return werr;
-       
-       if(!ret->root) {
+       rethive = talloc(parent_ctx, struct registry_hive);
+       rethive->location = location?talloc_strdup(rethive, location):NULL;
+       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;
        }
 
-       ret->root->hive = ret;
-       ret->root->name = NULL;
-       ret->root->path = talloc_strdup(mem_ctx, "");
+       rethive->root = retkey;
 
-       /* 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;
+       retkey->hive = rethive;
+       retkey->name = NULL;
+       retkey->path = talloc_strdup(retkey, "");
+       
+       *root = retkey;
 
        return WERR_OK;
 }
 
-/* Open a key by name (including the hive 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;
-       WERROR error;
-       int hivelength;
-       char *hivename;
-
-       if(strchr(name, '\\')) hivelength = strchr(name, '\\')-name;
-       else hivelength = strlen(name);
-
-       hivename = strndup(name, hivelength);
-       error = reg_get_hive(handle, hivename, &hive);
-       SAFE_FREE(hivename);
-
-       if(!W_ERROR_IS_OK(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(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)
 {
-       char *fullname;
        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;
        }
 
@@ -272,20 +240,18 @@ 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);
-
-       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;
 }
 
-WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, 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;
 
@@ -297,12 +263,10 @@ 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;
 }
 
-WERROR reg_key_num_subkeys(struct registry_key *key, int *count)
+WERROR reg_key_num_subkeys(const struct registry_key *key, uint32_t *count)
 {
        if(!key) return WERR_INVALID_PARAM;
        
@@ -313,11 +277,11 @@ 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++);
-               talloc_destroy(mem_ctx);
+               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;
@@ -327,7 +291,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(const struct registry_key *key, uint32_t *count)
 {
        
        if(!key) return WERR_INVALID_PARAM;
@@ -343,7 +307,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;
@@ -353,7 +317,7 @@ WERROR reg_key_num_values(struct registry_key *key, int *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;
 
@@ -373,7 +337,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;
@@ -383,14 +347,17 @@ 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);
-                       if(W_ERROR_IS_OK(error) && !strcmp((*subkey)->name, name)) {
-                               return error;
+                       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;
        }
@@ -403,7 +370,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;
@@ -415,139 +382,34 @@ 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) && !strcasecmp((*val)->name, name)) {
                                break;
                        }
                }
        }
 
-       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;
+       if (W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS))
+               return WERR_DEST_NOT_FOUND;
+
+       return error;
 }
 
-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(val);
-                       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_hive(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 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;
        
@@ -561,77 +423,52 @@ 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);
 
        return WERR_OK;
 }
 
-WERROR reg_val_set(struct registry_key *key, const char *value, int type, void *data, int len)
+_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, 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;
 }
 
-WERROR reg_get_hive(struct registry_context *h, const char *name, struct registry_key **key) 
+
+WERROR reg_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, struct security_descriptor **secdesc)
 {
-       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;
-               }
-       }
+       /* 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);
 
-       return WERR_NO_MORE_ITEMS;
+       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_value *val)
+_PUBLIC_ WERROR reg_del_value(const 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;
 
        return ret;
 }
 
-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)
+WERROR reg_key_flush(const struct registry_key *key)
 {
        if (!key) {
                return WERR_INVALID_PARAM;
@@ -645,7 +482,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(const struct registry_key *key, uint32_t *max_subkeylen, uint32_t *max_subkeysize)
 {
        int i = 0; 
        struct registry_key *subkey;
@@ -665,12 +502,12 @@ 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;
 }
 
-WERROR reg_key_valuesizes(struct registry_key *key, uint32 *max_valnamelen, uint32 *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;
@@ -686,13 +523,13 @@ WERROR reg_key_valuesizes(struct registry_key *key, uint32 *max_valnamelen, uint
                        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++;
        } while (W_ERROR_IS_OK(error));
 
-       talloc_destroy(mem_ctx);
+       talloc_free(mem_ctx);
 
        return WERR_OK;
 }