mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
r4132: - Bunch of rather large fixes in the registry
- Added some README files Not everything works yet, e.g. the EnumValue test appears to be broken.
This commit is contained in:
parent
573230ea99
commit
c169e86c1f
@ -62,6 +62,7 @@ static GtkWidget* create_FindDialog (void)
|
||||
|
||||
FindDialog = gtk_dialog_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (FindDialog), "Find Key or Value");
|
||||
gtk_window_set_resizable (GTK_WINDOW (FindDialog), FALSE);
|
||||
gtk_window_set_type_hint (GTK_WINDOW (FindDialog), GDK_WINDOW_TYPE_HINT_DIALOG);
|
||||
|
||||
dialog_vbox2 = GTK_DIALOG (FindDialog)->vbox;
|
||||
@ -135,7 +136,6 @@ static GtkWidget* create_SetValueDialog (void)
|
||||
|
||||
SetValueDialog = gtk_dialog_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (SetValueDialog), "Set Registry Value");
|
||||
GTK_WINDOW (SetValueDialog)->type = GTK_WINDOW_POPUP;
|
||||
gtk_window_set_position (GTK_WINDOW (SetValueDialog), GTK_WIN_POS_CENTER);
|
||||
gtk_window_set_resizable (GTK_WINDOW (SetValueDialog), FALSE);
|
||||
gtk_window_set_type_hint (GTK_WINDOW (SetValueDialog), GDK_WINDOW_TYPE_HINT_DIALOG);
|
||||
@ -207,7 +207,6 @@ static GtkWidget* create_NewKeyDialog (void)
|
||||
|
||||
NewKeyDialog = gtk_dialog_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (NewKeyDialog), "New Registry Key");
|
||||
GTK_WINDOW (NewKeyDialog)->type = GTK_WINDOW_POPUP;
|
||||
gtk_window_set_position (GTK_WINDOW (NewKeyDialog), GTK_WIN_POS_CENTER);
|
||||
gtk_window_set_resizable (GTK_WINDOW (NewKeyDialog), FALSE);
|
||||
gtk_window_set_type_hint (GTK_WINDOW (NewKeyDialog), GDK_WINDOW_TYPE_HINT_DIALOG);
|
||||
@ -287,45 +286,51 @@ static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath *
|
||||
if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) gtk_show_werror(mainwin, error);
|
||||
}
|
||||
|
||||
static void registry_load_hive(struct registry_key *root)
|
||||
{
|
||||
GtkTreeIter iter, tmpiter;
|
||||
/* Add the root */
|
||||
gtk_tree_store_append(store_keys, &iter, NULL);
|
||||
gtk_tree_store_set (store_keys,
|
||||
&iter,
|
||||
0,
|
||||
root->name?root->name:"",
|
||||
1,
|
||||
root,
|
||||
-1);
|
||||
|
||||
gtk_tree_store_append(store_keys, &tmpiter, &iter);
|
||||
|
||||
gtk_widget_set_sensitive( save, True );
|
||||
gtk_widget_set_sensitive( save_as, True );
|
||||
}
|
||||
|
||||
static void registry_load_root(void)
|
||||
{
|
||||
struct registry_key *root;
|
||||
GtkTreeIter iter, tmpiter;
|
||||
int i = 0;
|
||||
uint32_t i = 0;
|
||||
if(!registry) return;
|
||||
|
||||
gtk_tree_store_clear(store_keys);
|
||||
|
||||
for(i = 0; i < registry->num_hives; i++)
|
||||
for(i = HKEY_CLASSES_ROOT; i <= HKEY_PN; i++)
|
||||
{
|
||||
root = registry->hives[i]->root;
|
||||
if (!W_ERROR_IS_OK(reg_get_hive(registry, i, &root))) { continue; }
|
||||
|
||||
/* Add the root */
|
||||
gtk_tree_store_append(store_keys, &iter, NULL);
|
||||
gtk_tree_store_set (store_keys,
|
||||
&iter,
|
||||
0,
|
||||
root->hive->name?root->hive->name:"",
|
||||
1,
|
||||
root,
|
||||
-1);
|
||||
|
||||
gtk_tree_store_append(store_keys, &tmpiter, &iter);
|
||||
registry_load_hive(root);
|
||||
}
|
||||
|
||||
gtk_widget_set_sensitive( save, True );
|
||||
gtk_widget_set_sensitive( save_as, True );
|
||||
}
|
||||
|
||||
static void on_open_file_activate (GtkMenuItem *menuitem, gpointer user_data)
|
||||
{
|
||||
gint result = gtk_dialog_run(GTK_DIALOG(create_openfilewin()));
|
||||
char *filename, *tmp;
|
||||
struct registry_key *root;
|
||||
WERROR error;
|
||||
switch(result) {
|
||||
case GTK_RESPONSE_OK:
|
||||
filename = strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(openfilewin)));
|
||||
error = reg_open(®istry, user_data, filename, NULL);
|
||||
error = reg_open_hive(NULL, user_data, filename, NULL, &root);
|
||||
if(!W_ERROR_IS_OK(error)) {
|
||||
gtk_show_werror(mainwin, error);
|
||||
break;
|
||||
@ -334,7 +339,8 @@ static void on_open_file_activate (GtkMenuItem *menuitem, gpointer user_data)
|
||||
tmp = g_strdup_printf("Registry Editor - %s", filename);
|
||||
gtk_window_set_title (GTK_WINDOW (mainwin), tmp);
|
||||
g_free(tmp);
|
||||
registry_load_root();
|
||||
gtk_tree_store_clear(store_keys);
|
||||
registry_load_hive(root);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -346,7 +352,8 @@ 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(®istry, "gconf", NULL, NULL);
|
||||
struct registry_key *root;
|
||||
WERROR error = reg_open_hive(NULL, "gconf", NULL, NULL, &root);
|
||||
if(!W_ERROR_IS_OK(error)) {
|
||||
gtk_show_werror(mainwin, error);
|
||||
return;
|
||||
@ -354,13 +361,12 @@ static void on_open_gconf_activate (GtkMenuItem *menui
|
||||
|
||||
gtk_window_set_title (GTK_WINDOW (mainwin), "Registry Editor - GConf");
|
||||
|
||||
registry_load_root();
|
||||
gtk_tree_store_clear(store_keys);
|
||||
registry_load_hive(root);
|
||||
}
|
||||
|
||||
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(FALSE, NULL));
|
||||
gint result = gtk_dialog_run(GTK_DIALOG(rpcwin));
|
||||
@ -372,16 +378,16 @@ static void on_open_remote_activate(GtkMenuItem *menuitem, gpointer user_data)
|
||||
return;
|
||||
}
|
||||
|
||||
location = gtk_rpc_binding_dialog_get_binding_string(GTK_RPC_BINDING_DIALOG(rpcwin), mem_ctx);
|
||||
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(®istry, "rpc", location, credentials);
|
||||
error = reg_open_remote(®istry,
|
||||
gtk_rpc_binding_dialog_get_username(GTK_RPC_BINDING_DIALOG(rpcwin)),
|
||||
gtk_rpc_binding_dialog_get_password(GTK_RPC_BINDING_DIALOG(rpcwin)),
|
||||
gtk_rpc_binding_dialog_get_binding_string(GTK_RPC_BINDING_DIALOG(rpcwin), mem_ctx));
|
||||
|
||||
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);
|
||||
@ -805,14 +811,10 @@ static GtkWidget* create_savefilewin (void)
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
poptContext pc;
|
||||
const char *backend = NULL;
|
||||
const char *credentials = NULL;
|
||||
const char *location;
|
||||
WERROR error;
|
||||
int opt;
|
||||
struct poptOption long_options[] = {
|
||||
POPT_AUTOHELP
|
||||
{"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL},
|
||||
{"credentials", 'c', POPT_ARG_STRING, &credentials, 0, "credentials (user%%password)", NULL},
|
||||
POPT_TABLEEND
|
||||
};
|
||||
|
||||
@ -829,32 +831,18 @@ static GtkWidget* create_savefilewin (void)
|
||||
while((opt = poptGetNextOpt(pc)) != -1) {
|
||||
}
|
||||
|
||||
location = poptGetArg(pc);
|
||||
|
||||
if(location) {
|
||||
WERROR error;
|
||||
|
||||
if(!backend) {
|
||||
if(credentials)backend = "rpc";
|
||||
else backend = "nt4";
|
||||
}
|
||||
|
||||
error = reg_open(®istry, backend, location, credentials);
|
||||
if(!W_ERROR_IS_OK(error)) {
|
||||
gtk_show_werror(mainwin, error);
|
||||
return -1;
|
||||
}
|
||||
mainwin = create_mainwin ();
|
||||
registry_load_root();
|
||||
} else {
|
||||
mainwin = create_mainwin ();
|
||||
error = reg_open_local(®istry);
|
||||
if(!W_ERROR_IS_OK(error)) {
|
||||
gtk_show_werror(mainwin, error);
|
||||
return -1;
|
||||
}
|
||||
mainwin = create_mainwin ();
|
||||
registry_load_root();
|
||||
|
||||
gtk_widget_show_all (mainwin);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
if(registry)talloc_destroy(registry->mem_ctx);
|
||||
talloc_destroy(mem_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
36
source/include/credentials.h
Normal file
36
source/include/credentials.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
samba -- Unix SMB/CIFS implementation.
|
||||
|
||||
Client credentials structure
|
||||
|
||||
Copyright (C) 2004 Jelmer Vernooij <jelmer@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
struct cli_credentials {
|
||||
/* Preferred methods, NULL means default */
|
||||
const char **preferred_methods;
|
||||
|
||||
const char *username;
|
||||
const char *password;
|
||||
const char *domain;
|
||||
const char *realm;
|
||||
|
||||
const char *(*username_cb) (void);
|
||||
const char *(*password_cb) (void);
|
||||
const char *(*domain_cb) (void);
|
||||
const char *(*realm_cb) (void);
|
||||
};
|
@ -22,26 +22,36 @@
|
||||
#ifndef _REGISTRY_H /* _REGISTRY_H */
|
||||
#define _REGISTRY_H
|
||||
|
||||
#define HKEY_CLASSES_ROOT 0x80000000
|
||||
#define HKEY_CURRENT_USER 0x80000001
|
||||
#define HKEY_LOCAL_MACHINE 0x80000002
|
||||
#define HKEY_USERS 0x80000003
|
||||
|
||||
enum hkeys {
|
||||
HKEY_CLASSES_ROOT = 0x80000000,
|
||||
HKEY_CURRENT_USER = 0x80000001,
|
||||
HKEY_LOCAL_MACHINE = 0x80000002,
|
||||
HKEY_USERS = 0x80000003,
|
||||
HKEY_PERFORMANCE_DATA = 0x80000004,
|
||||
HKEY_CURRENT_CONFIG = 0x80000005,
|
||||
HKEY_DYN_DATA = 0x80000006,
|
||||
HKEY_PT = 0x80000007, /* Don't know if this is correct! */
|
||||
HKEY_PN = 0x80000008 /* Don't know if this is correct! */
|
||||
};
|
||||
|
||||
/* Registry data types */
|
||||
|
||||
#define REG_DELETE -1
|
||||
#define REG_DELETE -1
|
||||
#define REG_NONE 0
|
||||
#define REG_SZ 1
|
||||
#define REG_EXPAND_SZ 2
|
||||
#define REG_BINARY 3
|
||||
#define REG_DWORD 4
|
||||
#define REG_DWORD_LE 4 /* DWORD, little endian*/
|
||||
#define REG_DWORD_BE 5 /* DWORD, big endian */
|
||||
#define REG_DWORD_LE 4
|
||||
#define REG_DWORD REG_DWORD_LE
|
||||
#define REG_DWORD_BE 5
|
||||
#define REG_LINK 6
|
||||
#define REG_MULTI_SZ 7
|
||||
#define REG_RESOURCE_LIST 8
|
||||
#define REG_FULL_RESOURCE_DESCRIPTOR 9
|
||||
#define REG_RESOURCE_REQUIREMENTS_LIST 10
|
||||
#define REG_QWORD_LE 11
|
||||
#define REG_QWORD REQ_QWORD_LE
|
||||
|
||||
#if 0
|
||||
/* FIXME */
|
||||
@ -62,7 +72,7 @@ typedef struct ace_struct_s {
|
||||
/* structure to store the registry handles */
|
||||
struct registry_key {
|
||||
char *name; /* Name of the key */
|
||||
char *path; /* Full path to the key */
|
||||
const char *path; /* Full path to the key */
|
||||
char *class_name; /* Name of key class */
|
||||
NTTIME last_mod; /* Time last modified */
|
||||
SEC_DESC *security;
|
||||
@ -92,18 +102,15 @@ typedef void (*value_notification_function) (void);
|
||||
*
|
||||
* Backends can provide :
|
||||
* - just one hive (example: nt4, w95)
|
||||
* - several hives (example: rpc)
|
||||
* - several hives (example: rpc).
|
||||
*
|
||||
*/
|
||||
|
||||
struct registry_operations {
|
||||
struct hive_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 **);
|
||||
WERROR (*open_hive) (struct registry_hive *, struct registry_key **);
|
||||
WERROR (*close_hive) (struct registry_hive *);
|
||||
|
||||
/* Or this one */
|
||||
@ -140,11 +147,8 @@ struct registry_operations {
|
||||
};
|
||||
|
||||
struct registry_hive {
|
||||
const struct registry_operations *functions;
|
||||
char *name; /* usually something like HKEY_CURRENT_USER, etc */
|
||||
const struct hive_operations *functions;
|
||||
char *location;
|
||||
char *credentials;
|
||||
char *backend_hivename;
|
||||
void *backend_data;
|
||||
struct registry_key *root;
|
||||
struct registry_context *reg_ctx;
|
||||
@ -153,14 +157,13 @@ struct registry_hive {
|
||||
/* Handle to a full registry
|
||||
* contains zero or more hives */
|
||||
struct registry_context {
|
||||
TALLOC_CTX *mem_ctx;
|
||||
int num_hives;
|
||||
struct registry_hive **hives;
|
||||
void *backend_data;
|
||||
WERROR (*get_hive) (struct registry_context *, uint32 hkey, struct registry_key **);
|
||||
};
|
||||
|
||||
struct reg_init_function_entry {
|
||||
/* Function to create a member of the pdb_methods list */
|
||||
const struct registry_operations *functions;
|
||||
const struct hive_operations *hive_functions;
|
||||
struct reg_init_function_entry *prev, *next;
|
||||
};
|
||||
|
||||
|
30
source/lib/registry/README
Normal file
30
source/lib/registry/README
Normal file
@ -0,0 +1,30 @@
|
||||
This is the registry library. The registry is basically a bunch of hives
|
||||
(HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, etc) that can be loaded from
|
||||
different places.
|
||||
|
||||
The various registry backends provide support for loading/saving specific types
|
||||
of hives:
|
||||
- ldb
|
||||
- w95 (USER.DAT-style files)
|
||||
- nt4 (NTUSER.DAT-style files)
|
||||
- gconf (GNOME configuration)
|
||||
- rpc (Remote individual hives)
|
||||
|
||||
Instead of opening individual hives, one can also open a 'complete' registry by
|
||||
using one of these three functions:
|
||||
|
||||
- reg_open_local() - load local registry, see below
|
||||
- reg_open_remote() - connect to remote registry over RPC
|
||||
- reg_open_wine() (not working yet)
|
||||
|
||||
reg_open_local() loads a set of hives based on smb.conf settings.
|
||||
Lines in smb.conf should have the following syntax:
|
||||
|
||||
registry:<hivename> = <backend>:<location>
|
||||
|
||||
So an example usage could be:
|
||||
|
||||
registry:HKEY_CURRENT_USER = nt4:NTUSER.DAT
|
||||
registry:HKEY_LOCAL_MACHINE = ldb:tdb://registry.tdb
|
||||
|
||||
WERR_NOT_SUPPORTED will be returned for all hives that haven't been set.
|
@ -30,32 +30,25 @@ static struct reg_init_function_entry *backends = NULL;
|
||||
|
||||
static struct reg_init_function_entry *reg_find_backend_entry(const char *name);
|
||||
|
||||
#define reg_make_path(mem_ctx, parent, name) (((parent)->hive->root == (parent))?talloc_strdup(mem_ctx, name):talloc_asprintf(mem_ctx, "%s\\%s", parent->path, name))
|
||||
|
||||
/* Register new backend */
|
||||
NTSTATUS registry_register(const void *_function)
|
||||
NTSTATUS registry_register(const void *_hive_ops)
|
||||
{
|
||||
const struct registry_operations *functions = _function;
|
||||
const struct hive_operations *hive_ops = _hive_ops;
|
||||
struct reg_init_function_entry *entry = backends;
|
||||
|
||||
if (!functions || !functions->name) {
|
||||
DEBUG(0, ("Invalid arguments while registering registry backend\n"));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
DEBUG(5,("Attempting to register registry backend %s\n", functions->name));
|
||||
DEBUG(5,("Attempting to register registry backend %s\n", hive_ops->name));
|
||||
|
||||
/* Check for duplicates */
|
||||
if (reg_find_backend_entry(functions->name)) {
|
||||
DEBUG(0,("There already is a registry backend registered with the name %s!\n", functions->name));
|
||||
if (reg_find_backend_entry(hive_ops->name)) {
|
||||
DEBUG(0,("There already is a registry backend registered with the name %s!\n", hive_ops->name));
|
||||
return NT_STATUS_OBJECT_NAME_COLLISION;
|
||||
}
|
||||
|
||||
entry = malloc_p(struct reg_init_function_entry);
|
||||
entry->functions = functions;
|
||||
entry = talloc_p(NULL, struct reg_init_function_entry);
|
||||
entry->hive_functions = hive_ops;
|
||||
|
||||
DLIST_ADD(backends, entry);
|
||||
DEBUG(5,("Successfully added registry backend '%s'\n", functions->name));
|
||||
DEBUG(5,("Successfully added registry backend '%s'\n", hive_ops->name));
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
@ -67,7 +60,7 @@ static struct reg_init_function_entry *reg_find_backend_entry(const char *name)
|
||||
entry = backends;
|
||||
|
||||
while(entry) {
|
||||
if (strcmp(entry->functions->name, name) == 0) return entry;
|
||||
if (strcmp(entry->hive_functions->name, name) == 0) return entry;
|
||||
entry = entry->next;
|
||||
}
|
||||
|
||||
@ -80,85 +73,83 @@ BOOL reg_has_backend(const char *backend)
|
||||
return reg_find_backend_entry(backend) != NULL?True:False;
|
||||
}
|
||||
|
||||
WERROR reg_create(struct registry_context **_ret)
|
||||
static struct {
|
||||
uint32 hkey;
|
||||
const char *name;
|
||||
} hkey_names[] =
|
||||
{
|
||||
TALLOC_CTX *mem_ctx;
|
||||
struct registry_context *ret;
|
||||
mem_ctx = talloc_init("registry handle");
|
||||
ret = talloc_p(mem_ctx, struct registry_context);
|
||||
ret->mem_ctx = mem_ctx;
|
||||
ZERO_STRUCTP(ret);
|
||||
*_ret = ret;
|
||||
return WERR_OK;
|
||||
{HKEY_CLASSES_ROOT,"HKEY_CLASSES_ROOT" },
|
||||
{HKEY_CURRENT_USER,"HKEY_CURRENT_USER" },
|
||||
{HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" },
|
||||
{HKEY_PERFORMANCE_DATA, "HKEY_PERFORMANCE_DATA" },
|
||||
{HKEY_USERS, "HKEY_USERS" },
|
||||
{HKEY_CURRENT_CONFIG, "HKEY_CURRENT_CONFIG" },
|
||||
{HKEY_DYN_DATA, "HKEY_DYN_DATA" },
|
||||
{HKEY_PT, "HKEY_PT" },
|
||||
{HKEY_PN, "HKEY_PN" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
int reg_list_hives(TALLOC_CTX *mem_ctx, char ***hives, uint32_t **hkeys)
|
||||
{
|
||||
int i;
|
||||
*hives = talloc_array_p(mem_ctx, char *, ARRAY_SIZE(hkey_names));
|
||||
*hkeys = talloc_array_p(mem_ctx, uint32_t, ARRAY_SIZE(hkey_names));
|
||||
|
||||
for (i = 0; hkey_names[i].name; i++) {
|
||||
(*hives)[i] = talloc_strdup(mem_ctx, hkey_names[i].name);
|
||||
(*hkeys)[i] = hkey_names[i].hkey;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
WERROR reg_list_available_hives(TALLOC_CTX *mem_ctx, const char *backend, const char *location, const char *credentials, char ***hives)
|
||||
const char *reg_get_hkey_name(uint32_t hkey)
|
||||
{
|
||||
struct reg_init_function_entry *entry;
|
||||
|
||||
entry = reg_find_backend_entry(backend);
|
||||
|
||||
if (!entry) {
|
||||
DEBUG(0, ("No such registry backend '%s' loaded!\n", backend));
|
||||
return WERR_GENERAL_FAILURE;
|
||||
int i;
|
||||
for (i = 0; hkey_names[i].name; i++) {
|
||||
if (hkey_names[i].hkey == hkey) return hkey_names[i].name;
|
||||
}
|
||||
|
||||
if(!entry->functions->list_available_hives) {
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return entry->functions->list_available_hives(mem_ctx, location, credentials, hives);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WERROR reg_open(struct registry_context **ret, const char *backend, const char *location, const char *credentials)
|
||||
WERROR reg_get_hive_by_name(struct registry_context *ctx, const char *name, struct registry_key **key)
|
||||
{
|
||||
WERROR error = reg_create(ret), reterror = WERR_NO_MORE_ITEMS;
|
||||
char **hives;
|
||||
int i, j;
|
||||
TALLOC_CTX *mem_ctx = talloc_init("reg_open");
|
||||
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
|
||||
error = reg_list_available_hives(mem_ctx, backend, location, credentials, &hives);
|
||||
|
||||
if(W_ERROR_EQUAL(error, WERR_NOT_SUPPORTED)) {
|
||||
return reg_import_hive(*ret, backend, location, credentials, NULL);
|
||||
}
|
||||
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
|
||||
j = 0;
|
||||
for(i = 0; hives[i]; i++)
|
||||
{
|
||||
error = reg_import_hive(*ret, backend, location, credentials, hives[i]);
|
||||
if (W_ERROR_IS_OK(error)) {
|
||||
reterror = WERR_OK;
|
||||
(*ret)->hives[j]->name = talloc_strdup((*ret)->mem_ctx, hives[i]);
|
||||
j++;
|
||||
} else if (!W_ERROR_IS_OK(reterror)) reterror = error;
|
||||
int i;
|
||||
|
||||
for (i = 0; hkey_names[i].name; i++) {
|
||||
if (!strcmp(hkey_names[i].name, name)) return reg_get_hive(ctx, hkey_names[i].hkey, key);
|
||||
}
|
||||
|
||||
return reterror;
|
||||
DEBUG(1, ("No hive with name '%s'\n", name));
|
||||
|
||||
return WERR_BADFILE;
|
||||
}
|
||||
|
||||
WERROR reg_close (struct registry_context *ctx)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ctx->num_hives; i++) {
|
||||
if (ctx->hives[i]->functions->close_hive) {
|
||||
ctx->hives[i]->functions->close_hive(ctx->hives[i]);
|
||||
}
|
||||
}
|
||||
talloc_destroy(ctx);
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
WERROR reg_get_hive(struct registry_context *ctx, uint32_t hkey, struct registry_key **key)
|
||||
{
|
||||
WERROR ret = ctx->get_hive(ctx, hkey, key);
|
||||
|
||||
if (W_ERROR_IS_OK(ret)) {
|
||||
(*key)->name = talloc_strdup(*key, reg_get_hkey_name(hkey));
|
||||
(*key)->path = "";
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Open a registry file/host/etc */
|
||||
WERROR reg_import_hive(struct registry_context *h, const char *backend, const char *location, const char *credentials, const char *hivename)
|
||||
WERROR reg_open_hive(struct registry_context *parent_ctx, const char *backend, const char *location, const char *credentials, struct registry_key **root)
|
||||
{
|
||||
struct registry_hive *ret;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
struct reg_init_function_entry *entry;
|
||||
WERROR werr;
|
||||
|
||||
@ -169,24 +160,21 @@ WERROR reg_import_hive(struct registry_context *h, const char *backend, const ch
|
||||
return WERR_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
if(!entry->functions->open_hive) {
|
||||
if(!entry->hive_functions || !entry->hive_functions->open_hive) {
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
mem_ctx = h->mem_ctx;
|
||||
ret = talloc_p(mem_ctx, struct registry_hive);
|
||||
ret->location = location?talloc_strdup(mem_ctx, location):NULL;
|
||||
ret->backend_hivename = hivename?talloc_strdup(mem_ctx, hivename):NULL;
|
||||
ret->credentials = credentials?talloc_strdup(mem_ctx, credentials):NULL;
|
||||
ret->functions = entry->functions;
|
||||
ret = talloc_p(parent_ctx, struct registry_hive);
|
||||
ret->location = location?talloc_strdup(ret, location):NULL;
|
||||
ret->functions = entry->hive_functions;
|
||||
ret->backend_data = NULL;
|
||||
ret->reg_ctx = h;
|
||||
ret->name = NULL;
|
||||
ret->reg_ctx = parent_ctx;
|
||||
|
||||
werr = entry->functions->open_hive(mem_ctx, ret, &ret->root);
|
||||
werr = entry->hive_functions->open_hive(ret, &ret->root);
|
||||
|
||||
if(!W_ERROR_IS_OK(werr)) return werr;
|
||||
if(!W_ERROR_IS_OK(werr)) {
|
||||
return werr;
|
||||
}
|
||||
|
||||
if(!ret->root) {
|
||||
DEBUG(0, ("Backend %s didn't provide root key!\n", backend));
|
||||
@ -195,12 +183,9 @@ WERROR reg_import_hive(struct registry_context *h, const char *backend, const ch
|
||||
|
||||
ret->root->hive = ret;
|
||||
ret->root->name = NULL;
|
||||
ret->root->path = talloc_strdup(mem_ctx, "");
|
||||
|
||||
/* Add hive to context */
|
||||
h->num_hives++;
|
||||
h->hives = talloc_realloc_p(h, h->hives, struct registry_hive *, h->num_hives);
|
||||
h->hives[h->num_hives-1] = ret;
|
||||
ret->root->path = talloc_strdup(ret, "");
|
||||
|
||||
*root = ret->root;
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
@ -217,7 +202,7 @@ WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, co
|
||||
else hivelength = strlen(name);
|
||||
|
||||
hivename = strndup(name, hivelength);
|
||||
error = reg_get_hive(handle, hivename, &hive);
|
||||
error = reg_get_hive_by_name(handle, hivename, &hive);
|
||||
SAFE_FREE(hivename);
|
||||
|
||||
if(!W_ERROR_IS_OK(error)) {
|
||||
@ -272,7 +257,8 @@ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, const char
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
fullname = reg_make_path(mem_ctx, parent, name);
|
||||
|
||||
fullname = ((parent->hive->root == parent)?talloc_strdup(mem_ctx, name):talloc_asprintf(mem_ctx, "%s\\%s", parent->path, name));
|
||||
|
||||
error = parent->hive->functions->open_key(mem_ctx, parent->hive, fullname, result);
|
||||
|
||||
@ -499,7 +485,7 @@ WERROR reg_key_add_name_recursive_abs(struct registry_context *handle, const cha
|
||||
else hivelength = strlen(name);
|
||||
|
||||
hivename = strndup(name, hivelength);
|
||||
error = reg_get_hive(handle, hivename, &hive);
|
||||
error = reg_get_hive_by_name(handle, hivename, &hive);
|
||||
SAFE_FREE(hivename);
|
||||
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
@ -578,19 +564,7 @@ WERROR reg_val_set(struct registry_key *key, const char *value, int type, void *
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
WERROR reg_get_hive(struct registry_context *h, const char *name, struct registry_key **key)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < h->num_hives; i++)
|
||||
{
|
||||
if(!strcmp(h->hives[i]->name, name)) {
|
||||
*key = h->hives[i]->root;
|
||||
return WERR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return WERR_NO_MORE_ITEMS;
|
||||
}
|
||||
|
||||
WERROR reg_del_value(struct registry_value *val)
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
INIT_FUNCTION = registry_nt4_init
|
||||
SUBSYSTEM = REGISTRY
|
||||
INIT_OBJ_FILES = \
|
||||
lib/registry/reg_backend_nt4/reg_backend_nt4.o
|
||||
lib/registry/reg_backend_nt4.o
|
||||
# End MODULE registry_nt4
|
||||
################################################
|
||||
|
||||
@ -16,7 +16,7 @@ INIT_OBJ_FILES = \
|
||||
INIT_FUNCTION = registry_w95_init
|
||||
SUBSYSTEM = REGISTRY
|
||||
INIT_OBJ_FILES = \
|
||||
lib/registry/reg_backend_w95/reg_backend_w95.o
|
||||
lib/registry/reg_backend_w95.o
|
||||
# End MODULE registry_w95
|
||||
################################################
|
||||
|
||||
@ -26,7 +26,7 @@ INIT_OBJ_FILES = \
|
||||
INIT_FUNCTION = registry_dir_init
|
||||
SUBSYSTEM = REGISTRY
|
||||
INIT_OBJ_FILES = \
|
||||
lib/registry/reg_backend_dir/reg_backend_dir.o
|
||||
lib/registry/reg_backend_dir.o
|
||||
# End MODULE registry_dir
|
||||
################################################
|
||||
|
||||
@ -36,18 +36,20 @@ INIT_OBJ_FILES = \
|
||||
INIT_FUNCTION = registry_rpc_init
|
||||
SUBSYSTEM = REGISTRY
|
||||
INIT_OBJ_FILES = \
|
||||
lib/registry/reg_backend_rpc/reg_backend_rpc.o
|
||||
lib/registry/reg_backend_rpc.o
|
||||
REQUIRED_SUBSYSTEMS = RPC_NDR_WINREG
|
||||
# End MODULE registry_rpc
|
||||
################################################
|
||||
|
||||
|
||||
|
||||
################################################
|
||||
# Start MODULE registry_gconf
|
||||
[MODULE::registry_gconf]
|
||||
INIT_FUNCTION = registry_gconf_init
|
||||
SUBSYSTEM = REGISTRY
|
||||
INIT_OBJ_FILES = \
|
||||
lib/registry/reg_backend_gconf/reg_backend_gconf.o
|
||||
lib/registry/reg_backend_gconf.o
|
||||
REQUIRED_SUBSYSTEMS = EXT_LIB_gconf
|
||||
# End MODULE registry_gconf
|
||||
################################################
|
||||
@ -58,7 +60,7 @@ REQUIRED_SUBSYSTEMS = EXT_LIB_gconf
|
||||
INIT_FUNCTION = registry_ldb_init
|
||||
SUBSYSTEM = REGISTRY
|
||||
INIT_OBJ_FILES = \
|
||||
lib/registry/reg_backend_ldb/reg_backend_ldb.o
|
||||
lib/registry/reg_backend_ldb.o
|
||||
REQUIRED_SUBSYSTEMS = \
|
||||
LIBLDB
|
||||
# End MODULE registry_ldb
|
||||
@ -70,7 +72,8 @@ REQUIRED_SUBSYSTEMS = \
|
||||
INIT_OBJ_FILES = \
|
||||
lib/registry/common/reg_interface.o
|
||||
ADD_OBJ_FILES = \
|
||||
lib/registry/common/reg_util.o
|
||||
lib/registry/common/reg_util.o \
|
||||
lib/registry/reg_samba.o
|
||||
REQUIRED_SUBSYSTEMS = \
|
||||
LIBBASIC
|
||||
# End MODULE registry_ldb
|
||||
|
@ -110,12 +110,12 @@ static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, struct registry_key *k,
|
||||
return WERR_NO_MORE_ITEMS;
|
||||
}
|
||||
|
||||
static WERROR reg_dir_open(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **key)
|
||||
static WERROR reg_dir_open(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);
|
||||
*key = talloc_p(h, struct registry_key);
|
||||
(*key)->backend_data = talloc_strdup(*key, h->location);
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ static WERROR reg_dir_del_value(struct registry_value *v)
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static struct registry_operations reg_backend_dir = {
|
||||
static struct hive_operations reg_backend_dir = {
|
||||
.name = "dir",
|
||||
.open_hive = reg_dir_open,
|
||||
.open_key = reg_dir_open_key,
|
@ -29,16 +29,16 @@ static WERROR gerror_to_werror(GError *error)
|
||||
return WERR_FOOBAR;
|
||||
}
|
||||
|
||||
static WERROR reg_open_gconf_hive(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **k)
|
||||
static WERROR reg_open_gconf_hive(struct registry_hive *h, struct registry_key **k)
|
||||
{
|
||||
g_type_init();
|
||||
h->backend_data = (void *)gconf_client_get_default();
|
||||
if(!h->backend_data) return WERR_FOOBAR;
|
||||
|
||||
*k = talloc_p(mem_ctx, struct registry_key);
|
||||
(*k)->name = talloc_strdup(mem_ctx, "");
|
||||
(*k)->path = talloc_strdup(mem_ctx, "");
|
||||
(*k)->backend_data = talloc_strdup(mem_ctx, "/");
|
||||
*k = talloc_p(h, struct registry_key);
|
||||
(*k)->name = talloc_strdup(*k, "");
|
||||
(*k)->path = talloc_strdup(*k, "");
|
||||
(*k)->backend_data = talloc_strdup(*k, "/");
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ static WERROR gconf_set_value(struct registry_key *key, const char *valname, int
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static struct registry_operations reg_backend_gconf = {
|
||||
static struct hive_operations reg_backend_gconf = {
|
||||
.name = "gconf",
|
||||
.open_hive = reg_open_gconf_hive,
|
||||
.open_key = gconf_open_key,
|
@ -137,7 +137,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, struct registry_hive *h, const c
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static WERROR ldb_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *hive, struct registry_key **k)
|
||||
static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k)
|
||||
{
|
||||
struct ldb_context *c;
|
||||
|
||||
@ -151,8 +151,8 @@ static WERROR ldb_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *hive, str
|
||||
ldb_set_debug_stderr(c);
|
||||
hive->backend_data = c;
|
||||
|
||||
hive->root = talloc_zero_p(mem_ctx, struct registry_key);
|
||||
hive->root->name = talloc_strdup(mem_ctx, "");
|
||||
hive->root = talloc_zero_p(hive, struct registry_key);
|
||||
hive->root->name = talloc_strdup(hive->root, "");
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
@ -202,7 +202,7 @@ static WERROR ldb_close_hive (struct registry_hive *hive)
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static struct registry_operations reg_backend_ldb = {
|
||||
static struct hive_operations reg_backend_ldb = {
|
||||
.name = "ldb",
|
||||
.add_key = ldb_add_key,
|
||||
.del_key = ldb_del_key,
|
@ -1573,16 +1573,16 @@ error:
|
||||
|
||||
#endif
|
||||
|
||||
static WERROR nt_open_hive (TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **key)
|
||||
static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key)
|
||||
{
|
||||
REGF *regf;
|
||||
REGF_HDR *regf_hdr;
|
||||
uint_t regf_id, hbin_id;
|
||||
HBIN_HDR *hbin_hdr;
|
||||
|
||||
regf = (REGF *)talloc_p(mem_ctx, REGF);
|
||||
regf = (REGF *)talloc_p(h, REGF);
|
||||
memset(regf, 0, sizeof(REGF));
|
||||
regf->owner_sid_str = h->credentials;
|
||||
regf->owner_sid_str = NULL; /* FIXME: Fill in */
|
||||
h->backend_data = regf;
|
||||
|
||||
DEBUG(5, ("Attempting to load registry file\n"));
|
||||
@ -1655,7 +1655,7 @@ static WERROR nt_open_hive (TALLOC_CTX *mem_ctx, struct registry_hive *h, struct
|
||||
|
||||
h->backend_data = regf;
|
||||
|
||||
return nk_to_key(mem_ctx, h, ((REGF *)h->backend_data)->first_key, BLK_SIZE(((REGF *)h->backend_data)->first_key), NULL, key);
|
||||
return nk_to_key(h, h, ((REGF *)h->backend_data)->first_key, BLK_SIZE(((REGF *)h->backend_data)->first_key), NULL, key);
|
||||
}
|
||||
|
||||
|
||||
@ -1724,7 +1724,7 @@ static WERROR nt_key_by_index(TALLOC_CTX *mem_ctx, struct registry_key *k, int n
|
||||
return WERR_NO_MORE_ITEMS;
|
||||
}
|
||||
|
||||
static struct registry_operations reg_backend_nt4 = {
|
||||
static struct hive_operations reg_backend_nt4 = {
|
||||
.name = "nt4",
|
||||
.open_hive = nt_open_hive,
|
||||
.num_subkeys = nt_num_subkeys,
|
@ -21,6 +21,8 @@
|
||||
#include "registry.h"
|
||||
#include "librpc/gen_ndr/ndr_winreg.h"
|
||||
|
||||
static struct hive_operations reg_backend_rpc;
|
||||
|
||||
/**
|
||||
* This is the RPC backend for the registry library.
|
||||
*/
|
||||
@ -76,93 +78,56 @@ struct rpc_key_data {
|
||||
};
|
||||
|
||||
struct {
|
||||
const char *name;
|
||||
uint32 hkey;
|
||||
WERROR (*open) (struct dcerpc_pipe *p, TALLOC_CTX *, struct policy_handle *h);
|
||||
} known_hives[] = {
|
||||
{ "HKEY_LOCAL_MACHINE", open_HKLM },
|
||||
{ "HKEY_CURRENT_USER", open_HKCU },
|
||||
{ "HKEY_CLASSES_ROOT", open_HKCR },
|
||||
{ "HKEY_PERFORMANCE_DATA", open_HKPD },
|
||||
{ "HKEY_USERS", open_HKU },
|
||||
{ "HKEY_DYN_DATA", open_HKDD },
|
||||
{ "HKEY_CURRENT_CONFIG", open_HKCC },
|
||||
{ NULL, NULL }
|
||||
{ HKEY_LOCAL_MACHINE, open_HKLM },
|
||||
{ HKEY_CURRENT_USER, open_HKCU },
|
||||
{ HKEY_CLASSES_ROOT, open_HKCR },
|
||||
{ HKEY_PERFORMANCE_DATA, open_HKPD },
|
||||
{ HKEY_USERS, open_HKU },
|
||||
{ HKEY_DYN_DATA, open_HKDD },
|
||||
{ HKEY_CURRENT_CONFIG, open_HKCC },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static WERROR rpc_query_key(struct registry_key *k);
|
||||
|
||||
static WERROR rpc_list_hives (TALLOC_CTX *mem_ctx, const char *location, const char *credentials, char ***hives)
|
||||
static WERROR rpc_get_hive (struct registry_context *ctx, uint32 hkey_type, struct registry_key **k)
|
||||
{
|
||||
int i = 0;
|
||||
*hives = talloc_p(mem_ctx, char *);
|
||||
for(i = 0; known_hives[i].name; i++) {
|
||||
*hives = talloc_realloc_p(mem_ctx, *hives, char *, i+2);
|
||||
(*hives)[i] = talloc_strdup(mem_ctx, known_hives[i].name);
|
||||
}
|
||||
(*hives)[i] = NULL;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static WERROR rpc_close_hive (struct registry_hive *h)
|
||||
{
|
||||
dcerpc_pipe_close(h->backend_data);
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static WERROR rpc_open_hive(TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **k)
|
||||
{
|
||||
NTSTATUS status;
|
||||
char *user;
|
||||
char *pass;
|
||||
struct rpc_key_data *mykeydata;
|
||||
struct dcerpc_pipe *p;
|
||||
int n;
|
||||
struct registry_hive *h;
|
||||
struct rpc_key_data *mykeydata;
|
||||
|
||||
if (!h->credentials) return WERR_INVALID_PARAM;
|
||||
|
||||
/* Default to local smbd if no connection is specified */
|
||||
if (!h->location) {
|
||||
h->location = talloc_strdup(mem_ctx, "ncalrpc:");
|
||||
}
|
||||
|
||||
user = talloc_strdup(mem_ctx, h->credentials);
|
||||
pass = strchr(user, '%');
|
||||
if (pass) {
|
||||
*pass = '\0';
|
||||
pass = strdup(pass+1);
|
||||
} else {
|
||||
pass = strdup("");
|
||||
}
|
||||
|
||||
status = dcerpc_pipe_connect(&p, h->location,
|
||||
DCERPC_WINREG_UUID,
|
||||
DCERPC_WINREG_VERSION,
|
||||
lp_workgroup(),
|
||||
user, pass);
|
||||
free(pass);
|
||||
|
||||
h->backend_data = p;
|
||||
|
||||
if(NT_STATUS_IS_ERR(status)) {
|
||||
DEBUG(1, ("Unable to open '%s': %s\n", h->location, nt_errstr(status)));
|
||||
return ntstatus_to_werror(status);
|
||||
}
|
||||
|
||||
for(n = 0; known_hives[n].name; n++)
|
||||
for(n = 0; known_hives[n].hkey; n++)
|
||||
{
|
||||
if(!strcmp(known_hives[n].name, h->backend_hivename)) break;
|
||||
if(known_hives[n].hkey == hkey_type) break;
|
||||
}
|
||||
|
||||
if(!known_hives[n].name) {
|
||||
DEBUG(1, ("No such hive %s\n", known_hives[n].name));
|
||||
if(!known_hives[n].open) {
|
||||
DEBUG(1, ("No such hive %d\n", hkey_type));
|
||||
return WERR_NO_MORE_ITEMS;
|
||||
}
|
||||
|
||||
h = talloc_p(ctx, struct registry_hive);
|
||||
h->functions = ®_backend_rpc;
|
||||
h->location = NULL;
|
||||
h->backend_data = ctx->backend_data;
|
||||
h->reg_ctx = ctx;
|
||||
|
||||
*k = talloc_p(mem_ctx, struct registry_key);
|
||||
(*k)->backend_data = mykeydata = talloc_p(mem_ctx, struct rpc_key_data);
|
||||
(*k) = h->root = talloc_p(h, struct registry_key);
|
||||
(*k)->hive = h;
|
||||
(*k)->backend_data = mykeydata = talloc_p(*k, struct rpc_key_data);
|
||||
mykeydata->num_values = -1;
|
||||
mykeydata->num_subkeys = -1;
|
||||
return known_hives[n].open((struct dcerpc_pipe *)h->backend_data, *k, &(mykeydata->pol));
|
||||
return known_hives[n].open((struct dcerpc_pipe *)ctx->backend_data, *k, &(mykeydata->pol));
|
||||
}
|
||||
|
||||
static int rpc_close (void *_h)
|
||||
{
|
||||
struct registry_context *h = _h;
|
||||
dcerpc_pipe_close(h->backend_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -385,10 +350,8 @@ static WERROR rpc_num_subkeys(struct registry_key *key, int *count) {
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static struct registry_operations reg_backend_rpc = {
|
||||
static struct hive_operations reg_backend_rpc = {
|
||||
.name = "rpc",
|
||||
.open_hive = rpc_open_hive,
|
||||
.close_hive = rpc_close_hive,
|
||||
.open_key = rpc_open_key,
|
||||
.get_subkey_by_index = rpc_get_subkey_by_index,
|
||||
.get_value_by_index = rpc_get_value_by_index,
|
||||
@ -396,9 +359,39 @@ static struct registry_operations reg_backend_rpc = {
|
||||
.del_key = rpc_del_key,
|
||||
.num_subkeys = rpc_num_subkeys,
|
||||
.num_values = rpc_num_values,
|
||||
.list_available_hives = rpc_list_hives,
|
||||
};
|
||||
|
||||
WERROR reg_open_remote (struct registry_context **ctx, const char *user, const char *pass, const char *location)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct dcerpc_pipe *p;
|
||||
|
||||
*ctx = talloc_p(NULL, struct registry_context);
|
||||
|
||||
/* Default to local smbd if no connection is specified */
|
||||
if (!location) {
|
||||
location = talloc_strdup(ctx, "ncalrpc:");
|
||||
}
|
||||
|
||||
status = dcerpc_pipe_connect(&p, location,
|
||||
DCERPC_WINREG_UUID,
|
||||
DCERPC_WINREG_VERSION,
|
||||
lp_workgroup(),
|
||||
user, pass);
|
||||
(*ctx)->backend_data = p;
|
||||
|
||||
if(NT_STATUS_IS_ERR(status)) {
|
||||
DEBUG(1, ("Unable to open '%s': %s\n", location, nt_errstr(status)));
|
||||
return ntstatus_to_werror(status);
|
||||
}
|
||||
|
||||
(*ctx)->get_hive = rpc_get_hive;
|
||||
|
||||
talloc_set_destructor(*ctx, rpc_close);
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
NTSTATUS registry_rpc_init(void)
|
||||
{
|
||||
return registry_register(®_backend_rpc);
|
@ -180,14 +180,14 @@ static void parse_rgdb_block(CREG *creg, RGDB_HDR *rgdb_hdr)
|
||||
}
|
||||
}
|
||||
|
||||
static WERROR w95_open_reg (TALLOC_CTX *mem_ctx, struct registry_hive *h, struct registry_key **root)
|
||||
static WERROR w95_open_reg (struct registry_hive *h, struct registry_key **root)
|
||||
{
|
||||
CREG *creg;
|
||||
DWORD creg_id, rgkn_id;
|
||||
DWORD i;
|
||||
DWORD offset;
|
||||
|
||||
creg = talloc_p(mem_ctx, CREG);
|
||||
creg = talloc_p(h, CREG);
|
||||
memset(creg, 0, sizeof(CREG));
|
||||
h->backend_data = creg;
|
||||
|
||||
@ -234,7 +234,7 @@ static WERROR w95_open_reg (TALLOC_CTX *mem_ctx, struct registry_hive *h, struct
|
||||
}
|
||||
#endif
|
||||
|
||||
creg->rgdb_keys = talloc_array_p(mem_ctx, RGDB_KEY **, creg->creg_hdr->num_rgdb);
|
||||
creg->rgdb_keys = talloc_array_p(h, RGDB_KEY **, creg->creg_hdr->num_rgdb);
|
||||
|
||||
offset = 0;
|
||||
DEBUG(3, ("Reading %d rgdb entries\n", creg->creg_hdr->num_rgdb));
|
||||
@ -250,7 +250,7 @@ static WERROR w95_open_reg (TALLOC_CTX *mem_ctx, struct registry_hive *h, struct
|
||||
}
|
||||
|
||||
|
||||
creg->rgdb_keys[i] = talloc_array_p(mem_ctx, RGDB_KEY *, rgdb_hdr->max_id+1);
|
||||
creg->rgdb_keys[i] = talloc_array_p(h, RGDB_KEY *, rgdb_hdr->max_id+1);
|
||||
memset(creg->rgdb_keys[i], 0, sizeof(RGDB_KEY *) * (rgdb_hdr->max_id+1));
|
||||
|
||||
parse_rgdb_block(creg, rgdb_hdr);
|
||||
@ -259,7 +259,7 @@ static WERROR w95_open_reg (TALLOC_CTX *mem_ctx, struct registry_hive *h, struct
|
||||
}
|
||||
|
||||
/* First element in rgkn should be root key */
|
||||
*root = talloc_p(mem_ctx, struct registry_key);
|
||||
*root = talloc_p(h, struct registry_key);
|
||||
(*root)->name = NULL;
|
||||
(*root)->backend_data = LOCN_RGKN(creg, sizeof(RGKN_HDR));
|
||||
|
||||
@ -342,7 +342,7 @@ static WERROR w95_get_value_by_id(TALLOC_CTX *mem_ctx, struct registry_key *k, i
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static struct registry_operations reg_backend_w95 = {
|
||||
static struct hive_operations reg_backend_w95 = {
|
||||
.name = "w95",
|
||||
.open_hive = w95_open_reg,
|
||||
.get_value_by_index = w95_get_value_by_id,
|
@ -22,8 +22,17 @@
|
||||
#include "lib/registry/common/registry.h"
|
||||
#include "windows/registry.h"
|
||||
|
||||
static WERROR wine_open_reg (struct registry_hive *h, struct registry_key **key)
|
||||
{
|
||||
/* FIXME: Open h->location and mmap it */
|
||||
}
|
||||
|
||||
|
||||
|
||||
static REG_OPS reg_backend_wine = {
|
||||
.name = "wine",
|
||||
.open_hive = wine_open_reg,
|
||||
|
||||
};
|
||||
|
||||
NTSTATUS registry_wine_init(void)
|
||||
@ -31,3 +40,9 @@ NTSTATUS registry_wine_init(void)
|
||||
register_backend("registry", ®_backend_wine);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
WERROR reg_open_wine(struct registry_key **ctx)
|
||||
{
|
||||
/* FIXME: Open ~/.wine/system.reg, etc */
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
62
source/lib/registry/reg_samba.c
Normal file
62
source/lib/registry/reg_samba.c
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Copyright (C) Jelmer Vernooij 2004.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "registry.h"
|
||||
|
||||
#undef DBGC_CLASS
|
||||
#define DBGC_CLASS DBGC_REGISTRY
|
||||
|
||||
static WERROR reg_samba_get_hive (struct registry_context *ctx, uint32 hkey, struct registry_key **k)
|
||||
{
|
||||
WERROR error;
|
||||
const char *conf;
|
||||
char *backend, *location;
|
||||
const char *hivename = reg_get_hkey_name(hkey);
|
||||
|
||||
*k = NULL;
|
||||
|
||||
conf = lp_parm_string(-1, "registry", hivename);
|
||||
|
||||
if (!conf) {
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
backend = talloc_strdup(NULL, conf);
|
||||
location = strchr(backend, ':');
|
||||
|
||||
if (location) {
|
||||
*location = '\0';
|
||||
location++;
|
||||
}
|
||||
|
||||
error = reg_open_hive(ctx, backend, location, NULL, k);
|
||||
|
||||
talloc_destroy(backend);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
WERROR reg_open_local (struct registry_context **ctx)
|
||||
{
|
||||
*ctx = talloc_p(NULL, struct registry_context);
|
||||
(*ctx)->get_hive = reg_samba_get_hive;
|
||||
|
||||
return WERR_OK;
|
||||
}
|
@ -113,21 +113,19 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey,
|
||||
{
|
||||
int opt;
|
||||
poptContext pc;
|
||||
const char *backend1 = NULL, *backend2 = NULL;
|
||||
const char *location2;
|
||||
const char *credentials1= NULL, *credentials2 = NULL;
|
||||
char *outputfile = NULL;
|
||||
FILE *fd = stdout;
|
||||
struct registry_context *h1 = NULL, *h2;
|
||||
struct registry_context *h1 = NULL, *h2 = NULL;
|
||||
int from_null = 0;
|
||||
int i;
|
||||
WERROR error, error2;
|
||||
struct poptOption long_options[] = {
|
||||
POPT_AUTOHELP
|
||||
{"backend", 'b', POPT_ARG_STRING, NULL, 'b', "backend to use", NULL},
|
||||
{"credentials", 'c', POPT_ARG_STRING, NULL, 'c', "credentials", NULL},
|
||||
POPT_COMMON_CREDENTIALS
|
||||
{"output", 'o', POPT_ARG_STRING, &outputfile, 'o', "output file to use", NULL },
|
||||
{"null", 'n', POPT_ARG_NONE, &from_null, 'n', "Diff from NULL" },
|
||||
{"null", 'n', POPT_ARG_NONE, &from_null, 'n', "Diff from NULL", NULL },
|
||||
{"remote", 'R', POPT_ARG_STRING, NULL, 0, "Connect to remote server" , NULL },
|
||||
{"local", 'L', POPT_ARG_NONE, NULL, 0, "Open local registry", NULL },
|
||||
POPT_TABLEEND
|
||||
};
|
||||
|
||||
@ -141,50 +139,25 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey,
|
||||
pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0);
|
||||
|
||||
while((opt = poptGetNextOpt(pc)) != -1) {
|
||||
error = WERR_OK;
|
||||
switch(opt) {
|
||||
case 'c':
|
||||
if(!credentials1 && !from_null) credentials1 = poptGetOptArg(pc);
|
||||
else if(!credentials2) credentials2 = poptGetOptArg(pc);
|
||||
case 'L':
|
||||
if (!h1 && !from_null) error = reg_open_local(&h1);
|
||||
else if (!h2) error = reg_open_local(&h2);
|
||||
break;
|
||||
case 'b':
|
||||
if(!backend1 && !from_null) backend1 = poptGetOptArg(pc);
|
||||
else if(!backend2) backend2 = poptGetOptArg(pc);
|
||||
case 'R':
|
||||
if (!h1 && !from_null) error = reg_open_remote(&h1, cmdline_get_username(), cmdline_get_userpassword(), poptGetOptArg(pc));
|
||||
else if (!h2) error = reg_open_remote(&h2, cmdline_get_username(), cmdline_get_userpassword(), poptGetOptArg(pc));
|
||||
break;
|
||||
}
|
||||
|
||||
if (!W_ERROR_IS_OK(error)) {
|
||||
fprintf(stderr, "Error: %s\n", win_errstr(error));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
setup_logging(argv[0], True);
|
||||
|
||||
if(!from_null) {
|
||||
const char *location1;
|
||||
location1 = poptGetArg(pc);
|
||||
if(!location1) {
|
||||
poptPrintUsage(pc, stderr, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!backend1) backend1 = "rpc";
|
||||
|
||||
error = reg_open(&h1, backend1, location1, credentials1);
|
||||
if(!W_ERROR_IS_OK(error)) {
|
||||
fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location1, backend1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
location2 = poptGetArg(pc);
|
||||
if(!location2) {
|
||||
poptPrintUsage(pc, stderr, 0);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if(!backend2) backend2 = "rpc";
|
||||
|
||||
error = reg_open(&h2, backend2, location2, credentials2);
|
||||
if(!W_ERROR_IS_OK(error)) {
|
||||
fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location2, backend2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
poptFreeContext(pc);
|
||||
|
||||
if(outputfile) {
|
||||
@ -196,12 +169,25 @@ static void writediff(struct registry_key *oldkey, struct registry_key *newkey,
|
||||
}
|
||||
|
||||
fprintf(fd, "REGEDIT4\n\n");
|
||||
fprintf(fd, "; Generated using regdiff\n");
|
||||
fprintf(fd, "; Generated using regdiff, part of Samba\n");
|
||||
|
||||
error2 = error = WERR_OK;
|
||||
|
||||
for(i = 0; (!h1 || i < h1->num_hives) && i < h2->num_hives; i++) {
|
||||
writediff(h1?h1->hives[i]->root:NULL, h2->hives[i]->root, fd);
|
||||
for(i = HKEY_CLASSES_ROOT; i <= HKEY_PN; i++) {
|
||||
struct registry_key *r1, *r2;
|
||||
error = reg_get_hive(h1, i, &r1);
|
||||
if (!W_ERROR_IS_OK(error)) {
|
||||
DEBUG(0, ("Unable to open hive %s for backend 1\n", reg_get_hkey_name(i)));
|
||||
continue;
|
||||
}
|
||||
|
||||
error = reg_get_hive(h2, i, &r2);
|
||||
if (!W_ERROR_IS_OK(error)) {
|
||||
DEBUG(0, ("Unable to open hive %s for backend 2\n", reg_get_hkey_name(i)));
|
||||
continue;
|
||||
}
|
||||
|
||||
writediff(r1, r2, fd);
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
|
@ -758,16 +758,14 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd
|
||||
{
|
||||
int opt;
|
||||
poptContext pc;
|
||||
const char *location;
|
||||
const char *credentials = NULL;
|
||||
const char *patch;
|
||||
const char *backend = "rpc";
|
||||
struct registry_context *h;
|
||||
const char *remote = NULL;
|
||||
WERROR error;
|
||||
struct poptOption long_options[] = {
|
||||
POPT_AUTOHELP
|
||||
{"backend", 'b', POPT_ARG_STRING, &backend, 'b', "backend to use", NULL},
|
||||
{"credentials", 'c', POPT_ARG_STRING, &credentials, 'c', "credentials (user%password", NULL},
|
||||
POPT_COMMON_CREDENTIALS
|
||||
{"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL},
|
||||
POPT_TABLEEND
|
||||
};
|
||||
|
||||
@ -785,25 +783,22 @@ static int nt_apply_reg_command_file(struct registry_context *r, const char *cmd
|
||||
|
||||
setup_logging(argv[0], True);
|
||||
|
||||
location = poptGetArg(pc);
|
||||
if(!location) {
|
||||
poptPrintUsage(pc, stderr, 0);
|
||||
return 1;
|
||||
if (remote) {
|
||||
error = reg_open_remote (&h, cmdline_get_username(), cmdline_get_userpassword(), remote);
|
||||
} else {
|
||||
error = reg_open_local (&h);
|
||||
}
|
||||
|
||||
error = reg_open(&h, backend, location, credentials);
|
||||
if(!h) {
|
||||
fprintf(stderr, "Unable to open '%s' with backend '%s'\n", location, backend);
|
||||
if (W_ERROR_IS_OK(error)) {
|
||||
fprintf(stderr, "Error: %s\n", win_errstr(error));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
patch = poptGetArg(pc);
|
||||
if(!patch) patch = "/dev/stdin";
|
||||
poptFreeContext(pc);
|
||||
|
||||
nt_apply_reg_command_file(h, patch);
|
||||
|
||||
talloc_destroy(h->mem_ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -164,15 +164,23 @@ static struct registry_key *cmd_rmval(TALLOC_CTX *mem_ctx, struct registry_key *
|
||||
|
||||
static struct registry_key *cmd_hive(TALLOC_CTX *mem_ctx, struct registry_key *cur, int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < cur->hive->reg_ctx->num_hives; i++) {
|
||||
|
||||
if(argc == 1) {
|
||||
printf("%s\n", cur->hive->reg_ctx->hives[i]->name);
|
||||
} else if(!strcmp(cur->hive->reg_ctx->hives[i]->name, argv[1])) {
|
||||
return cur->hive->reg_ctx->hives[i]->root;
|
||||
}
|
||||
if (!cur->hive->reg_ctx) {
|
||||
fprintf(stderr, "Only one hive loaded\n");
|
||||
return cur;
|
||||
}
|
||||
|
||||
if (argc == 1) {
|
||||
printf("%s\n", cur->hive->root->name);
|
||||
} else {
|
||||
struct registry_key *newroot;
|
||||
WERROR error = reg_get_hive_by_name(cur->hive->reg_ctx, argv[1], &newroot);
|
||||
if (W_ERROR_IS_OK(error)) {
|
||||
return newroot;
|
||||
} else {
|
||||
fprintf(stderr, "Can't switch to hive %s: %s\n", cur->hive->root->name, win_errstr(error));
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -274,11 +282,7 @@ static char **reg_complete_command(const char *text, int end)
|
||||
matches[0] = strdup(matches[1]);
|
||||
break;
|
||||
default:
|
||||
matches[0] = malloc(samelen+1);
|
||||
if (!matches[0])
|
||||
goto cleanup;
|
||||
strncpy(matches[0], matches[1], samelen);
|
||||
matches[0][samelen] = 0;
|
||||
matches[0] = strndup(matches[1], samelen);
|
||||
}
|
||||
matches[count] = NULL;
|
||||
return matches;
|
||||
@ -295,11 +299,11 @@ cleanup:
|
||||
static char **reg_complete_key(const char *text, int end)
|
||||
{
|
||||
struct registry_key *subkey;
|
||||
int i, j = 0;
|
||||
int i, j = 1;
|
||||
int samelen = 0;
|
||||
int len;
|
||||
char **matches;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
/* Complete argument */
|
||||
|
||||
matches = malloc_array_p(char *, MAX_COMPLETIONS);
|
||||
if (!matches) return NULL;
|
||||
@ -313,6 +317,12 @@ static char **reg_complete_key(const char *text, int end)
|
||||
if(!strncmp(text, subkey->name, len)) {
|
||||
matches[j] = strdup(subkey->name);
|
||||
j++;
|
||||
|
||||
if (j == 1)
|
||||
samelen = strlen(matches[j]);
|
||||
else
|
||||
while (strncmp(matches[j], matches[j-1], samelen) != 0)
|
||||
samelen--;
|
||||
}
|
||||
} else if(W_ERROR_EQUAL(status, WERR_NO_MORE_ITEMS)) {
|
||||
break;
|
||||
@ -322,8 +332,20 @@ static char **reg_complete_key(const char *text, int end)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
matches[j] = NULL;
|
||||
talloc_destroy(mem_ctx);
|
||||
|
||||
if (j == 1) { /* No matches at all */
|
||||
SAFE_FREE(matches);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (j == 2) { /* Exact match */
|
||||
matches[0] = strdup(matches[1]);
|
||||
} else {
|
||||
matches[0] = strndup(matches[1], samelen);
|
||||
}
|
||||
|
||||
matches[j] = NULL;
|
||||
return matches;
|
||||
}
|
||||
|
||||
@ -341,18 +363,18 @@ static char **reg_completion(const char *text, int start, int end)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
const char *backend = "rpc";
|
||||
const char *credentials = NULL;
|
||||
const char *backend = NULL;
|
||||
struct registry_key *curkey = NULL;
|
||||
poptContext pc;
|
||||
WERROR error;
|
||||
TALLOC_CTX *mem_ctx = talloc_init("cmd");
|
||||
struct registry_context *h;
|
||||
const char *remote = NULL;
|
||||
struct registry_context *h = NULL;
|
||||
struct poptOption long_options[] = {
|
||||
POPT_AUTOHELP
|
||||
POPT_COMMON_SAMBA
|
||||
POPT_COMMON_CREDENTIALS
|
||||
{"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL},
|
||||
{"credentials", 'c', POPT_ARG_STRING, &credentials, 0, "credentials", NULL},
|
||||
{"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL},
|
||||
POPT_TABLEEND
|
||||
};
|
||||
|
||||
@ -370,20 +392,31 @@ static char **reg_completion(const char *text, int start, int end)
|
||||
|
||||
setup_logging("regtree", True);
|
||||
|
||||
error = reg_open(&h, backend, poptPeekArg(pc), credentials);
|
||||
if (remote) {
|
||||
error = reg_open_remote (&h, cmdline_get_username(), cmdline_get_userpassword(), remote);
|
||||
} else if (backend) {
|
||||
error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, &curkey);
|
||||
} else {
|
||||
error = reg_open_local(&h);
|
||||
}
|
||||
|
||||
if(!W_ERROR_IS_OK(error)) {
|
||||
fprintf(stderr, "Unable to open '%s' with backend '%s'\n", poptGetArg(pc), backend);
|
||||
fprintf(stderr, "Unable to open registry\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (h) {
|
||||
/*FIXME: What if HKEY_CLASSES_ROOT is not present ? */
|
||||
reg_get_hive(h, HKEY_CLASSES_ROOT, &curkey);
|
||||
}
|
||||
|
||||
poptFreeContext(pc);
|
||||
|
||||
curkey = h->hives[0]->root;
|
||||
|
||||
|
||||
while(True) {
|
||||
char *line, *prompt;
|
||||
|
||||
if(curkey->hive->name) {
|
||||
asprintf(&prompt, "%s:%s> ", curkey->hive->name, curkey->path);
|
||||
if(curkey->hive->root->name) {
|
||||
asprintf(&prompt, "%s:%s> ", curkey->hive->root->name, curkey->path);
|
||||
} else {
|
||||
asprintf(&prompt, "%s> ", curkey->path);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals)
|
||||
|
||||
/* Hive name */
|
||||
if(p->hive->root == p) {
|
||||
if(p->hive->name) printf("%s\n", p->hive->name); else printf("<No Name>\n");
|
||||
if(p->hive->root->name) printf("%s\n", p->hive->root->name); else printf("<No Name>\n");
|
||||
} else {
|
||||
if(!p->name) printf("<No Name>\n");
|
||||
if(fullpath) printf("%s\n", p->path);
|
||||
@ -73,17 +73,19 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int opt, i;
|
||||
const char *backend = "rpc";
|
||||
const char *credentials = NULL;
|
||||
const char *backend = NULL;
|
||||
const char *remote = NULL;
|
||||
poptContext pc;
|
||||
struct registry_context *h;
|
||||
struct registry_context *h = NULL;
|
||||
struct registry_key *root = NULL;
|
||||
WERROR error;
|
||||
int fullpath = 0, no_values = 0;
|
||||
struct poptOption long_options[] = {
|
||||
POPT_AUTOHELP
|
||||
POPT_COMMON_CREDENTIALS
|
||||
{"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL},
|
||||
{"fullpath", 'f', POPT_ARG_NONE, &fullpath, 0, "show full paths", NULL},
|
||||
{"credentials", 'c', POPT_ARG_STRING, &credentials, 0, "credentials (user%password)", NULL},
|
||||
{"remote", 'R', POPT_ARG_STRING, &remote, 0, "connect to specified remote server", NULL },
|
||||
{"no-values", 'V', POPT_ARG_NONE, &no_values, 0, "don't show values", NULL},
|
||||
POPT_TABLEEND
|
||||
};
|
||||
@ -102,7 +104,14 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals)
|
||||
|
||||
setup_logging("regtree", True);
|
||||
|
||||
error = reg_open(&h, backend, poptPeekArg(pc), credentials);
|
||||
if (remote) {
|
||||
error = reg_open_remote(&h, cmdline_get_username(), cmdline_get_userpassword(), remote);
|
||||
} else if (backend) {
|
||||
error = reg_open_hive(NULL, backend, poptGetArg(pc), NULL, &root);
|
||||
} else {
|
||||
error = reg_open_local (&h);
|
||||
}
|
||||
|
||||
if(!W_ERROR_IS_OK(error)) {
|
||||
fprintf(stderr, "Unable to open '%s' with backend '%s':%s \n", poptGetArg(pc), backend, win_errstr(error));
|
||||
return 1;
|
||||
@ -110,10 +119,19 @@ static void print_tree(int l, struct registry_key *p, int fullpath, int novals)
|
||||
poptFreeContext(pc);
|
||||
|
||||
error = WERR_OK;
|
||||
|
||||
for(i = 0; i < h->num_hives; i++) {
|
||||
print_tree(0, h->hives[i]->root, fullpath, no_values);
|
||||
}
|
||||
|
||||
if (!h) {
|
||||
print_tree(0, root, fullpath, no_values);
|
||||
} else {
|
||||
for(i = HKEY_CLASSES_ROOT; i < HKEY_PN; i++) {
|
||||
error = reg_get_hive(h, i, &root);
|
||||
if (!W_ERROR_IS_OK(error)) {
|
||||
fprintf(stderr, "Skipping %s\n", reg_get_hkey_name(i));
|
||||
continue;
|
||||
}
|
||||
print_tree(0, root, fullpath, no_values);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
3
source/rpc_server/winreg/README
Normal file
3
source/rpc_server/winreg/README
Normal file
@ -0,0 +1,3 @@
|
||||
This is the RPC server for the registry for Samba. It is basically
|
||||
a front-end for the registry library in lib/registry. See lib/registry/README for
|
||||
more details.
|
@ -28,40 +28,34 @@
|
||||
|
||||
enum handle_types { HTYPE_REGVAL, HTYPE_REGKEY };
|
||||
|
||||
static void winreg_destroy_hive(struct dcesrv_connection *c, struct dcesrv_handle *h)
|
||||
{
|
||||
reg_close(((struct registry_key *)h->data)->hive->reg_ctx);
|
||||
}
|
||||
|
||||
static WERROR winreg_openhive (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, const char *hivename, struct policy_handle **outh)
|
||||
static NTSTATUS dcerpc_winreg_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface)
|
||||
{
|
||||
struct registry_context *ctx;
|
||||
reg_open_local(&ctx);
|
||||
|
||||
dce_call->conn->private = ctx;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
#define DCESRV_INTERFACE_WINREG_BIND dcerpc_winreg_bind
|
||||
|
||||
static WERROR winreg_openhive (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, uint32_t hkey, struct policy_handle **outh)
|
||||
{
|
||||
struct registry_context *ctx = dce_call->conn->private;
|
||||
struct dcesrv_handle *h;
|
||||
WERROR error;
|
||||
const char *conf = lp_parm_string(-1, "registry", hivename);
|
||||
char *backend, *location;
|
||||
|
||||
if (!conf) {
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
backend = talloc_strdup(mem_ctx, conf);
|
||||
location = strchr(backend, ':');
|
||||
|
||||
if (location) {
|
||||
*location = '\0';
|
||||
location++;
|
||||
}
|
||||
|
||||
error = reg_open(&ctx, backend, location, NULL);
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
|
||||
h = dcesrv_handle_new(dce_call->conn, HTYPE_REGKEY);
|
||||
h->data = ctx->hives[0]->root;
|
||||
SMB_ASSERT(h->data);
|
||||
h->destroy = winreg_destroy_hive;
|
||||
|
||||
error = reg_get_hive(ctx, hkey, (struct registry_key **)&h->data);
|
||||
if (!W_ERROR_IS_OK(error)) {
|
||||
return error;
|
||||
}
|
||||
|
||||
*outh = &h->wire_handle;
|
||||
return WERR_OK;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
#define func_winreg_OpenHive(k,n) static WERROR winreg_Open ## k (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_Open ## k *r) \
|
||||
@ -69,15 +63,15 @@ static WERROR winreg_openhive (struct dcesrv_call_state *dce_call, TALLOC_CTX *m
|
||||
return winreg_openhive (dce_call, mem_ctx, n, &r->out.handle);\
|
||||
}
|
||||
|
||||
func_winreg_OpenHive(HKCR,"HKEY_CLASSES_ROOT")
|
||||
func_winreg_OpenHive(HKCU,"HKEY_CURRENT_USER")
|
||||
func_winreg_OpenHive(HKLM,"HKEY_LOCAL_MACHINE")
|
||||
func_winreg_OpenHive(HKPD,"HKEY_PERFORMANCE_DATA")
|
||||
func_winreg_OpenHive(HKU,"HKEY_USERS")
|
||||
func_winreg_OpenHive(HKCC,"HKEY_CURRENT_CONFIG")
|
||||
func_winreg_OpenHive(HKDD,"HKEY_DYN_DATA")
|
||||
func_winreg_OpenHive(HKPT,"HKEY_PT")
|
||||
func_winreg_OpenHive(HKPN,"HKEY_PN")
|
||||
func_winreg_OpenHive(HKCR,HKEY_CLASSES_ROOT)
|
||||
func_winreg_OpenHive(HKCU,HKEY_CURRENT_USER)
|
||||
func_winreg_OpenHive(HKLM,HKEY_LOCAL_MACHINE)
|
||||
func_winreg_OpenHive(HKPD,HKEY_PERFORMANCE_DATA)
|
||||
func_winreg_OpenHive(HKU,HKEY_USERS)
|
||||
func_winreg_OpenHive(HKCC,HKEY_CURRENT_CONFIG)
|
||||
func_winreg_OpenHive(HKDD,HKEY_DYN_DATA)
|
||||
func_winreg_OpenHive(HKPT,HKEY_PT)
|
||||
func_winreg_OpenHive(HKPN,HKEY_PN)
|
||||
|
||||
/*
|
||||
winreg_CloseKey
|
||||
|
@ -451,6 +451,7 @@ static BOOL test_InitiateSystemShutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_c
|
||||
struct winreg_InitiateSystemShutdown r;
|
||||
NTSTATUS status;
|
||||
|
||||
init_winreg_String(&r.in.hostname, NULL);
|
||||
init_winreg_String(&r.in.message, msg);
|
||||
r.in.flags = 0;
|
||||
r.in.timeout = timeout;
|
||||
|
Loading…
Reference in New Issue
Block a user