r2518: Some long overdue changes:
authorJelmer Vernooij <jelmer@samba.org>
Wed, 22 Sep 2004 12:32:31 +0000 (12:32 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:59:01 +0000 (12:59 -0500)
 - 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)

23 files changed:
source4/gtk/common/gtk-smb.c
source4/gtk/common/gtk-smb.h
source4/gtk/config.m4
source4/gtk/tools/gregedit.c
source4/gtk/tools/gwsam.c
source4/include/registry.h
source4/lib/registry/TODO
source4/lib/registry/common/reg_interface.c
source4/lib/registry/common/reg_objects.c [deleted file]
source4/lib/registry/common/reg_util.c
source4/lib/registry/common/registry.h [deleted file]
source4/lib/registry/config.mk
source4/lib/registry/reg_backend_dir/reg_backend_dir.c
source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c
source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c
source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c
source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c
source4/lib/registry/reg_backend_w95/reg_backend_w95.c
source4/lib/registry/tools/regdiff.c
source4/lib/registry/tools/regpatch.c
source4/lib/registry/tools/regshell.c
source4/lib/registry/tools/regtree.c
source4/librpc/idl/winreg.idl

index cc7013edc77aea3ffb2f3007f1623ed770032a2c..2348661cb752e6b6c6a5e83bc416b772e0009bbe 100644 (file)
@@ -55,6 +55,11 @@ static void on_browse_activate  (GtkButton     *button,  gpointer         user_d
        gtk_widget_destroy(GTK_WIDGET(shd));
 }
 
+static void on_krb5_toggled(GtkToggleButton *togglebutton, GtkRpcBindingDialog *d)
+{
+       gtk_widget_set_sensitive(d->entry_password, !gtk_toggle_button_get_active(togglebutton));
+}
+
 static void gtk_rpc_binding_dialog_init (GtkRpcBindingDialog *gtk_rpc_binding_dialog)
 {
        GtkWidget *dialog_vbox1;
@@ -75,7 +80,6 @@ static void gtk_rpc_binding_dialog_init (GtkRpcBindingDialog *gtk_rpc_binding_di
        GtkWidget *lbl_password;
        GtkWidget *btn_browse;
        GtkWidget *label9;
-       GtkWidget *chk_button;
        GtkWidget *lbl_credentials;
        GtkWidget *dialog_action_area1;
        GtkWidget *btn_cancel;
@@ -138,7 +142,7 @@ static void gtk_rpc_binding_dialog_init (GtkRpcBindingDialog *gtk_rpc_binding_di
        gtk_widget_show (btn_browse);
        gtk_box_pack_start (GTK_BOX (hbox1), btn_browse, TRUE, TRUE, 0);
 
-        g_signal_connect ((gpointer) btn_browse, "pressed",
+    g_signal_connect ((gpointer) btn_browse, "pressed",
                G_CALLBACK (on_browse_activate),
                gtk_rpc_binding_dialog);
 
@@ -208,12 +212,23 @@ static void gtk_rpc_binding_dialog_init (GtkRpcBindingDialog *gtk_rpc_binding_di
                        (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                        (GtkAttachOptions) (0), 0, 0);
 
-       chk_button = gtk_check_button_new_with_mnemonic ("_Use kerberos");
-       gtk_widget_show (chk_button);
-       gtk_table_attach (GTK_TABLE (table1), chk_button, 1, 2, 2, 3,
+       gtk_entry_set_text(GTK_ENTRY(gtk_rpc_binding_dialog->entry_username), getenv("LOGNAME"));
+
+       gtk_rpc_binding_dialog->krb5_chk_button = gtk_check_button_new_with_mnemonic ("_Use kerberos");
+       gtk_widget_show (gtk_rpc_binding_dialog->krb5_chk_button);
+       gtk_table_attach (GTK_TABLE (table1), gtk_rpc_binding_dialog->krb5_chk_button, 1, 2, 2, 3,
                        (GtkAttachOptions) (GTK_FILL),
                        (GtkAttachOptions) (0), 0, 0);
 
+    g_signal_connect ((gpointer) gtk_rpc_binding_dialog->krb5_chk_button, "toggled",
+               G_CALLBACK (on_krb5_toggled),
+               gtk_rpc_binding_dialog);
+
+       /* Poor man's autodetection */
+       if(getenv("KRB5CCNAME")) {
+               gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(gtk_rpc_binding_dialog->krb5_chk_button), TRUE);
+       }
+
        lbl_credentials = gtk_label_new ("Credentials");
        gtk_widget_show (lbl_credentials);
        gtk_frame_set_label_widget (GTK_FRAME (frame_credentials), lbl_credentials);
@@ -278,6 +293,11 @@ const char *gtk_rpc_binding_dialog_get_password(GtkRpcBindingDialog *d)
        return gtk_entry_get_text(GTK_ENTRY(d->entry_password));
 }
 
+const char *gtk_rpc_binding_dialog_get_host(GtkRpcBindingDialog *d)
+{
+       return gtk_entry_get_text(GTK_ENTRY(d->entry_host));
+}
+
 const char *gtk_rpc_binding_dialog_get_binding(GtkRpcBindingDialog *d, char *pipe_name)
 {
        const char *transport;
index e9b62d94dad369f54c892e39b00917de48700f89..0f34bb3249426b76dc8a5626e2bc570809deb430 100644 (file)
@@ -38,6 +38,7 @@ struct _GtkRpcBindingDialog
        GtkWidget *entry_host;
        GtkWidget *entry_username;
        GtkWidget *entry_password;
+       GtkWidget *krb5_chk_button;
        TALLOC_CTX *mem_ctx;
 };
 
index 05e737786092e423aad42b287f12ed0769c75670..757ce59c0719b279471c9adf8118274a5722b46f 100644 (file)
@@ -10,8 +10,7 @@ if test t$SMB_EXT_LIB_ENABLE_gtk = tYES; then
        SMB_SUBSYSTEM_ENABLE(GTKSMB, YES)
        SMB_BINARY_ENABLE(gregedit, YES)
        SMB_BINARY_ENABLE(gwcrontab, YES)
-       # this break the build on my SuSE 9.1 --metze
-       #SMB_BINARY_ENABLE(gwsam, YES)
+       SMB_BINARY_ENABLE(gwsam, YES)
        AC_DEFINE(HAVE_GTK, 1, [Whether GTK+ is available])
 fi
 
index 3297399b67a84df38d5a183e9adbbc895343efe9..8938e634fa5d47aca29d06e46a96250b27f1dd4d 100644 (file)
@@ -28,17 +28,18 @@ GtkTreeStore *store_keys;
 GtkListStore *store_vals;
 GtkWidget *tree_keys;
 GtkWidget *mainwin;
+TALLOC_CTX *mem_ctx; /* FIXME: Split up */
 
 GtkWidget *save;
 GtkWidget *save_as;
 static GtkWidget* create_openfilewin (void);
 static GtkWidget* create_savefilewin (void);
-REG_HANDLE *registry = NULL;
+struct registry_context *registry = NULL;
 
 static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath *arg2)
 {
        GtkTreeIter firstiter, iter, tmpiter;
-       REG_KEY *k, *sub;
+       struct registry_key *k, *sub;
        char *name;
        WERROR error;
        int i;
@@ -55,7 +56,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++) {
+       for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(mem_ctx, 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 
@@ -70,7 +71,7 @@ static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath *
                gtk_tree_store_set (store_keys,
                                            &iter, 
                                                0,
-                                               reg_key_name(sub),
+                                               sub->name,
                                                1, 
                                                sub,
                                                -1);
@@ -84,36 +85,28 @@ static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath *
 
 static void registry_load_root() 
 {
-       REG_KEY *root;
+       struct registry_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(mainwin, error);
-                       return;
-               }
+       for(i = 0; i < registry->num_hives; i++) 
+       {
+               root = registry->hives[i]->root;
 
                /* Add the root */
                gtk_tree_store_append(store_keys, &iter, NULL);
                gtk_tree_store_set (store_keys,
                                            &iter, 
                                                0,
-                                               reg_key_name(root),
+                                               root->hive->name,
                                                1,
                                                root,
                                                -1);
 
                gtk_tree_store_append(store_keys, &tmpiter, &iter);
-               i++;
        }
 
        gtk_widget_set_sensitive( save, True );
@@ -123,16 +116,20 @@ static void registry_load_root()
 static void on_open_file_activate (GtkMenuItem *menuitem, gpointer user_data)
 {
        gint result = gtk_dialog_run(GTK_DIALOG(create_openfilewin()));
-       char *filename;
+       char *filename, *tmp;
        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, &registry);
+               error = reg_open(&registry, user_data, filename, NULL);
                if(!W_ERROR_IS_OK(error)) {
                        gtk_show_werror(mainwin, error);
                        break;
                }
+
+               tmp = g_strdup_printf("Registry Editor - %s", filename);
+               gtk_window_set_title (GTK_WINDOW (mainwin), tmp);
+               g_free(tmp);
                registry_load_root();
                break;
        default:
@@ -145,12 +142,14 @@ static void on_open_file_activate (GtkMenuItem *menuitem, gpointer user_data)
 static void on_open_gconf_activate                       (GtkMenuItem     *menuitem,
                                                      gpointer         user_data)
 {
-       WERROR error = reg_open("gconf", NULL, NULL, &registry);
+       WERROR error = reg_open(&registry, "gconf", NULL, NULL);
        if(!W_ERROR_IS_OK(error)) {
                gtk_show_werror(mainwin, error);
                return;
        }
 
+       gtk_window_set_title (GTK_WINDOW (mainwin), "Registry Editor - GConf");
+
        registry_load_root();
 }
 
@@ -158,31 +157,41 @@ static void on_open_remote_activate(GtkMenuItem *menuitem, gpointer user_data)
 {
        char *credentials;
        const char *location;
+       char *tmp;
        GtkWidget *rpcwin = GTK_WIDGET(gtk_rpc_binding_dialog_new(TRUE));
        gint result = gtk_dialog_run(GTK_DIALOG(rpcwin));
        WERROR error;
-       switch(result) {
-       case GTK_RESPONSE_ACCEPT:
-               location = gtk_rpc_binding_dialog_get_binding(GTK_RPC_BINDING_DIALOG(rpcwin), NULL);
-               asprintf(&credentials, "%s%%%s", gtk_rpc_binding_dialog_get_username(GTK_RPC_BINDING_DIALOG(rpcwin)), gtk_rpc_binding_dialog_get_password(GTK_RPC_BINDING_DIALOG(rpcwin)));
-               error = reg_open("rpc", location, credentials, &registry);
-               if(!W_ERROR_IS_OK(error)) {
-                       gtk_show_werror(mainwin, error);
-                       break;
-               }
-               free(credentials);
-               registry_load_root();
-               break;
-       default:
-               break;
+       
+       if(result != GTK_RESPONSE_ACCEPT)
+       {
+               gtk_widget_destroy(rpcwin);
+               return;
+       }
+
+       location = gtk_rpc_binding_dialog_get_binding(GTK_RPC_BINDING_DIALOG(rpcwin), NULL);
+       asprintf(&credentials, "%s%%%s", gtk_rpc_binding_dialog_get_username(GTK_RPC_BINDING_DIALOG(rpcwin)), gtk_rpc_binding_dialog_get_password(GTK_RPC_BINDING_DIALOG(rpcwin)));
+       error = reg_open(&registry, "rpc", location, credentials);
+
+       if(!W_ERROR_IS_OK(error)) {
+               gtk_show_werror(mainwin, error);
+               gtk_widget_destroy(rpcwin);
+               return;
        }
+       free(credentials);
+
+       tmp = g_strdup_printf("Registry Editor - Remote Registry at %s", gtk_rpc_binding_dialog_get_host(GTK_RPC_BINDING_DIALOG(rpcwin)));
+       gtk_window_set_title (GTK_WINDOW (mainwin), tmp);
+       g_free(tmp);
+
+       registry_load_root();
+
 
        gtk_widget_destroy(rpcwin);
 }
 
 
 static void on_save_activate                       (GtkMenuItem     *menuitem,
-                                                                               gpointer         user_data)
+                                                                                                       gpointer         user_data)
 {
        WERROR error = reg_save(registry, NULL);
        if(!W_ERROR_IS_OK(error)) {
@@ -264,8 +273,8 @@ gboolean on_key_activate(GtkTreeSelection *selection,
                                              gpointer data)
 {
        int i;
-       REG_KEY *k;
-       REG_VAL *val;
+       struct registry_key *k;
+       struct registry_value *val;
        WERROR error;
        GtkTreeIter parent;
        if(path_currently_selected)return TRUE;
@@ -277,17 +286,17 @@ gboolean on_key_activate(GtkTreeSelection *selection,
 
        gtk_list_store_clear(store_vals);
 
-       for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(k, i, &val)); i++) {
+       for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(mem_ctx, 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),
+                                               val->name,
                                                1,
-                                               str_regtype(reg_val_type(val)),
+                                               str_regtype(val->data_type),
                                                2,
-                                               reg_val_data_string(val),
+                                               reg_val_data_string(mem_ctx, val),
                                                3, 
                                                val,
                                                -1);
@@ -607,6 +616,7 @@ static GtkWidget* create_savefilewin (void)
        load_interfaces();
 
        gtk_init (&argc, &argv);
+       mem_ctx = talloc_init("gregedit");
 
        pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0);
 
@@ -623,7 +633,7 @@ static GtkWidget* create_savefilewin (void)
                        else backend = "nt4";
                }
 
-               error = reg_open(backend, location, credentials, &registry);
+               error = reg_open(&registry, backend, location, credentials);
                if(!W_ERROR_IS_OK(error)) {
                        gtk_show_werror(mainwin, error);
                        return -1;
@@ -638,6 +648,7 @@ static GtkWidget* create_savefilewin (void)
 
        gtk_main ();
 
-       if(registry)reg_free(registry);
+       if(registry)talloc_destroy(registry->mem_ctx);
+       talloc_destroy(mem_ctx);
        return 0;
 }
index 31bbf002de5540b91b64b0d08650c53984ae3faf..2f0a8e300c2d84625f710e76e1e51d827da2c470 100644 (file)
@@ -39,13 +39,12 @@ void update_userlist(void)
        struct samr_EnumDomainUsers r;
        uint32_t resume_handle=0;
        int i;
-       BOOL ret = True;
        TALLOC_CTX *mem_ctx;
 
        if(!sam_pipe) return;
 
        mem_ctx = talloc_init("update_userlist");
-       r.in.handle = &domain_handle;
+       r.in.domain_handle = &domain_handle;
        r.in.resume_handle = &resume_handle;
        r.in.acct_flags = 0;
        r.in.max_size = (uint32_t)-1;
@@ -87,7 +86,7 @@ on_select_domain_activate                       (GtkMenuItem     *menuitem,
 {
        GtkSelectDomainDialog *d;
        gint result;
-       d = gtk_select_domain_dialog_new(sam_pipe);
+       d = GTK_SELECT_DOMAIN_DIALOG(gtk_select_domain_dialog_new(sam_pipe));
        result = gtk_dialog_run(GTK_DIALOG(d));
        switch(result) {
        case GTK_RESPONSE_ACCEPT:
@@ -129,7 +128,7 @@ void on_connect_activate (GtkMenuItem *menuitem, gpointer user_data)
 
        r.in.system_name = 0;
        r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
-       r.out.handle = &sam_handle;
+       r.out.connect_handle = &sam_handle;
 
        mem_ctx = talloc_init("connect");                                                                                                 
        status = dcerpc_samr_Connect(sam_pipe, mem_ctx, &r);
@@ -218,13 +217,7 @@ create_mainwindow (void)
        GtkWidget *new1;
        GtkWidget *separatormenuitem1;
        GtkWidget *quit;
-       GtkWidget *menuitem2;
        GtkWidget *seldomain;
-       GtkWidget *menuitem2_menu;
-       GtkWidget *cut1;
-       GtkWidget *copy1;
-       GtkWidget *paste1;
-       GtkWidget *delete1;
        GtkWidget *policies;
        GtkWidget *policies_menu;
        GtkWidget *account;
@@ -260,23 +253,20 @@ create_mainwindow (void)
        gtk_widget_show (menubar);
        gtk_box_pack_start (GTK_BOX (vbox1), menubar, FALSE, FALSE, 0);
 
-       menuitem1 = gtk_menu_item_new_with_mnemonic ("_User");
+       menuitem1 = gtk_menu_item_new_with_mnemonic ("_File");
        gtk_widget_show (menuitem1);
        gtk_container_add (GTK_CONTAINER (menubar), menuitem1);
 
        menuitem1_menu = gtk_menu_new ();
        gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem1), menuitem1_menu);
 
-       new1 = gtk_image_menu_item_new_from_stock ("gtk-new", accel_group);
-       gtk_widget_show (new1);
-       gtk_container_add (GTK_CONTAINER (menuitem1_menu), new1);
-
        connect = gtk_menu_item_new_with_mnemonic ("_Connect");
        gtk_widget_show (connect);
        gtk_container_add (GTK_CONTAINER (menuitem1_menu), connect);
 
        seldomain = gtk_menu_item_new_with_mnemonic("_Select Domain");
        gtk_widget_show(seldomain);
+       gtk_widget_set_sensitive (seldomain, FALSE);
        gtk_container_add (GTK_CONTAINER (menuitem1_menu), seldomain);
 
        separatormenuitem1 = gtk_separator_menu_item_new ();
@@ -288,9 +278,24 @@ create_mainwindow (void)
        gtk_widget_show (quit);
        gtk_container_add (GTK_CONTAINER (menuitem1_menu), quit);
 
+       menuitem1 = gtk_menu_item_new_with_mnemonic ("_User");
+       gtk_widget_show (menuitem1);
+       gtk_container_add (GTK_CONTAINER (menubar), menuitem1);
+       gtk_widget_set_sensitive (menuitem1, FALSE);
+
+       menuitem1_menu = gtk_menu_new ();
+       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem1), menuitem1_menu);
+
+       new1 = gtk_image_menu_item_new_from_stock ("gtk-new", accel_group);
+       gtk_widget_show (new1);
+       gtk_container_add (GTK_CONTAINER (menuitem1_menu), new1);
+
+
+
        policies = gtk_menu_item_new_with_mnemonic ("_Policies");
        gtk_widget_show (policies);
        gtk_container_add (GTK_CONTAINER (menubar), policies);
+       gtk_widget_set_sensitive (policies, FALSE);
 
        policies_menu = gtk_menu_new ();
        gtk_menu_item_set_submenu (GTK_MENU_ITEM (policies), policies_menu);
@@ -326,6 +331,7 @@ create_mainwindow (void)
        refresh = gtk_image_menu_item_new_from_stock ("gtk-refresh", accel_group);
        gtk_widget_show (refresh);
        gtk_container_add (GTK_CONTAINER (menuitem3_menu), refresh);
+       gtk_widget_set_sensitive (refresh, FALSE);
 
        menuitem4 = gtk_menu_item_new_with_mnemonic ("_Help");
        gtk_widget_show (menuitem4);
index 162bb5e283669bc9d5bb61a99c48b7ff83ebbdff..3aea70ecc1bb4c01b860480b9fbf0bc4550ce3b3 100644 (file)
 #define        REG_FULL_RESOURCE_DESCRIPTOR                            9
 #define        REG_RESOURCE_REQUIREMENTS_LIST                          10
 
-typedef struct reg_handle_s REG_HANDLE;
-typedef struct reg_key_s REG_KEY;
-typedef struct reg_val_s REG_VAL;
-typedef struct reg_ops_s REG_OPS;
-
 #if 0
 /* FIXME */
 typedef struct ace_struct_s {
@@ -57,4 +52,117 @@ typedef struct ace_struct_s {
 } ACE;
 #endif
 
+/*
+ * 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                    */
+  char *path;            /* Full path to the key */
+  char *class_name; /* Name of key class */
+  NTTIME last_mod; /* Time last modified                 */
+  SEC_DESC *security;
+  struct registry_hive *hive;
+  void *backend_data;
+  int ref;
+};
+
+struct registry_value {
+  char *name;
+  int data_type;
+  int data_len;
+  void *data_blk;    /* Might want a separate block */
+  struct registry_hive *hive;
+  struct registry_key *parent;
+  void *backend_data;
+  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_operations {
+       const char *name;
+
+       /* If one file, connection, etc may have more then one hive */
+       WERROR (*list_available_hives) (TALLOC_CTX *, const char *location, const char *credentials, char ***hives);
+       
+       /* Implement this one */
+       WERROR (*open_hive) (TALLOC_CTX *, struct registry_hive *, struct registry_key **);
+
+       /* Or this one */
+       WERROR (*open_key) (TALLOC_CTX *, struct registry_hive *, const char *name, struct registry_key **);
+
+       /* Either implement these */
+       WERROR (*num_subkeys) (struct registry_key *, int *count);
+       WERROR (*num_values) (struct registry_key *, int *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 *, SEC_DESC **);
+       WERROR (*key_set_sec_desc) (struct registry_key *, SEC_DESC *);
+
+       /* Notification */
+       WERROR (*request_key_change_notify) (struct registry_key *, key_notification_function);
+       WERROR (*request_value_change_notify) (struct registry_value *, value_notification_function);
+
+       /* Key management */
+       WERROR (*add_key)(TALLOC_CTX *, struct registry_key *, const char *name, uint32_t access_mask, SEC_DESC *, struct registry_key **);
+       WERROR (*del_key)(struct registry_key *);
+
+       /* Value management */
+       WERROR (*set_value)(struct registry_key *, const char *name, int type, void *data, int len); 
+       WERROR (*del_value)(struct registry_value *);
+};
+
+struct registry_hive {
+       const struct registry_operations *functions;
+       char *name; /* usually something like HKEY_CURRENT_USER, etc */
+       char *location;
+       char *credentials;
+       char *backend_hivename;
+       void *backend_data;
+       struct registry_key *root;
+       struct registry_context *reg_ctx;
+};
+
+/* Handle to a full registry
+ * contains zero or more hives */
+struct registry_context {
+       TALLOC_CTX *mem_ctx;
+       int num_hives;
+       struct registry_hive **hives;
+};
+
+struct reg_init_function_entry {
+       /* Function to create a member of the pdb_methods list */
+       const struct registry_operations *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 */
index 695f786b69d85c9dd1fad5312879f8716afcdb63..1dea9d2650c580bafd3b00104d57047588774549 100644 (file)
@@ -1,4 +1,3 @@
-- support subtrees
 - ..\..\, \bla\blie support in regshell
 - finish rpc_server
 
index f0a6807558fdef03c002ba85d2f8f7dd1067e9eb..ec6188be71f70b28999e31b21131bc78842242de 100644 (file)
@@ -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 (file)
index d911b46..0000000
+++ /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;
-}
index db5e97bf7fd53a3e5667953642ef0ccdfc5d3e61..21c925deab3a609134a027bd3228ebe62d1d6d33 100644 (file)
@@ -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 (file)
index 89d0ac6..0000000
+++ /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 */
index 8100c798e609ef60953856fc869f145c33fc03e3..659e705d5ddcaa8ab05ee1369eab8b42feacd03f 100644 (file)
@@ -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
index b2bd34bf71c6fd83c20d4ae2e18aa5dbdd899a46..95d4c47af0e6cd6bc340db38aa395ef23117e3b7 100644 (file)
 */
 
 #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,
 };
 
index 15a83197113d3455050be108b7dd3cad15657da5..d8c8d951c16c887aefb46f3d8099ee89c07db32a 100644 (file)
@@ -19,7 +19,6 @@
 */
 
 #include "includes.h"
-#include "lib/registry/common/registry.h"
 #include <gconf/gconf-client.h>
 
 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 
index 47cb60d7113e0b33793297d9137215d0aa8c58bc..e0f65f2c376bc8ff7338bf43d0e580bcf77f35bb 100644 (file)
@@ -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,
 };
 
index ee9f8bf24ffd1cc46f3d7f32ef50e408ca2ac70a..c271c55991afc25a735143d67e22c7dc07c910fe 100644 (file)
@@ -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, "<No 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,
index 0d8d935a4ac260b033ea9920f2812b202b03764b..1c887fc411e1f6c426f3dcfb885df041729428b6 100644 (file)
@@ -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)
index f392759b8de5e0e941a6f0fb6b07dbf1fdcc77f7..2184a8855dadb849e0f5ca54e6cb1245237200c4 100644 (file)
@@ -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,
 };
 
index c46411ae319b4508bd41286cc159e555c572d3cb..524e538591e9fc2ac0cc1013fa35aa997a879138 100644 (file)
 
 #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);
index 7eddea2b93abdaf4ce442867539f84969994b616..1b33628a71d5b9f8f49a415844e93536376ace6c 100644 (file)
@@ -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, &reg_val);
+                                 error = reg_key_get_value_by_name( mem_ctx, tmp, val->name, &reg_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;
 }
index 638ed70d5eeced08769369ab4936b1f060c79140..78fe36f1a0601d51ed9d696ca389005dcd982e2c 100644 (file)
  * 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 <keyname>\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 <name>\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 <valuename>\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;
 }
index b1ca9b3fb26d30f9603ea59dc96168b48d17c1a2..9748ca34380df6cc7286ade3ca3883b9ec0e82c7 100644 (file)
 
 #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("<No Name>\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;
index 812aa4e11f4e2f62ce006723fa966c3700b21b52..46fa8d0d67fc50f60e1f34dd3122f126d1dba2af 100644 (file)
        WERROR winreg_EnumValue(
                [in,ref] policy_handle *handle,
                [in] uint32 enum_index,
-               [in,out,ref] winreg_EnumValueName *name,
+               [out,ref] winreg_EnumValueName *name,
                [in,out] uint32 *type,
                [in,out] winreg_Uint8buf *value,
-               [in,out] uint32 *requested_len,
                [in,out] uint32 *returned_len
        );