1
0
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:
Jelmer Vernooij 2004-12-10 20:07:04 +00:00 committed by Gerald (Jerry) Carter
parent 573230ea99
commit c169e86c1f
21 changed files with 559 additions and 425 deletions

View File

@ -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(&registry, 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(&registry, "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(&registry, "rpc", location, credentials);
error = reg_open_remote(&registry,
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(&registry, 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(&registry);
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;
}

View 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);
};

View File

@ -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;
};

View 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.

View File

@ -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)
{

View File

@ -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

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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 = &reg_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(&reg_backend_rpc);

View File

@ -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,

View File

@ -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", &reg_backend_wine);
return NT_STATUS_OK;
}
WERROR reg_open_wine(struct registry_key **ctx)
{
/* FIXME: Open ~/.wine/system.reg, etc */
return WERR_NOT_SUPPORTED;
}

View 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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View 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.

View File

@ -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

View File

@ -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;