summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2004-09-22 12:32:31 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:59:01 -0500
commit369a5d64e462e084e6c5fe4984d56da18b2c92d9 (patch)
tree815e7a10696ef40205c1e16c4e01b660a7a8f0b7
parentbc8ef3d1b6bfdf279d65783869b9a247c1da38aa (diff)
downloadsamba-369a5d64e462e084e6c5fe4984d56da18b2c92d9.tar.gz
samba-369a5d64e462e084e6c5fe4984d56da18b2c92d9.tar.bz2
samba-369a5d64e462e084e6c5fe4984d56da18b2c92d9.zip
r2518: Some long overdue changes:
- Samba4-style code in lib/registry (struct registry_key instead of REG_KEY, etc) - Use hives (like Windows has drives) instead of one root key (like a Unix FS) - usability fixes in the GTK utilities (autodetect the username, enable/disable options, etc) - fix gwsam compile - several bugfixes in the registry rpc code - do charset conversion in nt4 registry backend (This used to be commit 2762ed3b9bf1d67dd54d63e02cddbfd71ea89892)
-rw-r--r--source4/gtk/common/gtk-smb.c30
-rw-r--r--source4/gtk/common/gtk-smb.h1
-rw-r--r--source4/gtk/config.m43
-rw-r--r--source4/gtk/tools/gregedit.c97
-rw-r--r--source4/gtk/tools/gwsam.c36
-rw-r--r--source4/include/registry.h118
-rw-r--r--source4/lib/registry/TODO1
-rw-r--r--source4/lib/registry/common/reg_interface.c493
-rw-r--r--source4/lib/registry/common/reg_objects.c213
-rw-r--r--source4/lib/registry/common/reg_util.c64
-rw-r--r--source4/lib/registry/common/registry.h142
-rw-r--r--source4/lib/registry/config.mk1
-rw-r--r--source4/lib/registry/reg_backend_dir/reg_backend_dir.c77
-rw-r--r--source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c201
-rw-r--r--source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c65
-rw-r--r--source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c143
-rw-r--r--source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c198
-rw-r--r--source4/lib/registry/reg_backend_w95/reg_backend_w95.c166
-rw-r--r--source4/lib/registry/tools/regdiff.c76
-rw-r--r--source4/lib/registry/tools/regpatch.c31
-rw-r--r--source4/lib/registry/tools/regshell.c128
-rw-r--r--source4/lib/registry/tools/regtree.c50
-rw-r--r--source4/librpc/idl/winreg.idl3
23 files changed, 1011 insertions, 1326 deletions
diff --git a/source4/gtk/common/gtk-smb.c b/source4/gtk/common/gtk-smb.c
index cc7013edc7..2348661cb7 100644
--- a/source4/gtk/common/gtk-smb.c
+++ b/source4/gtk/common/gtk-smb.c
@@ -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;
diff --git a/source4/gtk/common/gtk-smb.h b/source4/gtk/common/gtk-smb.h
index e9b62d94da..0f34bb3249 100644
--- a/source4/gtk/common/gtk-smb.h
+++ b/source4/gtk/common/gtk-smb.h
@@ -38,6 +38,7 @@ struct _GtkRpcBindingDialog
GtkWidget *entry_host;
GtkWidget *entry_username;
GtkWidget *entry_password;
+ GtkWidget *krb5_chk_button;
TALLOC_CTX *mem_ctx;
};
diff --git a/source4/gtk/config.m4 b/source4/gtk/config.m4
index 05e7377860..757ce59c07 100644
--- a/source4/gtk/config.m4
+++ b/source4/gtk/config.m4
@@ -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
diff --git a/source4/gtk/tools/gregedit.c b/source4/gtk/tools/gregedit.c
index 3297399b67..8938e634fa 100644
--- a/source4/gtk/tools/gregedit.c
+++ b/source4/gtk/tools/gregedit.c
@@ -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;
}
diff --git a/source4/gtk/tools/gwsam.c b/source4/gtk/tools/gwsam.c
index 31bbf002de..2f0a8e300c 100644
--- a/source4/gtk/tools/gwsam.c
+++ b/source4/gtk/tools/gwsam.c
@@ -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);
diff --git a/source4/include/registry.h b/source4/include/registry.h
index 162bb5e283..3aea70ecc1 100644
--- a/source4/include/registry.h
+++ b/source4/include/registry.h
@@ -43,11 +43,6 @@
#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 */
diff --git a/source4/lib/registry/TODO b/source4/lib/registry/TODO
index 695f786b69..1dea9d2650 100644
--- a/source4/lib/registry/TODO
+++ b/source4/lib/registry/TODO
@@ -1,4 +1,3 @@
-- support subtrees
- ..\..\, \bla\blie support in regshell
- finish rpc_server
diff --git a/source4/lib/registry/common/reg_interface.c b/source4/lib/registry/common/reg_interface.c
index f0a6807558..ec6188be71 100644
--- a/source4/lib/registry/common/reg_interface.c
+++ b/source4/lib/registry/common/reg_interface.c
@@ -19,7 +19,6 @@
*/
#include "includes.h"
-#include "lib/registry/common/registry.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_REGISTRY
@@ -29,10 +28,12 @@ static struct reg_init_function_entry *backends = NULL;
static struct reg_init_function_entry *reg_find_backend_entry(const char *name);
+#define reg_make_path(mem_ctx, parent, name) (((parent)->hive->root == (parent))?talloc_strdup(mem_ctx, name):talloc_asprintf(mem_ctx, "%s\\%s", parent->path, name))
+
/* Register new backend */
NTSTATUS registry_register(const void *_function)
{
- const struct registry_ops *functions = _function;
+ const struct registry_operations *functions = _function;
struct reg_init_function_entry *entry = backends;
if (!functions || !functions->name) {
@@ -91,90 +92,157 @@ BOOL reg_has_backend(const char *backend)
return reg_find_backend_entry(backend) != NULL?True:False;
}
-/* Open a registry file/host/etc */
-WERROR reg_open(const char *backend, const char *location, const char *credentials, REG_HANDLE **h)
+WERROR reg_create(struct registry_context **_ret)
+{
+ TALLOC_CTX *mem_ctx;
+ struct registry_context *ret;
+ mem_ctx = talloc_init("registry handle");
+ ret = talloc(mem_ctx, sizeof(struct registry_context));
+ ret->mem_ctx = mem_ctx;
+ ZERO_STRUCTP(ret);
+ *_ret = ret;
+ return WERR_OK;
+}
+
+WERROR reg_list_available_hives(TALLOC_CTX *mem_ctx, const char *backend, const char *location, const char *credentials, char ***hives)
{
struct reg_init_function_entry *entry;
+
+ entry = reg_find_backend_entry(backend);
+
+ if (!entry) {
+ DEBUG(0, ("No such registry backend '%s' loaded!\n", backend));
+ return WERR_GENERAL_FAILURE;
+ }
+
+ if(!entry->functions->list_available_hives) {
+ return WERR_NOT_SUPPORTED;
+ }
+
+ return entry->functions->list_available_hives(mem_ctx, location, credentials, hives);
+}
+
+WERROR reg_open(struct registry_context **ret, const char *backend, const char *location, const char *credentials)
+{
+ WERROR error = reg_create(ret);
+ char **hives;
+ int i;
+ TALLOC_CTX *mem_ctx = talloc_init("reg_open");
+
+ if(!W_ERROR_IS_OK(error)) return error;
+
+ error = reg_list_available_hives(mem_ctx, backend, location, credentials, &hives);
+
+ if(W_ERROR_EQUAL(error, WERR_NOT_SUPPORTED)) {
+ return reg_import_hive(*ret, backend, location, credentials, NULL);
+ }
+
+ if(!W_ERROR_IS_OK(error)) return error;
+
+ for(i = 0; hives[i]; i++)
+ {
+ error = reg_import_hive(*ret, backend, location, credentials, hives[i]);
+ if(!W_ERROR_IS_OK(error)) return error;
+ (*ret)->hives[i]->name = talloc_strdup((*ret)->mem_ctx, hives[i]);
+ }
+
+ return WERR_OK;
+}
+
+/* Open a registry file/host/etc */
+WERROR reg_import_hive(struct registry_context *h, const char *backend, const char *location, const char *credentials, const char *hivename)
+{
+ struct registry_hive *ret;
TALLOC_CTX *mem_ctx;
- REG_HANDLE *ret;
+ struct reg_init_function_entry *entry;
WERROR werr;
-
+
entry = reg_find_backend_entry(backend);
if (!entry) {
DEBUG(0, ("No such registry backend '%s' loaded!\n", backend));
return WERR_GENERAL_FAILURE;
}
+
+ if(!entry->functions->open_hive) {
+ return WERR_NOT_SUPPORTED;
+ }
- mem_ctx = talloc_init(backend);
- ret = talloc(mem_ctx, sizeof(REG_HANDLE));
- ZERO_STRUCTP(ret);
+
+ mem_ctx = h->mem_ctx;
+ ret = talloc_p(mem_ctx, struct registry_hive);
ret->location = location?talloc_strdup(mem_ctx, location):NULL;
+ ret->backend_hivename = hivename?talloc_strdup(mem_ctx, hivename):NULL;
ret->credentials = credentials?talloc_strdup(mem_ctx, credentials):NULL;
ret->functions = entry->functions;
ret->backend_data = NULL;
- ret->mem_ctx = mem_ctx;
- *h = ret;
+ ret->reg_ctx = h;
- if(!entry->functions->open_registry) {
- return WERR_OK;
- }
+ werr = entry->functions->open_hive(mem_ctx, ret, &ret->root);
+
+ if(!W_ERROR_IS_OK(werr)) return werr;
- werr = entry->functions->open_registry(ret, location, credentials);
+ if(!ret->root) return WERR_GENERAL_FAILURE;
- if(W_ERROR_IS_OK(werr))
- return WERR_OK;
+ ret->root->hive = ret;
+ ret->root->name = NULL;
+ ret->root->path = "";
- talloc_destroy(mem_ctx);
- return werr;
+ /* Add hive to context */
+ h->num_hives++;
+ h->hives = talloc_realloc_p(h->hives, struct registry_hive *, h->num_hives);
+ h->hives[h->num_hives-1] = ret;
+
+ return WERR_OK;
}
/* Open a key by name (including the hive name!) */
-WERROR reg_open_key_abs(REG_HANDLE *handle, const char *name, REG_KEY **result)
+WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result)
{
- REG_KEY *hive;
+ struct registry_key *hive;
WERROR error;
- int i, hivelength;
+ int hivelength;
+ char *hivename;
if(strchr(name, '\\')) hivelength = strchr(name, '\\')-name;
else hivelength = strlen(name);
- for(i = 0; W_ERROR_IS_OK(error); i++) {
- error = reg_get_hive(handle, i, &hive);
- if(W_ERROR_IS_OK(error) && !strncmp(reg_key_name(hive), name, hivelength)) {
- return reg_open_key(hive, name, result);
- }
+ hivename = strndup(name, hivelength);
+ error = reg_get_hive(handle, hivename, &hive);
+ SAFE_FREE(hivename);
+
+ if(!W_ERROR_IS_OK(error)) {
+ return error;
}
- return error;
+ return reg_open_key(mem_ctx, hive, name, result);
}
/* Open a key
* First tries to use the open_key function from the backend
* then falls back to get_subkey_by_name and later get_subkey_by_index
*/
-WERROR reg_open_key(REG_KEY *parent, const char *name, REG_KEY **result)
+WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, struct registry_key **result)
{
char *fullname;
WERROR error;
- TALLOC_CTX *mem_ctx;
if(!parent) {
DEBUG(0, ("Invalid parent key specified"));
return WERR_INVALID_PARAM;
}
- if(!parent->handle->functions->open_key &&
- (parent->handle->functions->get_subkey_by_name ||
- parent->handle->functions->get_subkey_by_index)) {
+ if(!parent->hive->functions->open_key &&
+ (parent->hive->functions->get_subkey_by_name ||
+ parent->hive->functions->get_subkey_by_index)) {
char *orig = strdup(name),
*curbegin = orig,
*curend = strchr(orig, '\\');
- REG_KEY *curkey = parent;
+ struct registry_key *curkey = parent;
while(curbegin && *curbegin) {
if(curend)*curend = '\0';
- error = reg_key_get_subkey_by_name(curkey, curbegin, result);
+ error = reg_key_get_subkey_by_name(mem_ctx, curkey, curbegin, &curkey);
if(!W_ERROR_IS_OK(error)) {
SAFE_FREE(orig);
return error;
@@ -184,94 +252,63 @@ WERROR reg_open_key(REG_KEY *parent, const char *name, REG_KEY **result)
curend = strchr(curbegin, '\\');
}
SAFE_FREE(orig);
-
+
*result = curkey;
+
return WERR_OK;
}
- if(!parent->handle->functions->open_key) {
+ if(!parent->hive->functions->open_key) {
DEBUG(0, ("Registry backend doesn't have get_subkey_by_name nor open_key!\n"));
return WERR_NOT_SUPPORTED;
}
- mem_ctx = talloc_init("mem_ctx");
+ fullname = reg_make_path(mem_ctx, parent, name);
- fullname = talloc_asprintf(mem_ctx, "%s%s%s",
- reg_key_get_path(parent),
- strlen(reg_key_get_path(parent))?"\\":"",
- name);
+ error = parent->hive->functions->open_key(mem_ctx, parent->hive, fullname, result);
- error = parent->handle->functions->open_key(parent->handle,
- parent->hive, fullname, result);
-
- if(!W_ERROR_IS_OK(error)) {
- talloc_destroy(mem_ctx);
- return error;
- }
+ if(!W_ERROR_IS_OK(error)) return error;
- (*result)->handle = parent->handle;
- (*result)->path = talloc_asprintf((*result)->mem_ctx, "%s\\%s",
- reg_key_get_path_abs(parent), (*result)->name);
(*result)->hive = parent->hive;
- talloc_steal((*result)->mem_ctx, fullname);
-
- talloc_destroy(mem_ctx);
+ (*result)->path = fullname;
+ (*result)->hive = parent->hive;
return WERR_OK;
}
-WERROR reg_key_get_value_by_index(REG_KEY *key, int idx, REG_VAL **val)
+WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *key, int idx, struct registry_value **val)
{
if(!key) return WERR_INVALID_PARAM;
- if(key->handle->functions->get_value_by_index) {
- WERROR status = key->handle->functions->get_value_by_index(key, idx, val);
+ if(key->hive->functions->get_value_by_index) {
+ WERROR status = key->hive->functions->get_value_by_index(mem_ctx, key, idx, val);
if(!W_ERROR_IS_OK(status))
return status;
-
- } else if(key->handle->functions->fetch_values) {
- if(!key->cache_values)
- key->handle->functions->fetch_values(key,
- &key->cache_values_count, &key->cache_values);
-
- if(idx < key->cache_values_count && idx >= 0) {
- *val = reg_val_dup(key->cache_values[idx]);
- } else {
- return WERR_NO_MORE_ITEMS;
- }
} else {
return WERR_NOT_SUPPORTED;
}
(*val)->parent = key;
- (*val)->handle = key->handle;
+ (*val)->hive = key->hive;
return WERR_OK;
}
-WERROR reg_key_num_subkeys(REG_KEY *key, int *count)
+WERROR reg_key_num_subkeys(struct registry_key *key, int *count)
{
if(!key) return WERR_INVALID_PARAM;
- if(key->handle->functions->num_subkeys) {
- return key->handle->functions->num_subkeys(key, count);
+ if(key->hive->functions->num_subkeys) {
+ return key->hive->functions->num_subkeys(key, count);
}
- if(key->handle->functions->fetch_subkeys) {
- if(!key->cache_subkeys)
- key->handle->functions->fetch_subkeys(key,
- &key->cache_subkeys_count, &key->cache_subkeys);
-
- *count = key->cache_subkeys_count;
- return WERR_OK;
- }
-
- if(key->handle->functions->get_subkey_by_index) {
+ if(key->hive->functions->get_subkey_by_index) {
int i;
WERROR error;
- REG_KEY *dest;
- for(i = 0; W_ERROR_IS_OK(error = key->handle->functions->get_subkey_by_index(key, i, &dest)); i++) {
- reg_key_free(dest);
- }
+ struct registry_key *dest;
+ TALLOC_CTX *mem_ctx = talloc_init("num_subkeys");
+
+ for(i = 0; W_ERROR_IS_OK(error = key->hive->functions->get_subkey_by_index(mem_ctx, key, i, &dest)); i++);
+ talloc_destroy(mem_ctx);
*count = i;
if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) return WERR_OK;
@@ -281,74 +318,49 @@ WERROR reg_key_num_subkeys(REG_KEY *key, int *count)
return WERR_NOT_SUPPORTED;
}
-WERROR reg_key_num_values(REG_KEY *key, int *count)
+WERROR reg_key_num_values(struct registry_key *key, int *count)
{
if(!key) return WERR_INVALID_PARAM;
- if(!key->handle->functions->num_values) {
- if(!key->handle->functions->fetch_values) {
- DEBUG(1, ("Backend '%s' doesn't support enumerating values\n", key->handle->functions->name));
- return WERR_NOT_SUPPORTED;
- }
-
- if(!key->cache_values)
- key->handle->functions->fetch_values(key, &key->cache_values_count, &key->cache_values);
-
- *count = key->cache_values_count;
- return WERR_OK;
- }
-
-
- return key->handle->functions->num_values(key, count);
+ return key->hive->functions->num_values(key, count);
}
-WERROR reg_key_get_subkey_by_index(REG_KEY *key, int idx, REG_KEY **subkey)
+WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key *key, int idx, struct registry_key **subkey)
{
if(!key) return WERR_INVALID_PARAM;
- if(key->handle->functions->get_subkey_by_index) {
- WERROR status = key->handle->functions->get_subkey_by_index(key, idx, subkey);
+ if(key->hive->functions->get_subkey_by_index) {
+ WERROR status = key->hive->functions->get_subkey_by_index(mem_ctx, key, idx, subkey);
if(!NT_STATUS_IS_OK(status)) return status;
- } else if(key->handle->functions->fetch_subkeys) {
- if(!key->cache_subkeys)
- key->handle->functions->fetch_subkeys(key,
- &key->cache_subkeys_count, &key->cache_subkeys);
-
- if(idx < key->cache_subkeys_count) {
- *subkey = reg_key_dup(key->cache_subkeys[idx]);
- } else {
- return WERR_NO_MORE_ITEMS;
- }
} else {
return WERR_NOT_SUPPORTED;
}
- (*subkey)->path = talloc_asprintf((*subkey)->mem_ctx, "%s\\%s",
- reg_key_get_path_abs(key), (*subkey)->name);
- (*subkey)->handle = key->handle;
- (*subkey)->hive = key->hive;
-
+ if(key->hive->root == key)
+ (*subkey)->path = talloc_strdup(mem_ctx, (*subkey)->name);
+ else
+ (*subkey)->path = talloc_asprintf(mem_ctx, "%s\\%s", key->path, (*subkey)->name);
+ (*subkey)->hive = key->hive;
return WERR_OK;;
}
-WERROR reg_key_get_subkey_by_name(REG_KEY *key, const char *name, REG_KEY **subkey)
+WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key, const char *name, struct registry_key **subkey)
{
int i;
WERROR error = WERR_OK;
if(!key) return WERR_INVALID_PARAM;
- if(key->handle->functions->get_subkey_by_name) {
- error = key->handle->functions->get_subkey_by_name(key,name,subkey);
- } else if(key->handle->functions->get_subkey_by_index || key->handle->functions->fetch_subkeys) {
+ if(key->hive->functions->get_subkey_by_name) {
+ error = key->hive->functions->get_subkey_by_name(mem_ctx, key,name,subkey);
+ } else if(key->hive->functions->get_subkey_by_index) {
for(i = 0; W_ERROR_IS_OK(error); i++) {
- error = reg_key_get_subkey_by_index(key, i, subkey);
+ error = reg_key_get_subkey_by_index(mem_ctx, key, i, subkey);
if(W_ERROR_IS_OK(error) && !strcmp((*subkey)->name, name)) {
return error;
}
- reg_key_free(*subkey);
}
} else {
return WERR_NOT_SUPPORTED;
@@ -356,29 +368,27 @@ WERROR reg_key_get_subkey_by_name(REG_KEY *key, const char *name, REG_KEY **subk
if(!W_ERROR_IS_OK(error)) return error;
- (*subkey)->path = talloc_asprintf((*subkey)->mem_ctx, "%s\\%s", reg_key_get_path_abs(key), (*subkey)->name);
- (*subkey)->handle = key->handle;
+ (*subkey)->path = talloc_asprintf(mem_ctx, "%s\\%s", key->path, (*subkey)->name);
(*subkey)->hive = key->hive;
return WERR_OK;
}
-WERROR reg_key_get_value_by_name(REG_KEY *key, const char *name, REG_VAL **val)
+WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, struct registry_key *key, const char *name, struct registry_value **val)
{
int i;
WERROR error = WERR_OK;
if(!key) return WERR_INVALID_PARAM;
- if(key->handle->functions->get_value_by_name) {
- error = key->handle->functions->get_value_by_name(key,name, val);
+ if(key->hive->functions->get_value_by_name) {
+ error = key->hive->functions->get_value_by_name(mem_ctx, key,name, val);
} else {
for(i = 0; W_ERROR_IS_OK(error); i++) {
- error = reg_key_get_value_by_index(key, i, val);
+ error = reg_key_get_value_by_index(mem_ctx, key, i, val);
if(W_ERROR_IS_OK(error) && StrCaseCmp((*val)->name, name)) {
break;
}
- reg_val_free(*val);
}
}
@@ -386,52 +396,49 @@ WERROR reg_key_get_value_by_name(REG_KEY *key, const char *name, REG_VAL **val)
return error;
(*val)->parent = key;
- (*val)->handle = key->handle;
+ (*val)->hive = key->hive;
return WERR_OK;
}
-WERROR reg_key_del(REG_KEY *key)
+WERROR reg_key_del(struct registry_key *key)
{
WERROR error;
if(!key) return WERR_INVALID_PARAM;
- if(!key->handle->functions->del_key)
+ if(!key->hive->functions->del_key)
return WERR_NOT_SUPPORTED;
- error = key->handle->functions->del_key(key);
+ error = key->hive->functions->del_key(key);
if(!W_ERROR_IS_OK(error)) return error;
- /* Invalidate cache */
- key->cache_subkeys = NULL;
- key->cache_subkeys_count = 0;
return WERR_OK;
}
-WERROR reg_sync(REG_KEY *h, const char *location)
-{
- if(!h->handle->functions->sync_key)
- return WERR_OK;
-
- return h->handle->functions->sync_key(h, location);
-}
-
-WERROR reg_key_del_recursive(REG_KEY *key)
+WERROR reg_key_del_recursive(struct registry_key *key)
{
WERROR error = WERR_OK;
int i;
+
+ TALLOC_CTX *mem_ctx = talloc_init("del_recursive");
/* Delete all values for specified key */
for(i = 0; W_ERROR_IS_OK(error); i++) {
- REG_VAL *val;
- error = reg_key_get_value_by_index(key, i, &val);
+ struct registry_value *val;
+ error = reg_key_get_value_by_index(mem_ctx, key, i, &val);
if(!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS))
+ {
+ talloc_destroy(mem_ctx);
return error;
+ }
if(W_ERROR_IS_OK(error)) {
- error = reg_val_del(val);
- if(!W_ERROR_IS_OK(error)) return error;
+ error = reg_del_value(val);
+ if(!W_ERROR_IS_OK(error)) {
+ talloc_destroy(mem_ctx);
+ return error;
+ }
}
}
@@ -439,204 +446,150 @@ WERROR reg_key_del_recursive(REG_KEY *key)
/* Delete all keys below this one */
for(i = 0; W_ERROR_IS_OK(error); i++) {
- REG_KEY *subkey;
+ struct registry_key *subkey;
- error = reg_key_get_subkey_by_index(key, i, &subkey);
- if(!W_ERROR_IS_OK(error)) return error;
+ error = reg_key_get_subkey_by_index(mem_ctx, key, i, &subkey);
+ if(!W_ERROR_IS_OK(error)) { talloc_destroy(mem_ctx); return error; }
error = reg_key_del_recursive(subkey);
- if(!W_ERROR_IS_OK(error)) return error;
+ if(!W_ERROR_IS_OK(error)) { talloc_destroy(mem_ctx); return error; }
}
+ talloc_destroy(mem_ctx);
return reg_key_del(key);
}
-WERROR reg_val_del(REG_VAL *val)
-{
- WERROR error;
- if (!val) return WERR_INVALID_PARAM;
-
- if (!val->handle->functions->del_value) {
- DEBUG(1, ("Backend '%s' doesn't support method del_value\n", val->handle->functions->name));
- return WERR_NOT_SUPPORTED;
- }
-
- error = val->handle->functions->del_value(val);
-
- if(!W_ERROR_IS_OK(error)) return error;
-
- val->parent->cache_values = NULL;
- val->parent->cache_values_count = 0;
-
- return WERR_OK;
-}
-
-WERROR reg_key_add_name_recursive_abs(REG_HANDLE *handle, const char *name)
+WERROR reg_key_add_name_recursive_abs(struct registry_context *handle, const char *name)
{
- REG_KEY *hive;
+ struct registry_key *hive;
WERROR error;
- int i, hivelength;
+ int hivelength;
+ char *hivename;
if(strchr(name, '\\')) hivelength = strchr(name, '\\')-name;
else hivelength = strlen(name);
- for(i = 0; W_ERROR_IS_OK(error); i++) {
- error = reg_get_hive(handle, i, &hive);
- if(W_ERROR_IS_OK(error) && !strncmp(reg_key_name(hive), name, hivelength)) {
- return reg_key_add_name_recursive(hive, name);
- }
- }
+ hivename = strndup(name, hivelength);
+ error = reg_get_hive(handle, hivename, &hive);
+ SAFE_FREE(hivename);
- return error;
+ if(!W_ERROR_IS_OK(error)) return error;
+
+ return reg_key_add_name_recursive(hive, name);
}
-WERROR reg_key_add_name_recursive(REG_KEY *parent, const char *path)
+WERROR reg_key_add_name_recursive(struct registry_key *parent, const char *path)
{
- REG_KEY *cur, *prevcur = parent;
- WERROR error;
- /* FIXME: we should never write to a 'const char *' !!! --metze */
- char *begin = (char *)path, *end;
+ struct registry_key *cur, *prevcur = parent;
+ WERROR error = WERR_OK;
+ char *dup, *begin, *end;
+ TALLOC_CTX *mem_ctx = talloc_init("add_recursive");
+
+ begin = dup = strdup(path);
while(1) {
end = strchr(begin, '\\');
if(end) *end = '\0';
- error = reg_key_get_subkey_by_name(prevcur, begin, &cur);
+ error = reg_key_get_subkey_by_name(mem_ctx, prevcur, begin, &cur);
/* Key is not there, add it */
if(W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) {
- error = reg_key_add_name(prevcur, begin, 0, NULL, &cur);
- if(!W_ERROR_IS_OK(error)) return error;
+ error = reg_key_add_name(mem_ctx, prevcur, begin, 0, NULL, &cur);
+ if(!W_ERROR_IS_OK(error)) break;
}
if(!W_ERROR_IS_OK(error)) {
if(end) *end = '\\';
- return error;
+ break;
}
- if(!end) break;
+ if(!end) {
+ error = WERR_OK;
+ break;
+ }
+
*end = '\\';
begin = end+1;
prevcur = cur;
}
- return WERR_OK;
+ SAFE_FREE(dup);
+ talloc_destroy(mem_ctx);
+ return error;
}
-WERROR reg_key_add_name(REG_KEY *parent, const char *name, uint32_t access_mask, SEC_DESC *desc, REG_KEY **newkey)
+WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, uint32_t access_mask, SEC_DESC *desc, struct registry_key **newkey)
{
WERROR error;
if (!parent) return WERR_INVALID_PARAM;
- if (!parent->handle->functions->add_key) {
- DEBUG(1, ("Backend '%s' doesn't support method add_key\n", parent->handle->functions->name));
+ if (!parent->hive->functions->add_key) {
+ DEBUG(1, ("Backend '%s' doesn't support method add_key\n", parent->hive->functions->name));
return WERR_NOT_SUPPORTED;
}
- error = parent->handle->functions->add_key(parent, name, access_mask, desc, newkey);
+ error = parent->hive->functions->add_key(mem_ctx, parent, name, access_mask, desc, newkey);
if(!W_ERROR_IS_OK(error)) return error;
- (*newkey)->handle = parent->handle;
- (*newkey)->backend_data = talloc_asprintf((*newkey)->mem_ctx, "%s\\%s", reg_key_get_path(parent), name);
+ (*newkey)->hive = parent->hive;
+ (*newkey)->backend_data = talloc_asprintf(mem_ctx, "%s\\%s", parent->path, name);
- parent->cache_subkeys = NULL;
- parent->cache_subkeys_count = 0;
return WERR_OK;
}
-WERROR reg_val_update(REG_VAL *val, int type, void *data, int len)
+WERROR reg_val_set(struct registry_key *key, const char *value, int type, void *data, int len)
{
- WERROR error;
-
- /* A 'real' update function has preference */
- if (val->handle->functions->update_value)
- return val->handle->functions->update_value(val, type, data, len);
-
- /* Otherwise, just remove and add again */
- if (val->handle->functions->add_value &&
- val->handle->functions->del_value) {
- REG_VAL *new;
- if(!W_ERROR_IS_OK(error = val->handle->functions->del_value(val)))
- return error;
-
- error = val->handle->functions->add_value(val->parent, val->name, type, data, len);
- if(!W_ERROR_IS_OK(error)) return error;
- memcpy(val, new, sizeof(REG_VAL));
- val->parent->cache_values = NULL;
- val->parent->cache_values_count = 0;
- return WERR_OK;
- }
-
- DEBUG(1, ("Backend '%s' doesn't support method update_value\n", val->handle->functions->name));
- return WERR_NOT_SUPPORTED;
-}
-
-void reg_free(REG_HANDLE *h)
-{
- if(!h->functions->close_registry) return;
+ /* A 'real' set function has preference */
+ if (key->hive->functions->set_value)
+ return key->hive->functions->set_value(key, value, type, data, len);
- h->functions->close_registry(h);
+ DEBUG(1, ("Backend '%s' doesn't support method set_value\n", key->hive->functions->name));
+ return WERR_NOT_SUPPORTED;
}
-WERROR reg_get_hive(REG_HANDLE *h, int hivenum, REG_KEY **key)
+WERROR reg_get_hive(struct registry_context *h, const char *name, struct registry_key **key)
{
- WERROR ret;
-
- if(h->functions->get_hive) {
- ret = h->functions->get_hive(h, hivenum, key);
- } else if(h->functions->open_key) {
- if(hivenum == 0) ret = h->functions->open_key(h, hivenum, "", key);
- else ret = WERR_NO_MORE_ITEMS;
- } else {
- DEBUG(0, ("Backend '%s' has neither open_root_key nor open_key or get_hive method implemented\n", h->functions->name));
- ret = WERR_NOT_SUPPORTED;
- }
-
- if(W_ERROR_IS_OK(ret)) {
- (*key)->handle = h;
- if(!(*key)->path) {
- (*key)->path = talloc_strdup((*key)->mem_ctx, (*key)->name);
+ int i;
+ for(i = 0; i < h->num_hives; i++)
+ {
+ if(!strcmp(h->hives[i]->name, name)) {
+ *key = h->hives[i]->root;
+ return WERR_OK;
}
- (*key)->hive = hivenum;
}
- return ret;
+ return WERR_NO_MORE_ITEMS;
}
-WERROR reg_key_add_value(REG_KEY *key, const char *name, int type, void *value, size_t vallen)
+WERROR reg_del_value(struct registry_value *val)
{
WERROR ret = WERR_OK;
- if(!key->handle->functions->add_value)
+ if(!val->hive->functions->del_value)
return WERR_NOT_SUPPORTED;
- ret = key->handle->functions->add_value(key, name, type, value, vallen);
+ ret = val->hive->functions->del_value(val);
if(!W_ERROR_IS_OK(ret)) return ret;
- /* Invalidate the cache */
- key->cache_values = NULL;
- key->cache_values_count = 0;
return ret;
}
-WERROR reg_save(REG_HANDLE *h, const char *location)
+WERROR reg_save(struct registry_context *h, const char *location)
{
/* FIXME */
return WERR_NOT_SUPPORTED;
}
-WERROR reg_key_get_parent(REG_KEY *key, REG_KEY **parent)
+WERROR reg_key_get_parent(TALLOC_CTX *mem_ctx, struct registry_key *key, struct registry_key **parent)
{
char *parent_name;
char *last;
- REG_KEY *root;
+ struct registry_key *root;
WERROR error;
- error = reg_get_hive(key->handle, key->hive, &root);
- if(!W_ERROR_IS_OK(error)) return error;
-
- parent_name = strdup(reg_key_get_path(key));
+ parent_name = strdup(key->path);
last = strrchr(parent_name, '\\');
if(!last) {
@@ -645,7 +598,7 @@ WERROR reg_key_get_parent(REG_KEY *key, REG_KEY **parent)
}
*last = '\0';
- error = reg_open_key(root, parent_name, parent);
+ error = reg_open_key(mem_ctx, root, parent_name, parent);
SAFE_FREE(parent_name);
return error;
}
diff --git a/source4/lib/registry/common/reg_objects.c b/source4/lib/registry/common/reg_objects.c
deleted file mode 100644
index d911b4650b..0000000000
--- a/source4/lib/registry/common/reg_objects.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Gerald Carter 2002.
- * Copyright (C) Jelmer Vernooij 2003-2004.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* Implementation of registry frontend view functions. */
-
-#include "includes.h"
-#include "lib/registry/common/registry.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
-/***********************************************************************
- allocate memory for and duplicate a REG_VAL.
- This is malloc'd memory so the caller should free it when done
- **********************************************************************/
-
-REG_VAL* reg_val_dup( REG_VAL *val )
-{
- val->ref++;
- return val;
-}
-
-/**********************************************************************
- free the memory allocated to a REG_VAL
- *********************************************************************/
-
-void reg_val_free( REG_VAL *val )
-{
- if ( !val )
- return;
-
- val->ref--;
- if(val->ref) return;
-
- if(val->handle->functions->free_val_backend_data)
- val->handle->functions->free_val_backend_data(val);
-
- talloc_destroy( val->mem_ctx );
-
- return;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-uint8_t * reg_val_data_blk( REG_VAL *val )
-{
- return val->data_blk;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-int reg_val_size( REG_VAL *val )
-{
- return val->data_len;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-char *reg_val_name( REG_VAL *val )
-{
- return val->name;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-uint32_t reg_val_type( REG_VAL *val )
-{
- return val->data_type;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-REG_HANDLE *reg_key_handle (REG_KEY *key)
-{
- return key->handle;
-}
-
-char *reg_key_name( REG_KEY *key )
-{
- return key->name;
-}
-
-char *reg_key_class( REG_KEY *key )
-{
- return key->class_name;
-}
-
-NTTIME reg_key_last_modified( REG_KEY *key )
-{
- return key->last_mod;
-}
-
-REG_KEY *reg_key_dup(REG_KEY *key)
-{
- key->ref++;
- return key;
-}
-
-void reg_key_free(REG_KEY *key)
-{
- if(!key)
- return;
-
- key->ref--;
- if(key->ref) return;
-
- if(key->handle->functions->free_key_backend_data)
- key->handle->functions->free_key_backend_data(key);
-
- if(key->cache_values) {
- int i;
- for(i = 0; i < key->cache_values_count; i++) {
- reg_val_free(key->cache_values[i]);
- }
- }
-
- if(key->cache_subkeys) {
- int i;
- for(i = 0; i < key->cache_subkeys_count; i++) {
- reg_key_free(key->cache_subkeys[i]);
- }
- }
-
- talloc_destroy(key->mem_ctx);
-}
-
-char *reg_val_get_path(REG_VAL *v)
-{
- /* FIXME */
- return NULL;
-}
-
-const char *reg_key_get_path(REG_KEY *k)
-{
- SMB_REG_ASSERT(k);
- return strchr(k->path, '\\')?strchr(k->path, '\\')+1:"";
-}
-
-const char *reg_key_get_path_abs(REG_KEY *k)
-{
- SMB_REG_ASSERT(k);
- return k->path;
-}
-
-/* For use by the backends _ONLY_ */
-REG_KEY *reg_key_new_abs(const char *path, REG_HANDLE *h, void *data)
-{
- REG_KEY *r;
- TALLOC_CTX *mem_ctx = talloc_init(path);
- r = talloc(mem_ctx, sizeof(REG_KEY));
- ZERO_STRUCTP(r);
- r->handle = h;
- r->mem_ctx = mem_ctx;
- r->path = talloc_strdup(mem_ctx, path);
- r->name = talloc_strdup(mem_ctx, strrchr(path, '\\')?strrchr(path,'\\')+1:path);
- r->backend_data = data;
- r->ref = 1;
- return r;
-}
-
-REG_KEY *reg_key_new_rel(const char *name, REG_KEY *k, void *data)
-{
- REG_KEY *r;
- const char *parent_path = k?reg_key_get_path(k):"";
- TALLOC_CTX *mem_ctx = talloc_init(name);
- r = talloc(mem_ctx, sizeof(REG_KEY));
- ZERO_STRUCTP(r);
- r->handle = k->handle;
- r->hive = k->hive;
- r->name = talloc_strdup(mem_ctx, name);
-
- r->path = talloc_asprintf(mem_ctx, "%s%s%s", parent_path, *parent_path && parent_path[strlen(parent_path)-1] != '\\'?"\\":"", name);
- r->backend_data = data;
- r->mem_ctx = mem_ctx;
- r->ref = 1;
- return r;
-}
-
-REG_VAL *reg_val_new(REG_KEY *parent, void *data)
-{
- REG_VAL *r;
- TALLOC_CTX *mem_ctx = talloc_init("value");
- r = talloc(mem_ctx, sizeof(REG_VAL));
- ZERO_STRUCTP(r);
- r->mem_ctx = mem_ctx;
- r->handle = parent->handle;
- r->backend_data = data;
- r->ref = 1;
- return r;
-}
diff --git a/source4/lib/registry/common/reg_util.c b/source4/lib/registry/common/reg_util.c
index db5e97bf7f..21c925deab 100644
--- a/source4/lib/registry/common/reg_util.c
+++ b/source4/lib/registry/common/reg_util.c
@@ -34,90 +34,68 @@ const char *str_regtype(int type)
return "Unknown";
}
-char *reg_val_data_string(REG_VAL *v)
+char *reg_val_data_string(TALLOC_CTX *mem_ctx, struct registry_value *v)
{
char *asciip;
char *ret = NULL;
int i;
- if(reg_val_size(v) == 0) return strdup("");
+ if(v->data_len == 0) return talloc_strdup(mem_ctx, "");
- switch (reg_val_type(v)) {
+ switch (v->data_type) {
case REG_SZ:
- /* FIXME: Convert to ascii */
- return strndup(reg_val_data_blk(v), reg_val_size(v));
+ return talloc_strndup(mem_ctx, v->data_blk, v->data_len);
case REG_EXPAND_SZ:
- return strndup(reg_val_data_blk(v), reg_val_size(v));
+ return talloc_strndup(mem_ctx, v->data_blk, v->data_len);
case REG_BINARY:
- ret = malloc(reg_val_size(v) * 3 + 2);
+ ret = talloc(mem_ctx, v->data_len * 3 + 2);
asciip = ret;
- for (i=0; i<reg_val_size(v); i++) {
- int str_rem = reg_val_size(v) * 3 - (asciip - ret);
- asciip += snprintf(asciip, str_rem, "%02x", *(uint8_t *)(reg_val_data_blk(v)+i));
- if (i < reg_val_size(v) && str_rem > 0)
+ for (i=0; i<v->data_len; i++) {
+ int str_rem = v->data_len * 3 - (asciip - ret);
+ asciip += snprintf(asciip, str_rem, "%02x", *(uint8_t *)(v->data_blk+i));
+ if (i < v->data_len && str_rem > 0)
*asciip = ' '; asciip++;
}
*asciip = '\0';
return ret;
- break;
case REG_DWORD:
- if (*(int *)reg_val_data_blk(v) == 0)
- ret = strdup("0");
- else
- asprintf(&ret, "0x%x", *(int *)reg_val_data_blk(v));
- break;
+ if (*(int *)v->data_blk == 0)
+ return talloc_strdup(mem_ctx, "0");
+
+ return talloc_asprintf(mem_ctx, "0x%x", *(int *)v->data_blk);
case REG_MULTI_SZ:
/* FIXME */
break;
default:
- return 0;
break;
}
return ret;
}
-char *reg_val_description(REG_VAL *val)
+char *reg_val_description(TALLOC_CTX *mem_ctx, struct registry_value *val)
{
- char *ret, *ds = reg_val_data_string(val);
- asprintf(&ret, "%s = %s : %s", reg_val_name(val)?reg_val_name(val):"<No Name>", str_regtype(reg_val_type(val)), ds);
- free(ds);
- return ret;
+ return talloc_asprintf(mem_ctx, "%s = %s : %s", val->name?val->name:"<No Name>", str_regtype(val->data_type), reg_val_data_string(mem_ctx, val));
}
-BOOL reg_val_set_string(REG_VAL *val, char *str)
+BOOL reg_val_set_string(struct registry_value *val, char *str)
{
/* FIXME */
return False;
}
-WERROR reg_key_get_subkey_val(REG_KEY *key, const char *subname, const char *valname, REG_VAL **val)
+WERROR reg_key_get_subkey_val(TALLOC_CTX *mem_ctx, struct registry_key *key, const char *subname, const char *valname, struct registry_value **val)
{
- REG_KEY *k;
- WERROR error = reg_key_get_subkey_by_name(key, subname, &k);
- if(!W_ERROR_IS_OK(error)) return error;
-
- return reg_key_get_value_by_name(k, valname, val);
-}
-
-WERROR reg_key_set_subkey_val(REG_KEY *key, const char *subname, const char *valname, uint32_t type, uint8_t *data, int real_len)
-{
- REG_KEY *k;
- REG_VAL *v;
- WERROR error;
-
- error = reg_key_get_subkey_by_name(key, subname, &k);
- if(!W_ERROR_IS_OK(error)) return error;
-
- error = reg_key_get_value_by_name(k, valname, &v);
+ struct registry_key *k;
+ WERROR error = reg_key_get_subkey_by_name(mem_ctx, key, subname, &k);
if(!W_ERROR_IS_OK(error)) return error;
- return reg_val_update(v, type, data, real_len);
+ return reg_key_get_value_by_name(mem_ctx, k, valname, val);
}
/***********************************************************************
diff --git a/source4/lib/registry/common/registry.h b/source4/lib/registry/common/registry.h
deleted file mode 100644
index 89d0ac6b14..0000000000
--- a/source4/lib/registry/common/registry.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Registry interface
- This file contains the _internal_ structs for the registry
- subsystem. Backends and the subsystem itself are the only
- files that need to include this file.
- Copyright (C) Gerald Carter 2002.
- Copyright (C) Jelmer Vernooij 2003-2004.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#ifndef _REGISTRY_REGISTRY_H /* _REGISTRY_REGISTRY_H */
-#define _REGISTRY_REGISTRY_H
-
-#define REGISTRY_INTERFACE_VERSION 1
-
-/* structure to store the registry handles */
-struct reg_key_s {
- char *name; /* Name of the key */
- char *path; /* Full path to the key */
- char *class_name; /* Name of key class */
- NTTIME last_mod; /* Time last modified */
- SEC_DESC *security;
- REG_HANDLE *handle;
- void *backend_data;
- REG_VAL **cache_values;
- int cache_values_count;
- REG_KEY **cache_subkeys;
- int cache_subkeys_count;
- int hive;
- TALLOC_CTX *mem_ctx;
- int ref;
-};
-
-struct reg_val_s {
- char *name;
- int has_name;
- int data_type;
- int data_len;
- void *data_blk; /* Might want a separate block */
- REG_HANDLE *handle;
- REG_KEY *parent;
- void *backend_data;
- TALLOC_CTX *mem_ctx;
- int ref;
-};
-
-/* FIXME */
-typedef void (*key_notification_function) (void);
-typedef void (*value_notification_function) (void);
-
-/*
- * Container for function pointers to enumeration routines
- * for virtual registry view
- *
- * Backends can provide :
- * - just one hive (example: nt4, w95)
- * - several hives (example: rpc)
- *
- */
-
-struct registry_ops {
- const char *name;
- WERROR (*open_registry) (REG_HANDLE *, const char *location, const char *credentials);
- WERROR (*sync_key)(REG_KEY *, const char *location);
- WERROR (*close_registry) (REG_HANDLE *);
-
- /* Implement this one */
- WERROR (*get_hive) (REG_HANDLE *, int , REG_KEY **);
-
- /* Or this one */
- WERROR (*open_key) (REG_HANDLE *, int hive, const char *name, REG_KEY **);
-
- /* Either implement these */
- WERROR (*num_subkeys) (REG_KEY *, int *count);
- WERROR (*num_values) (REG_KEY *, int *count);
- WERROR (*get_subkey_by_index) (REG_KEY *, int idx, REG_KEY **);
- /* Can not contain more then one level */
- WERROR (*get_subkey_by_name) (REG_KEY *, const char *name, REG_KEY **);
- WERROR (*get_value_by_index) (REG_KEY *, int idx, REG_VAL **);
- /* Can not contain more then one level */
- WERROR (*get_value_by_name) (REG_KEY *, const char *name, REG_VAL **);
-
- /* Or these */
- WERROR (*fetch_subkeys) (REG_KEY *, int *count, REG_KEY ***);
- WERROR (*fetch_values) (REG_KEY *, int *count, REG_VAL ***);
-
- /* Security control */
- WERROR (*key_get_sec_desc) (REG_KEY *, SEC_DESC **);
- WERROR (*key_set_sec_desc) (REG_KEY *, SEC_DESC *);
-
- /* Notification */
- WERROR (*request_key_change_notify) (REG_KEY *, key_notification_function);
- WERROR (*request_value_change_notify) (REG_VAL *, value_notification_function);
-
- /* Key management */
- WERROR (*add_key)(REG_KEY *, const char *name, uint32_t access_mask, SEC_DESC *, REG_KEY **);
- WERROR (*del_key)(REG_KEY *);
-
- /* Value management */
- WERROR (*add_value)(REG_KEY *, const char *name, int type, void *data, int len);
- WERROR (*del_value)(REG_VAL *);
-
- /* If update is not available, value will first be deleted and then added
- * again */
- WERROR (*update_value)(REG_VAL *, int type, void *data, int len);
-
- void (*free_key_backend_data) (REG_KEY *);
- void (*free_val_backend_data) (REG_VAL *);
-};
-
-struct reg_handle_s {
- const struct registry_ops *functions;
- char *location;
- char *credentials;
- void *backend_data;
- TALLOC_CTX *mem_ctx;
-};
-
-struct reg_init_function_entry {
- /* Function to create a member of the pdb_methods list */
- const struct registry_ops *functions;
- struct reg_init_function_entry *prev, *next;
-};
-
-/* Used internally */
-#define SMB_REG_ASSERT(a) { if(!(a)) { DEBUG(0,("%s failed! (%s:%d)", #a, __FILE__, __LINE__)); }}
-
-#endif /* _REGISTRY_H */
diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk
index 8100c798e6..659e705d5d 100644
--- a/source4/lib/registry/config.mk
+++ b/source4/lib/registry/config.mk
@@ -60,7 +60,6 @@ REQUIRED_SUBSYSTEMS = \
INIT_OBJ_FILES = \
lib/registry/common/reg_interface.o
ADD_OBJ_FILES = \
- lib/registry/common/reg_objects.o \
lib/registry/common/reg_util.o
REQUIRED_SUBSYSTEMS = \
LIBBASIC
diff --git a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c
index b2bd34bf71..95d4c47af0 100644
--- a/source4/lib/registry/reg_backend_dir/reg_backend_dir.c
+++ b/source4/lib/registry/reg_backend_dir/reg_backend_dir.c
@@ -19,13 +19,12 @@
*/
#include "includes.h"
-#include "lib/registry/common/registry.h"
-static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32_t access_mask, SEC_DESC *desc, REG_KEY **result)
+static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, uint32_t access_mask, SEC_DESC *desc, struct registry_key **result)
{
char *path;
int ret;
- asprintf(&path, "%s%s\\%s", parent->handle->location, reg_key_get_path(parent), name);
+ asprintf(&path, "%s%s\\%s", parent->hive->location, parent->path, name);
path = reg_path_win2unix(path);
ret = mkdir(path, 0700);
SAFE_FREE(path);
@@ -33,19 +32,16 @@ static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32_t access
return WERR_INVALID_PARAM;
}
-static WERROR reg_dir_del_key(REG_KEY *k)
+static WERROR reg_dir_del_key(struct registry_key *k)
{
return (rmdir((char *)k->backend_data) == 0)?WERR_OK:WERR_GENERAL_FAILURE;
}
-static WERROR reg_dir_open_key(REG_HANDLE *h, int hive, const char *name, REG_KEY **subkey)
+static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **subkey)
{
DIR *d;
char *fullpath;
- REG_KEY *ret;
- TALLOC_CTX *mem_ctx;
-
- if(hive != 0) return WERR_NO_MORE_ITEMS;
+ struct registry_key *ret;
if(!name) {
DEBUG(0, ("NULL pointer passed as directory name!"));
@@ -53,33 +49,28 @@ static WERROR reg_dir_open_key(REG_HANDLE *h, int hive, const char *name, REG_KE
}
- mem_ctx = talloc_init("tmp");
fullpath = talloc_asprintf(mem_ctx, "%s%s", h->location, name);
fullpath = reg_path_win2unix(fullpath);
d = opendir(fullpath);
if(!d) {
DEBUG(3,("Unable to open '%s': %s\n", fullpath, strerror(errno)));
- talloc_destroy(mem_ctx);
return WERR_BADFILE;
}
closedir(d);
- ret = reg_key_new_abs(name, h, fullpath);
- talloc_steal(ret->mem_ctx, fullpath);
- talloc_destroy(mem_ctx);
+ ret = talloc_p(mem_ctx, struct registry_key);
+ ret->hive = h;
+ ret->path = fullpath;
*subkey = ret;
return WERR_OK;
}
-static WERROR reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r)
+static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_key **key)
{
struct dirent *e;
- int max = 200;
char *fullpath = k->backend_data;
- REG_KEY **ar;
+ int i = 0;
DIR *d;
- (*count) = 0;
- ar = talloc(k->mem_ctx, sizeof(REG_KEY *) * max);
d = opendir(fullpath);
@@ -96,13 +87,15 @@ static WERROR reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r)
stat(thispath, &stbuf);
if(S_ISDIR(stbuf.st_mode)) {
- ar[(*count)] = reg_key_new_rel(e->d_name, k, NULL);
- ar[(*count)]->backend_data = talloc_strdup(ar[*count]->mem_ctx, thispath);
- if(ar[(*count)])(*count)++;
-
- if((*count) == max) {
- max+=200;
- ar = realloc(ar, sizeof(REG_KEY *) * max);
+ i++;
+ if(i == idx) {
+ (*key) = talloc_p(mem_ctx, struct registry_key);
+ (*key)->name = e->d_name;
+ (*key)->path = NULL;
+ (*key)->backend_data = talloc_strdup(mem_ctx, thispath);
+ SAFE_FREE(thispath);
+ closedir(d);
+ return WERR_OK;
}
}
@@ -112,44 +105,38 @@ static WERROR reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r)
closedir(d);
- *r = ar;
- return WERR_OK;
+ return WERR_NO_MORE_ITEMS;
}
-static WERROR reg_dir_open(REG_HANDLE *h, const char *loc, const char *credentials) {
- if(!loc) return WERR_INVALID_PARAM;
+static WERROR reg_dir_open(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **key)
+{
+ if(!h->location) return WERR_INVALID_PARAM;
+
+ *key = talloc_p(mem_ctx, struct registry_key);
+ (*key)->backend_data = talloc_strdup(mem_ctx, h->location);
return WERR_OK;
}
-static WERROR reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len)
+static WERROR reg_dir_set_value(struct registry_key *p, const char *name, int type, void *data, int len)
{
/* FIXME */
return WERR_NOT_SUPPORTED;
}
-static WERROR reg_dir_get_hive(REG_HANDLE *h, int hive, REG_KEY **key)
-{
- if(hive != 0) return WERR_NO_MORE_ITEMS;
- *key = reg_key_new_abs("", h, NULL);
- (*key)->backend_data = talloc_strdup((*key)->mem_ctx, h->location);
- return WERR_OK;
-}
-
-static WERROR reg_dir_del_value(REG_VAL *v)
+static WERROR reg_dir_del_value(struct registry_value *v)
{
/* FIXME*/
return WERR_NOT_SUPPORTED;
}
-static struct registry_ops reg_backend_dir = {
+static struct registry_operations reg_backend_dir = {
.name = "dir",
- .open_registry = reg_dir_open,
+ .open_hive = reg_dir_open,
.open_key = reg_dir_open_key,
- .get_hive = reg_dir_get_hive,
- .fetch_subkeys = reg_dir_fetch_subkeys,
.add_key = reg_dir_add_key,
.del_key = reg_dir_del_key,
- .add_value = reg_dir_add_value,
+ .get_subkey_by_index = reg_dir_key_by_index,
+ .set_value = reg_dir_set_value,
.del_value = reg_dir_del_value,
};
diff --git a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c
index 15a8319711..d8c8d951c1 100644
--- a/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c
+++ b/source4/lib/registry/reg_backend_gconf/reg_backend_gconf.c
@@ -19,7 +19,6 @@
*/
#include "includes.h"
-#include "lib/registry/common/registry.h"
#include <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
diff --git a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c
index 47cb60d711..e0f65f2c37 100644
--- a/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c
+++ b/source4/lib/registry/reg_backend_ldb/reg_backend_ldb.c
@@ -19,7 +19,6 @@
*/
#include "includes.h"
-#include "lib/registry/common/registry.h"
static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char *add)
{
@@ -55,40 +54,46 @@ static char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path, const char *
return ret;
}
+
+static int ldb_close_registry(void *data)
+{
+ ldb_close((struct ldb_context *)data);
+ return 0;
+}
+
+
/*
* Saves the dn as private_data for every key/val
*/
-static WERROR ldb_open_registry(REG_HANDLE *handle, const char *location, const char *credentials)
+static WERROR ldb_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *hive, struct registry_key **k)
{
struct ldb_context *c;
- if (!location) return WERR_INVALID_PARAM;
- c = ldb_connect(location, 0, NULL);
+ if (!hive->location) return WERR_INVALID_PARAM;
+ c = ldb_connect(hive->location, 0, NULL);
ldb_set_debug_stderr(c);
+
if(!c) return WERR_FOOBAR;
- handle->backend_data = c;
+ hive->backend_data = c;
+ talloc_set_destructor(c, ldb_close_registry);
return WERR_OK;
}
-static WERROR ldb_close_registry(REG_HANDLE *h)
-{
- ldb_close((struct ldb_context *)h->backend_data);
- return WERR_OK;
-}
-
-static WERROR ldb_add_key(REG_KEY *p, const char *name, uint32_t access_mask, SEC_DESC *sec, REG_KEY **new)
+static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, struct registry_key *p, const char *name, uint32_t access_mask, SEC_DESC *sec, struct registry_key **new)
{
return WERR_NOT_SUPPORTED;
}
-static WERROR ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys)
+#if 0
+FIXME
+static WERROR ldb_fetch_subkeys(struct registry_key *k, int *count, struct registry_key ***subkeys)
{
- struct ldb_context *c = k->handle->backend_data;
+ struct ldb_context *c = k->hive->backend_data;
int ret, i, j;
struct ldb_message **msg;
@@ -99,7 +104,7 @@ static WERROR ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys)
return WERR_FOOBAR;
}
- *subkeys = talloc_array_p(k->mem_ctx, REG_KEY *, ret);
+ *subkeys = talloc_array_p(k->mem_ctx, struct registry_key *, ret);
j = 0;
for(i = 0; i < ret; i++) {
struct ldb_message_element *el;
@@ -121,9 +126,9 @@ static WERROR ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys)
return WERR_OK;
}
-static WERROR ldb_fetch_values(REG_KEY *k, int *count, REG_VAL ***values)
+static WERROR ldb_fetch_values(struct registry_key *k, int *count, REG_VAL ***values)
{
- struct ldb_context *c = k->handle->backend_data;
+ struct ldb_context *c = k->hive->backend_data;
int ret, i, j;
struct ldb_message **msg;
@@ -156,21 +161,14 @@ static WERROR ldb_fetch_values(REG_KEY *k, int *count, REG_VAL ***values)
return WERR_OK;
}
-static WERROR ldb_get_hive(REG_HANDLE *h, int num, REG_KEY **key)
-{
- if(num != 0) return WERR_NO_MORE_ITEMS;
- *key = reg_key_new_abs("", h, NULL);
- return WERR_OK;
-}
+#endif
-static WERROR ldb_open_key(REG_HANDLE *h, int num, const char *name, REG_KEY **key)
+static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **key)
{
struct ldb_context *c = h->backend_data;
struct ldb_message **msg;
char *ldap_path;
int ret;
- TALLOC_CTX *mem_ctx = talloc_init("ldb_path");
- if(num != 0) return WERR_NO_MORE_ITEMS;
ldap_path = reg_path_to_ldb(mem_ctx, name, NULL);
ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "*", NULL,&msg);
@@ -182,25 +180,20 @@ static WERROR ldb_open_key(REG_HANDLE *h, int num, const char *name, REG_KEY **k
return WERR_FOOBAR;
}
- *key = reg_key_new_abs(name, h, ldap_path);
- talloc_steal((*key)->mem_ctx, ldap_path);
- printf("Got something!\n");
+ *key = talloc_p(mem_ctx, struct registry_key);
/* FIXME */
ldb_search_free(c, msg);
- talloc_destroy(mem_ctx);
return WERR_OK;
}
-static struct registry_ops reg_backend_ldb = {
+static struct registry_operations reg_backend_ldb = {
.name = "ldb",
- .open_registry = ldb_open_registry,
- .get_hive = ldb_get_hive,
- .close_registry = ldb_close_registry,
+ .open_hive = ldb_open_hive,
.open_key = ldb_open_key,
- .fetch_subkeys = ldb_fetch_subkeys,
- .fetch_values = ldb_fetch_values,
+/* .fetch_subkeys = ldb_fetch_subkeys,
+ .fetch_values = ldb_fetch_values,*/
.add_key = ldb_add_key,
};
diff --git a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c
index ee9f8bf24f..c271c55991 100644
--- a/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c
+++ b/source4/lib/registry/reg_backend_nt4/reg_backend_nt4.c
@@ -304,9 +304,9 @@ Hope this helps.... (Although it was "fun" for me to uncover this things,
*************************************************************************/
#include "includes.h"
-#include "lib/registry/common/registry.h"
#define REG_KEY_LIST_SIZE 10
+#define FLAG_HAS_NAME 0x01
/*FIXME*/
/*
@@ -514,7 +514,7 @@ static BOOL nt_create_ace(SEC_ACE *ace, int type, int flags, uint32_t perms, con
/*
* Create a default ACL
*/
-static SEC_ACL *nt_create_default_acl(REG_HANDLE *regf)
+static SEC_ACL *nt_create_default_acl(struct registry_hive *regf)
{
SEC_ACE aces[8];
@@ -534,7 +534,7 @@ static SEC_ACL *nt_create_default_acl(REG_HANDLE *regf)
* Create a default security descriptor. We pull in things from env
* if need be
*/
-static SEC_DESC *nt_create_def_sec_desc(REG_HANDLE *regf)
+static SEC_DESC *nt_create_def_sec_desc(struct registry_hive *regf)
{
SEC_DESC *tmp;
@@ -559,7 +559,7 @@ static SEC_DESC *nt_create_def_sec_desc(REG_HANDLE *regf)
* says, but the Owner and Group SIDs can be overwridden from the command line
* and additional ACEs can be applied from the command line etc.
*/
-static KEY_SEC_DESC *nt_inherit_security(REG_KEY *key)
+static KEY_SEC_DESC *nt_inherit_security(struct registry_key *key)
{
if (!key) return NULL;
@@ -570,7 +570,7 @@ static KEY_SEC_DESC *nt_inherit_security(REG_KEY *key)
* Create an initial security descriptor and init other structures, if needed
* We assume that the initial security stuff is empty ...
*/
-static KEY_SEC_DESC *nt_create_init_sec(REG_HANDLE *h)
+static KEY_SEC_DESC *nt_create_init_sec(struct registry_hive *h)
{
REGF *regf = h->backend_data;
KEY_SEC_DESC *tsec = NULL;
@@ -618,7 +618,7 @@ static KEY_SEC_DESC *nt_create_init_sec(REG_HANDLE *h)
/* Get the header of the registry. Return a pointer to the structure
* If the mmap'd area has not been allocated, then mmap the input file
*/
-static REGF_HDR *nt_get_regf_hdr(REG_HANDLE *h)
+static REGF_HDR *nt_get_regf_hdr(struct registry_hive *h)
{
REGF *regf = h->backend_data;
SMB_REG_ASSERT(regf);
@@ -676,7 +676,7 @@ static int valid_regf_hdr(REGF_HDR *regf_hdr)
/*
* Create a new entry in the map, and increase the size of the map if needed
*/
-static SK_MAP *alloc_sk_map_entry(REG_HANDLE *h, KEY_SEC_DESC *tmp, int sk_off)
+static SK_MAP *alloc_sk_map_entry(struct registry_hive *h, KEY_SEC_DESC *tmp, int sk_off)
{
REGF *regf = h->backend_data;
if (!regf->sk_map) { /* Allocate a block of 10 */
@@ -731,7 +731,7 @@ KEY_SEC_DESC *lookup_sec_key(SK_MAP *sk_map, int count, int sk_off)
/*
* Allocate a KEY_SEC_DESC if we can't find one in the map
*/
-static KEY_SEC_DESC *lookup_create_sec_key(REG_HANDLE *h, SK_MAP *sk_map, int sk_off)
+static KEY_SEC_DESC *lookup_create_sec_key(struct registry_hive *h, SK_MAP *sk_map, int sk_off)
{
REGF *regf = h->backend_data;
KEY_SEC_DESC *tmp = lookup_sec_key(regf->sk_map, regf->sk_count, sk_off);
@@ -750,7 +750,7 @@ static KEY_SEC_DESC *lookup_create_sec_key(REG_HANDLE *h, SK_MAP *sk_map, int sk
}
}
-static SEC_DESC *process_sec_desc(REG_HANDLE *regf, SEC_DESC *sec_desc)
+static SEC_DESC *process_sec_desc(struct registry_hive *regf, SEC_DESC *sec_desc)
{
SEC_DESC *tmp = NULL;
@@ -790,7 +790,7 @@ static SEC_DESC *process_sec_desc(REG_HANDLE *regf, SEC_DESC *sec_desc)
return tmp;
}
-static KEY_SEC_DESC *process_sk(REG_HANDLE *regf, SK_HDR *sk_hdr, int sk_off, int size)
+static KEY_SEC_DESC *process_sk(struct registry_hive *regf, SK_HDR *sk_hdr, int sk_off, int size)
{
KEY_SEC_DESC *tmp = NULL;
int sk_next_off, sk_prev_off, sk_size;
@@ -879,38 +879,34 @@ static KEY_SEC_DESC *process_sk(REG_HANDLE *regf, SK_HDR *sk_hdr, int sk_off, in
/*
* Process a VK header and return a value
*/
-static WERROR vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size, REG_VAL **value)
+static WERROR vk_to_val(TALLOC_CTX *mem_ctx, struct registry_key *parent, VK_HDR *vk_hdr, int size, struct registry_value **value)
{
- char val_name[1024];
- REGF *regf = parent->handle->backend_data;
+ REGF *regf = parent->hive->backend_data;
int nam_len, dat_len, flag, dat_type, dat_off, vk_id;
- REG_VAL *tmp = NULL;
+ struct registry_value *tmp = NULL;
if (!vk_hdr) return WERR_INVALID_PARAM;
if ((vk_id = SVAL(&vk_hdr->VK_ID,0)) != str_to_dword("vk")) {
DEBUG(0, ("Unrecognized VK header ID: %0X, block: %0X, %s\n",
- vk_id, (int)vk_hdr, parent->handle->location));
+ vk_id, (int)vk_hdr, parent->hive->location));
return WERR_GENERAL_FAILURE;
}
nam_len = SVAL(&vk_hdr->nam_len,0);
- val_name[nam_len] = '\0';
flag = SVAL(&vk_hdr->flag,0);
dat_type = IVAL(&vk_hdr->dat_type,0);
dat_len = IVAL(&vk_hdr->dat_len,0); /* If top bit, offset contains data */
dat_off = IVAL(&vk_hdr->dat_off,0);
- tmp = reg_val_new(parent, NULL);
- tmp->has_name = flag;
+ tmp = talloc_p(mem_ctx, struct registry_value);
tmp->data_type = dat_type;
- if (flag & 0x01) {
- strncpy(val_name, vk_hdr->dat_name, nam_len);
- tmp->name = strdup(val_name);
+ if (flag & FLAG_HAS_NAME) {
+ tmp->name = talloc_strndup(mem_ctx, vk_hdr->dat_name, nam_len);
+ } else {
+ tmp->name = NULL;
}
- else
- strncpy(val_name, "<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,
diff --git a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c
index 0d8d935a4a..1c887fc411 100644
--- a/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c
+++ b/source4/lib/registry/reg_backend_rpc/reg_backend_rpc.c
@@ -18,7 +18,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "includes.h"
-#include "lib/registry/common/registry.h"
/**
* This is the RPC backend for the registry library.
@@ -37,7 +36,7 @@ static void init_winreg_String(struct winreg_String *name, const char *s)
}
-#define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, REG_KEY *h, struct policy_handle *hnd) \
+#define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *hnd) \
{ \
struct winreg_Open ## u r; \
struct winreg_OpenUnknown unknown; \
@@ -49,7 +48,7 @@ static void init_winreg_String(struct winreg_String *name, const char *s)
r.in.access_required = SEC_RIGHTS_MAXIMUM_ALLOWED; \
r.out.handle = hnd;\
\
- status = dcerpc_winreg_Open ## u(p, h->mem_ctx, &r); \
+ status = dcerpc_winreg_Open ## u(p, mem_ctx, &r); \
if (NT_STATUS_IS_ERR(status)) {\
DEBUG(0,("Error executing open\n"));\
return ntstatus_to_werror(status);\
@@ -74,7 +73,7 @@ struct rpc_key_data {
struct {
const char *name;
- WERROR (*open) (struct dcerpc_pipe *p, REG_KEY *k, struct policy_handle *h);
+ WERROR (*open) (struct dcerpc_pipe *p, TALLOC_CTX *, struct policy_handle *h);
} known_hives[] = {
{ "HKEY_LOCAL_MACHINE", open_HKLM },
{ "HKEY_CURRENT_USER", open_HKCU },
@@ -84,122 +83,124 @@ struct {
{ NULL, NULL }
};
-static WERROR rpc_query_key(REG_KEY *k);
+static WERROR rpc_query_key(struct registry_key *k);
-static WERROR rpc_open_registry(REG_HANDLE *h, const char *location, const char *credentials)
+WERROR rpc_list_hives (TALLOC_CTX *mem_ctx, const char *location, const char *credentials, char ***hives)
+{
+ int i = 0;
+ *hives = talloc_p(mem_ctx, char *);
+ for(i = 0; known_hives[i].name; i++) {
+ *hives = talloc_realloc_p(*hives, char *, i+2);
+ (*hives)[i] = talloc_strdup(mem_ctx, known_hives[i].name);
+ }
+ (*hives)[i] = NULL;
+ return WERR_OK;
+}
+
+static WERROR rpc_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **k)
{
NTSTATUS status;
char *user, *pass;
+ struct rpc_key_data *mykeydata;
+ struct dcerpc_pipe *p;
+ int n;
- if(!credentials || !location) return WERR_INVALID_PARAM;
+ if(!h->credentials || !h->location) return WERR_INVALID_PARAM;
- user = talloc_strdup(h->mem_ctx, credentials);
+ user = talloc_strdup(mem_ctx, h->credentials);
pass = strchr(user, '%');
- *pass = '\0'; pass++;
+ if(pass)
+ {
+ *pass = '\0'; pass++;
+ } else {
+ pass = "";
+ }
- status = dcerpc_pipe_connect((struct dcerpc_pipe **)&h->backend_data, h->location,
+ status = dcerpc_pipe_connect(&p, h->location,
DCERPC_WINREG_UUID,
DCERPC_WINREG_VERSION,
lp_workgroup(),
user, pass);
-
- return ntstatus_to_werror(status);
-}
-static WERROR rpc_get_hive(REG_HANDLE *h, int n, REG_KEY **k)
-{
- struct rpc_key_data *mykeydata;
- WERROR error;
+ h->backend_data = p;
+
+ if(NT_STATUS_IS_ERR(status)) return ntstatus_to_werror(status);
+
+ for(n = 0; known_hives[n].name; n++)
+ {
+ if(!strcmp(known_hives[n].name, h->backend_hivename)) break;
+ }
+
if(!known_hives[n].name) return WERR_NO_MORE_ITEMS;
- *k = reg_key_new_abs(known_hives[n].name, h, NULL);
- (*k)->backend_data = mykeydata = talloc_p((*k)->mem_ctx, struct rpc_key_data);
+
+ *k = talloc_p(mem_ctx, struct registry_key);
+ (*k)->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data);
mykeydata->num_values = -1;
mykeydata->num_subkeys = -1;
- error = known_hives[n].open((struct dcerpc_pipe *)h->backend_data, *k, &mykeydata->pol);
- return error;
+ return known_hives[n].open((struct dcerpc_pipe *)h->backend_data, *k, &(mykeydata->pol));
}
-static WERROR rpc_close_registry(REG_HANDLE *h)
+static WERROR rpc_close_registry(struct registry_hive *h)
{
dcerpc_pipe_close((struct dcerpc_pipe *)h->backend_data);
return WERR_OK;
}
-static WERROR rpc_key_put_rpc_data(REG_KEY *k, struct rpc_key_data **data)
+static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k)
{
struct winreg_OpenKey r;
- WERROR error;
- REG_KEY *hivekey;
struct rpc_key_data *mykeydata;
- if(k->backend_data) {
- *data = k->backend_data;
- return WERR_OK;
- }
-
- k->backend_data = mykeydata = talloc_p(k->mem_ctx, struct rpc_key_data);
- *data = mykeydata;
+ k->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data);
mykeydata->num_values = -1;
mykeydata->num_subkeys = -1;
/* Then, open the handle using the hive */
memset(&r, 0, sizeof(struct winreg_OpenKey));
- error = rpc_get_hive(k->handle, k->hive, &hivekey);
- if(!W_ERROR_IS_OK(error))return error;
- r.in.handle = &(((struct rpc_key_data *)hivekey->backend_data)->pol);
- init_winreg_String(&r.in.keyname, reg_key_get_path(k));
+ r.in.handle = &(((struct rpc_key_data *)k->hive->root->backend_data)->pol);
+ init_winreg_String(&r.in.keyname, k->path);
r.in.unknown = 0x00000000;
r.in.access_mask = 0x02000000;
r.out.handle = &mykeydata->pol;
- dcerpc_winreg_OpenKey((struct dcerpc_pipe *)k->handle->backend_data, k->mem_ctx, &r);
+ dcerpc_winreg_OpenKey((struct dcerpc_pipe *)k->hive->backend_data, mem_ctx, &r);
return r.out.result;
}
-static WERROR rpc_open_key(REG_HANDLE *h, int hive, const char *name, REG_KEY **key)
+static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const char *name, struct registry_key **key)
{
struct rpc_key_data *mykeydata;
struct winreg_OpenKey r;
- REG_KEY *hivekey;
- WERROR error;
-
- *key = reg_key_new_abs(name, h, NULL);
- (*key)->backend_data = mykeydata = talloc_p((*key)->mem_ctx, struct rpc_key_data);
+ *key = talloc_p(mem_ctx, struct registry_key);
+ (*key)->name = talloc_strdup(mem_ctx, name);
+
+ (*key)->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data);
mykeydata->num_values = -1;
mykeydata->num_subkeys = -1;
/* Then, open the handle using the hive */
memset(&r, 0, sizeof(struct winreg_OpenKey));
- error = rpc_get_hive(h, hive, &hivekey);
- if(!W_ERROR_IS_OK(error))return error;
- r.in.handle = &(((struct rpc_key_data *)hivekey->backend_data)->pol);
+ r.in.handle = &(((struct rpc_key_data *)h->root->backend_data)->pol);
init_winreg_String(&r.in.keyname, name);
r.in.unknown = 0x00000000;
r.in.access_mask = 0x02000000;
r.out.handle = &mykeydata->pol;
- dcerpc_winreg_OpenKey((struct dcerpc_pipe *)(*key)->handle->backend_data, (*key)->mem_ctx, &r);
+ dcerpc_winreg_OpenKey((struct dcerpc_pipe *)(h->backend_data), mem_ctx, &r);
return r.out.result;
}
-static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value)
+static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_value **value)
{
- struct winreg_EnumValue r;
- struct winreg_Uint8buf vb;
- struct winreg_EnumValueName vn;
- NTSTATUS status;
- struct rpc_key_data *mykeydata;
- uint32_t type = 0x0, requested_len = 0, returned_len = 0;
+ struct rpc_key_data *mykeydata = parent->backend_data;
+ uint32_t requested_len = 0;
WERROR error;
- error = rpc_key_put_rpc_data(parent, &mykeydata);
- if(!W_ERROR_IS_OK(error)) return error;
-
if(mykeydata->num_values == -1) {
error = rpc_query_key(parent);
if(!W_ERROR_IS_OK(error)) return error;
@@ -207,6 +208,7 @@ static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value)
requested_len = mykeydata->max_valdatalen;
+#if 0 /* EnumValue is not working yet ... */
r.in.handle = &mykeydata->pol;
r.in.enum_index = n;
r.in.type = r.out.type = &type;
@@ -225,7 +227,7 @@ static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value)
vb.max_len = mykeydata->max_valdatalen;
vb.offset = 0x0;
vb.len = 0x0;
- vb.buffer = talloc_array_p(parent->mem_ctx, uint8, mykeydata->max_valdatalen);
+ vb.buffer = talloc_array_p(mem_ctx, uint8, mykeydata->max_valdatalen);
r.in.value = r.out.value = &vb;
status = dcerpc_winreg_EnumValue((struct dcerpc_pipe *)parent->handle->backend_data, parent->mem_ctx, &r);
@@ -242,23 +244,20 @@ static WERROR rpc_get_value_by_index(REG_KEY *parent, int n, REG_VAL **value)
exit(1);
return WERR_OK;
}
+#endif
- return r.out.result;
+ return WERR_NOT_SUPPORTED;
}
-static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey)
+static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_key **subkey)
{
struct winreg_EnumKey r;
struct winreg_EnumKeyNameRequest keyname;
struct winreg_String classname;
struct winreg_Time tm;
struct rpc_key_data *mykeydata = parent->backend_data;
- WERROR error;
NTSTATUS status;
- error = rpc_key_put_rpc_data(parent, &mykeydata);
- if(!W_ERROR_IS_OK(error)) return error;
-
r.in.handle = &mykeydata->pol;
keyname.unknown = 0x0000020a;
init_winreg_String(&keyname.key_name, NULL);
@@ -271,40 +270,33 @@ static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey)
r.in.enum_index = n;
r.in.unknown = r.out.unknown = 0x0414;
r.in.key_name_len = r.out.key_name_len = 0;
- status = dcerpc_winreg_EnumKey((struct dcerpc_pipe *)parent->handle->backend_data, parent->mem_ctx, &r);
+ status = dcerpc_winreg_EnumKey((struct dcerpc_pipe *)parent->hive->backend_data, mem_ctx, &r);
if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
- *subkey = reg_key_new_rel(r.out.out_name->name, parent, NULL);
+ if(parent->hive->root == parent)
+ return rpc_open_key(mem_ctx, parent->hive, talloc_strdup(mem_ctx, r.out.out_name->name), subkey);
+ return rpc_open_key(mem_ctx, parent->hive, talloc_asprintf(mem_ctx, "%s\\%s", parent->path, r.out.out_name->name), subkey);
}
return r.out.result;
}
-static WERROR rpc_add_key(REG_KEY *parent, const char *name, uint32_t access_mask, SEC_DESC *sec, REG_KEY **key)
+static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char *name, uint32_t access_mask, SEC_DESC *sec, struct registry_key **key)
{
- struct rpc_key_data *mykeydata;
- WERROR error;
-
- error = rpc_key_put_rpc_data(parent, &mykeydata);
- if(!W_ERROR_IS_OK(error)) return error;
-
- /* FIXME */
return WERR_NOT_SUPPORTED;
}
-static WERROR rpc_query_key(REG_KEY *k)
+static WERROR rpc_query_key(struct registry_key *k)
{
NTSTATUS status;
- WERROR error;
struct winreg_QueryInfoKey r;
- struct rpc_key_data *mykeydata;
-
- error = rpc_key_put_rpc_data(k, &mykeydata);
- if(!W_ERROR_IS_OK(error)) return error;
+ struct rpc_key_data *mykeydata = k->backend_data;
+ TALLOC_CTX *mem_ctx = talloc_init("query_key");
init_winreg_String(&r.in.class, NULL);
r.in.handle = &mykeydata->pol;
- status = dcerpc_winreg_QueryInfoKey((struct dcerpc_pipe *)k->handle->backend_data, k->mem_ctx, &r);
+ status = dcerpc_winreg_QueryInfoKey((struct dcerpc_pipe *)(k->hive->backend_data), mem_ctx, &r);
+ talloc_destroy(mem_ctx);
if (!NT_STATUS_IS_OK(status)) {
printf("QueryInfoKey failed - %s\n", nt_errstr(status));
@@ -321,40 +313,37 @@ static WERROR rpc_query_key(REG_KEY *k)
return r.out.result;
}
-static WERROR rpc_del_key(REG_KEY *k)
+static WERROR rpc_del_key(struct registry_key *k)
{
NTSTATUS status;
struct rpc_key_data *mykeydata = k->backend_data;
struct winreg_DeleteKey r;
- REG_KEY *parent;
+ struct registry_key *parent;
WERROR error;
+ TALLOC_CTX *mem_ctx = talloc_init("del_key");
- error = reg_key_get_parent(k, &parent);
- if(!W_ERROR_IS_OK(error)) return error;
+ error = reg_key_get_parent(mem_ctx, k, &parent);
+ if(!W_ERROR_IS_OK(error)) {
+ talloc_destroy(mem_ctx);
+ return error;
+ }
+
+ mykeydata = parent->backend_data;
- error = rpc_key_put_rpc_data(parent, &mykeydata);
- if(!W_ERROR_IS_OK(error)) return error;
-
r.in.handle = &mykeydata->pol;
init_winreg_String(&r.in.key, k->name);
- status = dcerpc_winreg_DeleteKey((struct dcerpc_pipe *)k->handle->backend_data, k->mem_ctx, &r);
+ status = dcerpc_winreg_DeleteKey((struct dcerpc_pipe *)k->hive->backend_data, mem_ctx, &r);
- return r.out.result;
-}
+ talloc_destroy(mem_ctx);
-static void rpc_close_key(REG_KEY *k)
-{
- reg_key_free(k);
+ return r.out.result;
}
-static WERROR rpc_num_values(REG_KEY *key, int *count) {
+static WERROR rpc_num_values(struct registry_key *key, int *count) {
struct rpc_key_data *mykeydata = key->backend_data;
WERROR error;
- error = rpc_key_put_rpc_data(key, &mykeydata);
- if(!W_ERROR_IS_OK(error)) return error;
-
if(mykeydata->num_values == -1) {
error = rpc_query_key(key);
if(!W_ERROR_IS_OK(error)) return error;
@@ -364,13 +353,10 @@ static WERROR rpc_num_values(REG_KEY *key, int *count) {
return WERR_OK;
}
-static WERROR rpc_num_subkeys(REG_KEY *key, int *count) {
+static WERROR rpc_num_subkeys(struct registry_key *key, int *count) {
struct rpc_key_data *mykeydata = key->backend_data;
WERROR error;
- error = rpc_key_put_rpc_data(key, &mykeydata);
- if(!W_ERROR_IS_OK(error)) return error;
-
if(mykeydata->num_subkeys == -1) {
error = rpc_query_key(key);
if(!W_ERROR_IS_OK(error)) return error;
@@ -380,19 +366,17 @@ static WERROR rpc_num_subkeys(REG_KEY *key, int *count) {
return WERR_OK;
}
-static struct registry_ops reg_backend_rpc = {
+static struct registry_operations reg_backend_rpc = {
.name = "rpc",
- .open_registry = rpc_open_registry,
- .close_registry = rpc_close_registry,
- .get_hive = rpc_get_hive,
+ .open_hive = rpc_open_hive,
.open_key = rpc_open_key,
.get_subkey_by_index = rpc_get_subkey_by_index,
.get_value_by_index = rpc_get_value_by_index,
.add_key = rpc_add_key,
.del_key = rpc_del_key,
- .free_key_backend_data = rpc_close_key,
.num_subkeys = rpc_num_subkeys,
.num_values = rpc_num_values,
+ .list_available_hives = rpc_list_hives,
};
NTSTATUS registry_rpc_init(void)
diff --git a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c
index f392759b8d..2184a8855d 100644
--- a/source4/lib/registry/reg_backend_w95/reg_backend_w95.c
+++ b/source4/lib/registry/reg_backend_w95/reg_backend_w95.c
@@ -20,7 +20,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "includes.h"
-#include "lib/registry/common/registry.h"
/**
* The registry starts with a header that contains pointers to
@@ -179,67 +178,18 @@ static void parse_rgdb_block(CREG *creg, RGDB_HDR *rgdb_hdr)
}
}
-static WERROR w95_open_root (REG_HANDLE *h, int hive, REG_KEY **key)
-{
- CREG *creg = h->backend_data;
-
- if(hive != 0) return WERR_NO_MORE_ITEMS;
-
- /* First element in rgkn should be root key */
- *key = reg_key_new_abs("", h, LOCN_RGKN(creg, sizeof(RGKN_HDR)));
-
- return WERR_OK;
-}
-
-static WERROR w95_get_subkey_by_index (REG_KEY *parent, int n, REG_KEY **key)
-{
- CREG *creg = parent->handle->backend_data;
- RGKN_KEY *rgkn_key = parent->backend_data;
- RGKN_KEY *child;
- DWORD child_offset;
- DWORD cur = 0;
-
- /* Get id of first child */
- child_offset = rgkn_key->first_child_offset;
-
- while(child_offset != 0xFFFFFFFF) {
- child = LOCN_RGKN(creg, child_offset);
-
- /* n == cur ? return! */
- if(cur == n) {
- RGDB_KEY *rgdb_key;
- char *name;
- rgdb_key = LOCN_RGDB_KEY(creg, child->id.rgdb, child->id.id);
- if(!rgdb_key) {
- DEBUG(0, ("Can't find %d,%d in RGDB table!\n", child->id.rgdb, child->id.id));
- return WERR_FOOBAR;
- }
- name = strndup((char *)rgdb_key + sizeof(RGDB_KEY), rgdb_key->name_len);
- *key = reg_key_new_rel(name, parent, child);
- SAFE_FREE(name);
- return WERR_OK;
- }
-
- cur++;
-
- child_offset = child->next_offset;
- }
-
- return WERR_NO_MORE_ITEMS;
-}
-
-static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *credentials)
+static WERROR w95_open_reg (TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **root)
{
CREG *creg;
DWORD creg_id, rgkn_id;
DWORD i;
DWORD offset;
- creg = talloc_p(h->mem_ctx, CREG);
+ creg = talloc_p(mem_ctx, CREG);
memset(creg, 0, sizeof(CREG));
h->backend_data = creg;
- if((creg->fd = open(location, O_RDONLY, 0000)) < 0) {
+ if((creg->fd = open(h->location, O_RDONLY, 0000)) < 0) {
return WERR_FOOBAR;
}
@@ -250,7 +200,7 @@ static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *cre
creg->base = mmap(0, creg->sbuf.st_size, PROT_READ, MAP_SHARED, creg->fd, 0);
if ((int)creg->base == 1) {
- DEBUG(0,("Could not mmap file: %s, %s\n", location, strerror(errno)));
+ DEBUG(0,("Could not mmap file: %s, %s\n", h->location, strerror(errno)));
return WERR_FOOBAR;
}
@@ -258,7 +208,7 @@ static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *cre
if ((creg_id = IVAL(&creg->creg_hdr->CREG_ID,0)) != str_to_dword("CREG")) {
DEBUG(0, ("Unrecognized Windows 95 registry header id: 0x%0X, %s\n",
- creg_id, location));
+ creg_id, h->location));
return WERR_FOOBAR;
}
@@ -266,7 +216,7 @@ static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *cre
if ((rgkn_id = IVAL(&creg->rgkn_hdr->RGKN_ID,0)) != str_to_dword("RGKN")) {
DEBUG(0, ("Unrecognized Windows 95 registry key index id: 0x%0X, %s\n",
- rgkn_id, location));
+ rgkn_id, h->location));
return WERR_FOOBAR;
}
@@ -282,7 +232,7 @@ static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *cre
}
#endif
- creg->rgdb_keys = talloc_array_p(h->mem_ctx, RGDB_KEY **, creg->creg_hdr->num_rgdb);
+ creg->rgdb_keys = talloc_array_p(mem_ctx, RGDB_KEY **, creg->creg_hdr->num_rgdb);
offset = 0;
DEBUG(3, ("Reading %d rgdb entries\n", creg->creg_hdr->num_rgdb));
@@ -291,14 +241,14 @@ static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *cre
if(strncmp((char *)&(rgdb_hdr->RGDB_ID), "RGDB", 4)) {
DEBUG(0, ("unrecognized rgdb entry: %4d, %s\n",
- rgdb_hdr->RGDB_ID, location));
+ rgdb_hdr->RGDB_ID, h->location));
return WERR_FOOBAR;
} else {
DEBUG(3, ("Valid rgdb entry, first free id: %d, max id: %d\n", rgdb_hdr->first_free_id, rgdb_hdr->max_id));
}
- creg->rgdb_keys[i] = talloc_array_p(h->mem_ctx, RGDB_KEY *, rgdb_hdr->max_id+1);
+ creg->rgdb_keys[i] = talloc_array_p(mem_ctx, RGDB_KEY *, rgdb_hdr->max_id+1);
memset(creg->rgdb_keys[i], 0, sizeof(RGDB_KEY *) * (rgdb_hdr->max_id+1));
parse_rgdb_block(creg, rgdb_hdr);
@@ -306,11 +256,51 @@ static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *cre
offset+=rgdb_hdr->size;
}
-
+ /* First element in rgkn should be root key */
+ *root = talloc_p(mem_ctx, struct registry_key);
+ (*root)->name = NULL;
+ (*root)->backend_data = LOCN_RGKN(creg, sizeof(RGKN_HDR));
+
return WERR_OK;
}
-static WERROR w95_close_reg(REG_HANDLE *h)
+static WERROR w95_get_subkey_by_index (TALLOC_CTX *mem_ctx, struct registry_key *parent, int n, struct registry_key **key)
+{
+ CREG *creg = parent->hive->backend_data;
+ RGKN_KEY *rgkn_key = parent->backend_data;
+ RGKN_KEY *child;
+ DWORD child_offset;
+ DWORD cur = 0;
+
+ /* Get id of first child */
+ child_offset = rgkn_key->first_child_offset;
+
+ while(child_offset != 0xFFFFFFFF) {
+ child = LOCN_RGKN(creg, child_offset);
+
+ /* n == cur ? return! */
+ if(cur == n) {
+ RGDB_KEY *rgdb_key;
+ rgdb_key = LOCN_RGDB_KEY(creg, child->id.rgdb, child->id.id);
+ if(!rgdb_key) {
+ DEBUG(0, ("Can't find %d,%d in RGDB table!\n", child->id.rgdb, child->id.id));
+ return WERR_FOOBAR;
+ }
+ *key = talloc_p(mem_ctx, struct registry_key);
+ (*key)->backend_data = child;
+ (*key)->name = talloc_strndup(mem_ctx, (char *)rgdb_key + sizeof(RGDB_KEY), rgdb_key->name_len);
+ return WERR_OK;
+ }
+
+ cur++;
+
+ child_offset = child->next_offset;
+ }
+
+ return WERR_NO_MORE_ITEMS;
+}
+
+static WERROR w95_close_reg(struct registry_hive *h)
{
CREG *creg = h->backend_data;
if (creg->base) munmap(creg->base, creg->sbuf.st_size);
@@ -319,47 +309,51 @@ static WERROR w95_close_reg(REG_HANDLE *h)
return WERR_OK;
}
+static WERROR w95_num_values(struct registry_key *k, int *count)
+{
+ RGKN_KEY *rgkn_key = k->backend_data;
+ RGDB_KEY *rgdb_key = LOCN_RGDB_KEY((CREG *)k->hive->backend_data, rgkn_key->id.rgdb, rgkn_key->id.id);
+
+ if(!rgdb_key) return WERR_FOOBAR;
+
+ *count = rgdb_key->num_values;
+
+ return WERR_OK;
+}
-static WERROR w95_fetch_values(REG_KEY *k, int *count, REG_VAL ***values)
+static WERROR w95_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, int idx, struct registry_value **value)
{
RGKN_KEY *rgkn_key = k->backend_data;
DWORD i;
DWORD offset = 0;
- RGDB_KEY *rgdb_key = LOCN_RGDB_KEY((CREG *)k->handle->backend_data, rgkn_key->id.rgdb, rgkn_key->id.id);
+ RGDB_KEY *rgdb_key = LOCN_RGDB_KEY((CREG *)k->hive->backend_data, rgkn_key->id.rgdb, rgkn_key->id.id);
+ RGDB_VALUE *curval;
if(!rgdb_key) return WERR_FOOBAR;
- *count = rgdb_key->num_values;
+ if(idx >= rgdb_key->num_values) return WERR_NO_MORE_ITEMS;
- if((*count) == 0) return WERR_OK;
+ for(i = 0; i < idx; i++) {
+ curval = (RGDB_VALUE *)(((char *)rgdb_key) + sizeof(RGDB_KEY) + rgdb_key->name_len + offset);
+ offset+=sizeof(RGDB_VALUE) + curval->name_len + curval->data_len;
+ }
- (*values) = talloc_array_p(k->mem_ctx, REG_VAL *, (*count)+1);
- for(i = 0; i < rgdb_key->num_values; i++) {
- RGDB_VALUE *val = (RGDB_VALUE *)(((char *)rgdb_key) + sizeof(RGDB_KEY) + rgdb_key->name_len + offset);
- (*values)[i] = reg_val_new(k, val);
-
- /* Name */
- (*values)[i]->name = talloc_strndup(k->mem_ctx, (char *)val+sizeof(RGDB_VALUE), val->name_len);
+ *value = talloc_p(mem_ctx, struct registry_value);
+ (*value)->backend_data = curval;
+ (*value)->name = talloc_strndup(mem_ctx, (char *)curval+sizeof(RGDB_VALUE), curval->name_len);
- /* Value */
- (*values)[i]->data_len = val->data_len;
- (*values)[i]->data_blk = talloc_memdup((*values)[i]->mem_ctx, (char *)val+sizeof(RGDB_VALUE)+val->name_len, val->data_len);
-
- /* Type */
- (*values)[i]->data_type = val->type;
-
- offset+=sizeof(RGDB_VALUE) + val->name_len + val->data_len;
- }
+ (*value)->data_len = curval->data_len;
+ (*value)->data_blk = talloc_memdup(mem_ctx, (char *)curval+sizeof(RGDB_VALUE)+curval->name_len, curval->data_len);
+ (*value)->data_type = curval->type;
return WERR_OK;
}
-static struct registry_ops reg_backend_w95 = {
+static struct registry_operations reg_backend_w95 = {
.name = "w95",
- .open_registry = w95_open_reg,
- .close_registry = w95_close_reg,
- .get_hive = w95_open_root,
- .fetch_values = w95_fetch_values,
+ .open_hive = w95_open_reg,
+ .get_value_by_index = w95_get_value_by_id,
+ .num_values = w95_num_values,
.get_subkey_by_index = w95_get_subkey_by_index,
};
diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c
index c46411ae31..524e538591 100644
--- a/source4/lib/registry/tools/regdiff.c
+++ b/source4/lib/registry/tools/regdiff.c
@@ -21,47 +21,57 @@
#include "includes.h"
-static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out)
+static void writediff(struct registry_key *oldkey, struct registry_key *newkey, FILE *out)
{
int i;
- REG_KEY *t1, *t2;
- REG_VAL *v1, *v2;
+ struct registry_key *t1, *t2;
+ struct registry_value *v1, *v2;
WERROR error1, error2;
+ TALLOC_CTX *mem_ctx = talloc_init("writediff");
- for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_subkey_by_index(oldkey, i, &t1)); i++) {
- error2 = reg_key_get_subkey_by_name(newkey, reg_key_name(t1), &t2);
+ for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_subkey_by_index(mem_ctx, oldkey, i, &t1)); i++) {
+ error2 = reg_key_get_subkey_by_name(mem_ctx, newkey, t1->name, &t2);
if(W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) {
- fprintf(out, "-%s\n", reg_key_get_path(t1)+1);
+ fprintf(out, "-%s\n", t1->path+1);
} else if(!W_ERROR_IS_OK(error2)) {
DEBUG(0, ("Error occured while getting subkey by name: %d\n", W_ERROR_V(error2)));
}
}
+ talloc_destroy(mem_ctx);
+
if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) {
DEBUG(0, ("Error occured while getting subkey by index: %d\n", W_ERROR_V(error1)));
return;
}
- for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_subkey_by_index(newkey, i, &t1)); i++) {
- error2 = reg_key_get_subkey_by_name(oldkey, reg_key_name(t1), &t2);
+ mem_ctx = talloc_init("writediff");
+
+ for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_subkey_by_index(mem_ctx, newkey, i, &t1)); i++) {
+ error2 = reg_key_get_subkey_by_name(mem_ctx, oldkey, t1->name, &t2);
if(W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) {
- fprintf(out, "\n[%s]\n", reg_key_get_path(t1)+1);
+ fprintf(out, "\n[%s]\n", t1->path+1);
} else if(!W_ERROR_IS_OK(error2)) {
DEBUG(0, ("Error occured while getting subkey by name: %d\n", W_ERROR_V(error2)));
}
writediff(t2, t1, out);
}
+ talloc_destroy(mem_ctx);
+
if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) {
DEBUG(0, ("Error occured while getting subkey by index: %d\n", W_ERROR_V(error1)));
return;
}
- for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(newkey, i, &v1)); i++) {
- error2 = reg_key_get_value_by_name(oldkey, reg_val_name(v1), &v2);
- if ((W_ERROR_IS_OK(error2) && (reg_val_size(v2) != reg_val_size(v1) || memcmp(reg_val_data_blk(v1), reg_val_data_blk(v2), reg_val_size(v1))))
+
+ mem_ctx = talloc_init("writediff");
+
+ for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(mem_ctx, newkey, i, &v1)); i++) {
+ error2 = reg_key_get_value_by_name(mem_ctx, oldkey, v1->name, &v2);
+ if ((W_ERROR_IS_OK(error2) && (v2->data_len != v1->data_len || memcmp(v1->data_blk, v2->data_blk, v1->data_len)))
|| W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) {
- fprintf(out, "\"%s\"=%s:%s\n", reg_val_name(v1), str_regtype(reg_val_type(v1)), reg_val_data_string(v1));
+ fprintf(out, "\"%s\"=%s:%s\n", v1->name, str_regtype(v1->data_type), reg_val_data_string(mem_ctx, v1));
}
if(!W_ERROR_IS_OK(error2) && !W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) {
@@ -69,22 +79,27 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out)
}
}
+ talloc_destroy(mem_ctx);
+
if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) {
DEBUG(0, ("Error occured while getting value by index: %d\n", W_ERROR_V(error1)));
return;
}
+ mem_ctx = talloc_init("writediff");
- for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(oldkey, i, &v1)); i++) {
- error2 = reg_key_get_value_by_name(newkey, reg_val_name(v1), &v2);
+ for(i = 0; W_ERROR_IS_OK(error1 = reg_key_get_value_by_index(mem_ctx, oldkey, i, &v1)); i++) {
+ error2 = reg_key_get_value_by_name(mem_ctx, newkey, v1->name, &v2);
if(W_ERROR_IS_OK(error2)) {
} else if(W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) {
- fprintf(out, "\"%s\"=-\n", reg_val_name(v1));
+ fprintf(out, "\"%s\"=-\n", v1->name);
} else {
DEBUG(0, ("Error occured while getting value by name: %d\n", W_ERROR_V(error2)));
}
}
+ talloc_destroy(mem_ctx);
+
if(!W_ERROR_EQUAL(error1, WERR_NO_MORE_ITEMS)) {
DEBUG(0, ("Error occured while getting value by index: %d\n", W_ERROR_V(error1)));
return;
@@ -100,8 +115,7 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out)
const char *credentials1= NULL, *credentials2 = NULL;
char *outputfile = NULL;
FILE *fd = stdout;
- REG_HANDLE *h1, *h2;
- REG_KEY *root1 = NULL, *root2;
+ struct registry_context *h1, *h2;
int from_null = 0;
int i;
WERROR error, error2;
@@ -114,6 +128,12 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out)
POPT_TABLEEND
};
+
+ if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
+ fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
+ }
+
+
pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0);
while((opt = poptGetNextOpt(pc)) != -1) {
@@ -140,7 +160,7 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out)
if(!backend1) backend1 = "dir";
- error = reg_open(backend1, location1, credentials1, &h1);
+ error = reg_open(&h1, backend1, location1, credentials1);
if(!W_ERROR_IS_OK(error)) {
fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location1, backend1);
return 1;
@@ -155,7 +175,7 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out)
if(!backend2) backend2 = "dir";
- error = reg_open(backend2, location2, credentials2, &h2);
+ error = reg_open(&h2, backend2, location2, credentials2);
if(!W_ERROR_IS_OK(error)) {
fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location2, backend2);
return 1;
@@ -176,20 +196,8 @@ static void writediff(REG_KEY *oldkey, REG_KEY *newkey, FILE *out)
error2 = error = WERR_OK;
- for(i = 0; ; i++) {
- if(backend1) error = reg_get_hive(h1, i, &root1);
- else root1 = NULL;
-
- if(!W_ERROR_IS_OK(error)) break;
-
- if(backend2) error2 = reg_get_hive(h2, i, &root2);
- else root2 = NULL;
-
- if(!W_ERROR_IS_OK(error2)) break;
-
- writediff(root1, root2, fd);
-
- if(!root1 && !root2) break;
+ for(i = 0; i < h1->num_hives && i < h2->num_hives; i++) {
+ writediff(h1->hives[i]->root, h2->hives[i]->root, fd);
}
fclose(fd);
diff --git a/source4/lib/registry/tools/regpatch.c b/source4/lib/registry/tools/regpatch.c
index 7eddea2b93..1b33628a71 100644
--- a/source4/lib/registry/tools/regpatch.c
+++ b/source4/lib/registry/tools/regpatch.c
@@ -664,12 +664,13 @@ static CMD_FILE *cmd_file_create(const char *file)
char *str_type(uint8_t type);
-static int nt_apply_reg_command_file(REG_HANDLE *r, const char *cmd_file_name)
+static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd_file_name)
{
CMD *cmd;
BOOL modified = False;
CMD_FILE *cmd_file = NULL;
- REG_KEY *tmp = NULL;
+ TALLOC_CTX *mem_ctx = talloc_init("apply_cmd_file");
+ struct registry_key *tmp = NULL;
WERROR error;
cmd_file = cmd_file_create(cmd_file_name);
@@ -680,12 +681,12 @@ static int nt_apply_reg_command_file(REG_HANDLE *r, const char *cmd_file_name)
*/
switch (cmd->cmd) {
case CMD_ADD_KEY:
- error = reg_open_key_abs(r, cmd->key, &tmp);
+ error = reg_open_key_abs(mem_ctx, r, cmd->key, &tmp);
/* If we found it, apply the other bits, else create such a key */
if (W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) {
if(W_ERROR_IS_OK(reg_key_add_name_recursive_abs(r, cmd->key))) {
- error = reg_open_key_abs(r, cmd->key, &tmp);
+ error = reg_open_key_abs(mem_ctx, r, cmd->key, &tmp);
if(!W_ERROR_IS_OK(error)) {
DEBUG(0, ("Error finding new key '%s' after it has been added\n", cmd->key));
continue;
@@ -699,12 +700,12 @@ static int nt_apply_reg_command_file(REG_HANDLE *r, const char *cmd_file_name)
while (cmd->val_count) {
VAL_SPEC_LIST *val = cmd->val_spec_list;
- REG_VAL *reg_val = NULL;
+ struct registry_value *reg_val = NULL;
if (val->type == REG_DELETE) {
- error = reg_key_get_value_by_name( tmp, val->name, &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;
}
diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c
index 638ed70d5e..78fe36f1a0 100644
--- a/source4/lib/registry/tools/regshell.c
+++ b/source4/lib/registry/tools/regshell.c
@@ -33,96 +33,96 @@
* exit
*/
-static REG_KEY *cmd_info(REG_KEY *cur, int argc, char **argv)
+static struct registry_key *cmd_info(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv)
{
time_t last_mod;
- printf("Name: %s\n", reg_key_name(cur));
- printf("Full path: %s\n", reg_key_get_path(cur));
- printf("Key Class: %s\n", reg_key_class(cur));
- last_mod = nt_time_to_unix(reg_key_last_modified(cur));
+ printf("Name: %s\n", cur->name);
+ printf("Full path: %s\n", cur->path);
+ printf("Key Class: %s\n", cur->class_name);
+ last_mod = nt_time_to_unix(cur->last_mod);
printf("Time Last Modified: %s\n", ctime(&last_mod));
/* FIXME: Security info */
return cur;
}
-static REG_KEY *cmd_pwd(REG_KEY *cur, int argc, char **argv)
+static struct registry_key *cmd_pwd(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv)
{
- printf("%s\n", reg_key_get_path_abs(cur));
+ printf("%s\n", cur->path);
return cur;
}
-static REG_KEY *cmd_set(REG_KEY *cur, int argc, char **argv)
+static struct registry_key *cmd_set(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv)
{
/* FIXME */
return NULL;
}
-static REG_KEY *cmd_ck(REG_KEY *cur, int argc, char **argv)
+static struct registry_key *cmd_ck(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv)
{
- REG_KEY *new = NULL;
+ struct registry_key *new = NULL;
WERROR error;
if(argc < 2) {
new = cur;
} else {
- error = reg_open_key(cur, argv[1], &new);
+ error = reg_open_key(mem_ctx, cur, argv[1], &new);
if(!W_ERROR_IS_OK(error)) {
DEBUG(0, ("Error opening specified key: %s\n", win_errstr(error)));
return NULL;
}
}
- printf("Current path is: %s\n", reg_key_get_path_abs(new));
+ printf("Current path is: %s\n", new->path);
return new;
}
-static REG_KEY *cmd_ls(REG_KEY *cur, int argc, char **argv)
+static struct registry_key *cmd_ls(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv)
{
int i;
WERROR error;
- REG_VAL *value;
- REG_KEY *sub;
- for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(cur, i, &sub)); i++) {
- printf("K %s\n", reg_key_name(sub));
+ struct registry_value *value;
+ struct registry_key *sub;
+ for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(mem_ctx, cur, i, &sub)); i++) {
+ printf("K %s\n", sub->name);
}
if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) {
DEBUG(0, ("Error occured while browsing thru keys: %s\n", win_errstr(error)));
}
- for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(cur, i, &value)); i++) {
- printf("V \"%s\" %s %s\n", reg_val_name(value), str_regtype(reg_val_type(value)), reg_val_data_string(value));
+ for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(mem_ctx, cur, i, &value)); i++) {
+ printf("V \"%s\" %s %s\n", value->name, str_regtype(value->data_type), reg_val_data_string(mem_ctx, value));
}
return NULL;
}
-static REG_KEY *cmd_mkkey(REG_KEY *cur, int argc, char **argv)
+static struct registry_key *cmd_mkkey(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv)
{
- REG_KEY *tmp;
+ struct registry_key *tmp;
if(argc < 2) {
fprintf(stderr, "Usage: mkkey <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;
}
diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c
index b1ca9b3fb2..9748ca3438 100644
--- a/source4/lib/registry/tools/regtree.c
+++ b/source4/lib/registry/tools/regtree.c
@@ -21,39 +21,45 @@
#include "includes.h"
-static void print_tree(int l, REG_KEY *p, int fullpath, int novals)
+static void print_tree(int l, struct registry_key *p, int fullpath, int novals)
{
- REG_KEY *subkey;
- REG_VAL *value;
+ struct registry_key *subkey;
+ struct registry_value *value;
WERROR error;
int i;
+ TALLOC_CTX *mem_ctx;
for(i = 0; i < l; i++) putchar(' ');
- if(fullpath) printf("%s\n", reg_key_get_path_abs(p));
- else printf("%s\n", reg_key_name(p));
+
+ /* Hive name */
+ if(p->hive->root == p) printf("%s\n", p->hive->name);
+ else if(!p->name) printf("<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;
diff --git a/source4/librpc/idl/winreg.idl b/source4/librpc/idl/winreg.idl
index 812aa4e11f..46fa8d0d67 100644
--- a/source4/librpc/idl/winreg.idl
+++ b/source4/librpc/idl/winreg.idl
@@ -149,10 +149,9 @@
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
);