1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-27 22:50:26 +03:00

r128: Another registry update. Changes:

- Start with the LDB backend
- The API is now more windows-like, which should make it easier to use
  in rpc_server
- Added a GTK+ front-end
- Added some more IDL

More updates will follow, especially in the RPC field..
(This used to be commit 3adffa021779b26047a20f16a3c0b53d74751560)
This commit is contained in:
Jelmer Vernooij 2004-04-08 22:39:47 +00:00 committed by Gerald (Jerry) Carter
parent d907dcf383
commit aebfb3b9f4
19 changed files with 1490 additions and 591 deletions

View File

@ -140,6 +140,7 @@ DCERPC_LIBS = @DCERPC_LIBS@
REG_OBJS = @REG_OBJS@
REG_LIBS = @REG_LIBS@
GTK_LIBS = @GTK_LIBS@
TORTURE_RAW_OBJS = @TORTURE_RAW_OBJS@
@ -191,6 +192,7 @@ NDRDUMP_OBJS = utils/ndrdump.o utils/rewrite.o \
NDRDUMP_LIBS = $(LIBSMB_LIBS) $(CONFIG_LIBS) $(LIBBASIC_LIBS)
REGTREE_OBJ = $(REG_OBJS) lib/registry/tools/regtree.o $(LIBBASIC_OBJS) $(CONFIG_OBJS) $(LIBSMB_OBJS)
GREGEDIT_OBJ = $(REG_OBJS) lib/registry/tools/gregedit.o $(LIBBASIC_OBJS) $(CONFIG_OBJS) $(LIBSMB_OBJS)
REGSHELL_OBJ = $(REG_OBJS) lib/registry/tools/regshell.o $(LIBBASIC_OBJS) $(CONFIG_OBJS) $(LIBCMDLINE_OBJS) $(LIBSMB_OBJS)
REGPATCH_OBJ = $(REG_OBJS) lib/registry/tools/regpatch.o $(LIBBASIC_OBJS) $(CONFIG_OBJS) $(LIBSMB_OBJS)
REGDIFF_OBJ = $(REG_OBJS) lib/registry/tools/regdiff.o $(LIBBASIC_OBJS) $(CONFIG_OBJS) $(LIBSMB_OBJS)
@ -350,6 +352,10 @@ bin/regtree@EXEEXT@: $(REGTREE_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(REGTREE_OBJ) $(LDFLAGS) $(LIBS) $(REG_LIBS)
bin/gregedit@EXEEXT@: $(GREGEDIT_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLGS) -o $@ $(GREGEDIT_OBJ) $(LDFLAGS) $(LIBS) $(REG_LIBS) $(GTK_LIBS)
bin/regpatch@EXEEXT@: $(REGPATCH_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(REGPATCH_OBJ) $(LDFLAGS) $(LIBS) $(REG_LIBS)

View File

@ -231,4 +231,7 @@
#define WERR_DFS_INTERNAL_ERROR W_ERROR(NERR_BASE+590)
#define WERR_DFS_CANT_CREATE_JUNCT W_ERROR(NERR_BASE+569)
#define WERR_FOOBAR WERR_GENERAL_FAILURE
#endif /* _DOSERR_H */

View File

@ -1,126 +0,0 @@
#ifndef _PROTO_H_
#define _PROTO_H_
/* This file is automatically generated with "make proto". DO NOT EDIT */
/* The following definitions come from common/ldb.c */
struct ldb_context *ldb_connect(const char *url, unsigned int flags,
const char *options[]);
int ldb_close(struct ldb_context *ldb);
int ldb_search(struct ldb_context *ldb,
const char *base,
enum ldb_scope scope,
const char *expression,
const char *attrs[], struct ldb_message ***res);
int ldb_search_free(struct ldb_context *ldb, struct ldb_message **msgs);
int ldb_add(struct ldb_context *ldb,
const struct ldb_message *message);
int ldb_modify(struct ldb_context *ldb,
const struct ldb_message *message);
int ldb_delete(struct ldb_context *ldb, const char *dn);
const char *ldb_errstring(struct ldb_context *ldb);
/* The following definitions come from common/ldb_ldif.c */
char *ldb_base64_encode(const char *buf, int len);
int ldb_should_b64_encode(const struct ldb_val *val);
int ldif_write(int (*fprintf_fn)(void *, const char *, ...),
void *private,
const struct ldb_message *msg);
void ldif_read_free(struct ldb_message *msg);
struct ldb_message *ldif_read(int (*fgetc_fn)(void *), void *private);
struct ldb_message *ldif_read_file(FILE *f);
struct ldb_message *ldif_read_string(const char *s);
int ldif_write_file(FILE *f, const struct ldb_message *msg);
/* The following definitions come from common/ldb_parse.c */
struct ldb_parse_tree *ldb_parse_tree(const char *s);
void ldb_parse_tree_free(struct ldb_parse_tree *tree);
/* The following definitions come from common/util.c */
void *realloc_array(void *ptr, size_t el_size, unsigned count);
int list_find(const void *needle,
const void *base, size_t nmemb, size_t size, comparison_fn_t comp_fn);
/* The following definitions come from ldb_ldap/ldb_ldap.c */
struct ldb_context *lldb_connect(const char *url,
unsigned int flags,
const char *options[]);
/* The following definitions come from ldb_tdb/ldb_index.c */
int ltdb_search_indexed(struct ldb_context *ldb,
const char *base,
enum ldb_scope scope,
struct ldb_parse_tree *tree,
const char *attrs[], struct ldb_message ***res);
int ltdb_index_add(struct ldb_context *ldb, const struct ldb_message *msg);
int ltdb_index_del(struct ldb_context *ldb, const struct ldb_message *msg);
/* The following definitions come from ldb_tdb/ldb_match.c */
int ldb_message_match(struct ldb_context *ldb,
struct ldb_message *msg,
struct ldb_parse_tree *tree,
const char *base,
enum ldb_scope scope);
/* The following definitions come from ldb_tdb/ldb_pack.c */
int ltdb_pack_data(struct ldb_context *ctx,
const struct ldb_message *message,
struct TDB_DATA *data);
int ltdb_unpack_data(struct ldb_context *ctx,
const struct TDB_DATA *data,
struct ldb_message *message);
/* The following definitions come from ldb_tdb/ldb_search.c */
int ldb_msg_find_attr(const struct ldb_message *msg, const char *attr);
int ltdb_has_wildcard(const struct ldb_val *val);
void ltdb_search_dn1_free(struct ldb_context *ldb, struct ldb_message *msg);
int ltdb_search_dn1(struct ldb_context *ldb, const char *dn, struct ldb_message *msg);
int ltdb_search_dn(struct ldb_context *ldb, char *dn,
const char *attrs[], struct ldb_message ***res);
int ltdb_add_attr_results(struct ldb_context *ldb, struct ldb_message *msg,
const char *attrs[],
unsigned int *count,
struct ldb_message ***res);
int ltdb_search_free(struct ldb_context *ldb, struct ldb_message **msgs);
int ltdb_search(struct ldb_context *ldb, const char *base,
enum ldb_scope scope, const char *expression,
const char *attrs[], struct ldb_message ***res);
/* The following definitions come from ldb_tdb/ldb_tdb.c */
struct TDB_DATA ltdb_key(const char *dn);
int ltdb_store(struct ldb_context *ldb, const struct ldb_message *msg, int flgs);
int ltdb_delete_noindex(struct ldb_context *ldb, const char *dn);
struct ldb_context *ltdb_connect(const char *url,
unsigned int flags,
const char *options[]);
/* The following definitions come from ldb_tdb/ldbadd.c */
/* The following definitions come from ldb_tdb/ldbdel.c */
/* The following definitions come from ldb_tdb/ldbsearch.c */
/* The following definitions come from tools/ldbadd.c */
/* The following definitions come from tools/ldbdel.c */
/* The following definitions come from tools/ldbsearch.c */
#endif /* _PROTO_H_ */

View File

@ -1,10 +1,6 @@
- support subtrees
- ../../, /bla/blie support in regshell
- use memory pools?
- get rid of all the nasty memory leaks..
- security stuff
- clean up code
- rpc_server
- ..\..\, \bla\blie support in regshell
- finish rpc_server
reg_backend_dir:
- value support
@ -15,9 +11,15 @@ reg_backend_nt4:
reg_backend_rpc:
- value enum support
- write support
- rewrite
reg_backend_ldb:
- implement
- finish
reg_backend_wine.c:
- implement
- finish
gregedit.c:
- support for editing values / adding values / deleting values
- support for adding/deleting keys
- support for security descriptors

View File

@ -32,7 +32,7 @@ static struct reg_init_function_entry *reg_find_backend_entry(const char *name);
/* Register new backend */
NTSTATUS registry_register(void *_function)
{
REG_OPS *functions = _function;
struct registry_ops *functions = _function;
struct reg_init_function_entry *entry = backends;
if (!functions || !functions->name) {
@ -69,17 +69,19 @@ static struct reg_init_function_entry *reg_find_backend_entry(const char *name)
}
/* Open a registry file/host/etc */
REG_HANDLE *reg_open(const char *backend, const char *location, BOOL try_full_load)
WERROR reg_open(const char *backend, const char *location, const char *credentials, REG_HANDLE **h)
{
struct reg_init_function_entry *entry;
static BOOL reg_first_init = True;
TALLOC_CTX *mem_ctx;
REG_HANDLE *ret;
NTSTATUS status;
WERROR werr;
if(reg_first_init) {
if (!NT_STATUS_IS_OK(register_subsystem("registry", registry_register))) {
return False;
}
status = register_subsystem("registry", registry_register);
if (!NT_STATUS_IS_OK(status))
return WERR_GENERAL_FAILURE;
static_init_reg;
reg_first_init = False;
@ -89,7 +91,7 @@ REG_HANDLE *reg_open(const char *backend, const char *location, BOOL try_full_lo
if (!entry) {
DEBUG(0, ("No such registry backend '%s' loaded!\n", backend));
return NULL;
return WERR_GENERAL_FAILURE;
}
mem_ctx = talloc_init(backend);
@ -99,31 +101,35 @@ REG_HANDLE *reg_open(const char *backend, const char *location, BOOL try_full_lo
ret->functions = entry->functions;
ret->backend_data = NULL;
ret->mem_ctx = mem_ctx;
*h = ret;
if(!entry->functions->open_registry) {
return ret;
return WERR_OK;
}
if(entry->functions->open_registry(ret, location, try_full_load))
return ret;
werr = entry->functions->open_registry(ret, location, credentials);
if(W_ERROR_IS_OK(werr))
return WERR_OK;
talloc_destroy(mem_ctx);
return NULL;
return werr;
}
/* Open a key
* First tries to use the open_key function from the backend
* then falls back to get_subkey_by_name and later get_subkey_by_index
*/
REG_KEY *reg_open_key(REG_KEY *parent, const char *name)
WERROR reg_open_key(REG_KEY *parent, const char *name, REG_KEY **result)
{
char *fullname;
WERROR status;
REG_KEY *ret = NULL;
TALLOC_CTX *mem_ctx;
if(!parent) {
DEBUG(0, ("Invalid parent key specified"));
return NULL;
return WERR_INVALID_PARAM;
}
if(!parent->handle->functions->open_key &&
@ -136,10 +142,10 @@ REG_KEY *reg_open_key(REG_KEY *parent, const char *name)
while(curbegin && *curbegin) {
if(curend)*curend = '\0';
curkey = reg_key_get_subkey_by_name(curkey, curbegin);
if(!curkey) {
status = reg_key_get_subkey_by_name(curkey, curbegin, result);
if(!NT_STATUS_IS_OK(status)) {
SAFE_FREE(orig);
return NULL;
return status;
}
if(!curend) break;
curbegin = curend + 1;
@ -147,255 +153,287 @@ REG_KEY *reg_open_key(REG_KEY *parent, const char *name)
}
SAFE_FREE(orig);
return curkey;
*result = curkey;
return WERR_OK;
}
mem_ctx = talloc_init("mem_ctx");
fullname = talloc_asprintf(mem_ctx, "%s%s%s", parent->path, parent->path[strlen(parent->path)-1] == '\\'?"":"\\", name);
\
if(!parent->handle->functions->open_key) {
DEBUG(0, ("Registry backend doesn't have get_subkey_by_name nor open_key!\n"));
return NULL;
return WERR_NOT_SUPPORTED;
}
ret = parent->handle->functions->open_key(parent->handle, fullname);
status = parent->handle->functions->open_key(parent->handle, fullname, result);
if(ret) {
ret->handle = parent->handle;
ret->path = fullname;
talloc_steal(mem_ctx, ret->mem_ctx, fullname);
if(!NT_STATUS_IS_OK(status)) {
talloc_destroy(mem_ctx);
return status;
}
ret->handle = parent->handle;
ret->path = fullname;
talloc_steal(mem_ctx, ret->mem_ctx, fullname);
talloc_destroy(mem_ctx);
return ret;
*result = ret;
return WERR_OK;
}
REG_VAL *reg_key_get_value_by_index(REG_KEY *key, int idx)
WERROR reg_key_get_value_by_index(REG_KEY *key, int idx, REG_VAL **val)
{
REG_VAL *ret;
if(!key) return NULL;
if(!key) return WERR_INVALID_PARAM;
if(!key->handle->functions->get_value_by_index) {
if(!key->cache_values)
key->handle->functions->fetch_values(key, &key->cache_values_count, &key->cache_values);
if(idx < key->cache_values_count && idx >= 0) {
ret = reg_val_dup(key->cache_values[idx]);
*val = reg_val_dup(key->cache_values[idx]);
} else {
return NULL;
return WERR_NO_MORE_ITEMS;
}
} else {
ret = key->handle->functions->get_value_by_index(key, idx);
WERROR status = key->handle->functions->get_value_by_index(key, idx, val);
if(!W_ERROR_IS_OK(status))
return status;
}
if(ret) {
ret->parent = key;
ret->handle = key->handle;
}
return ret;
(*val)->parent = key;
(*val)->handle = key->handle;
return WERR_OK;
}
int reg_key_num_subkeys(REG_KEY *key)
WERROR reg_key_num_subkeys(REG_KEY *key, int *count)
{
if(!key) return 0;
if(!key) return WERR_INVALID_PARAM;
if(!key->handle->functions->num_subkeys) {
if(!key->cache_subkeys)
key->handle->functions->fetch_subkeys(key, &key->cache_subkeys_count, &key->cache_subkeys);
return key->cache_subkeys_count;
*count = key->cache_subkeys_count;
return WERR_OK;
}
return key->handle->functions->num_subkeys(key);
return key->handle->functions->num_subkeys(key, count);
}
int reg_key_num_values(REG_KEY *key)
WERROR reg_key_num_values(REG_KEY *key, int *count)
{
if(!key) return 0;
if(!key) return WERR_INVALID_PARAM;
if(!key->handle->functions->num_values) {
if(!key->handle->functions->fetch_values) {
DEBUG(1, ("Backend '%s' doesn't support enumerating values\n", key->handle->functions->name));
return 0;
return WERR_NOT_SUPPORTED;
}
if(!key->cache_values)
key->handle->functions->fetch_values(key, &key->cache_values_count, &key->cache_values);
return key->cache_values_count;
*count = key->cache_values_count;
return WERR_OK;
}
return key->handle->functions->num_values(key);
return key->handle->functions->num_values(key, count);
}
REG_KEY *reg_key_get_subkey_by_index(REG_KEY *key, int idx)
WERROR reg_key_get_subkey_by_index(REG_KEY *key, int idx, REG_KEY **subkey)
{
REG_KEY *ret = NULL;
if(!key) return NULL;
if(!key) return WERR_INVALID_PARAM;
if(!key->handle->functions->get_subkey_by_index) {
if(!key->cache_subkeys)
key->handle->functions->fetch_subkeys(key, &key->cache_subkeys_count, &key->cache_subkeys);
if(idx < key->cache_subkeys_count) {
ret = reg_key_dup(key->cache_subkeys[idx]);
*subkey = reg_key_dup(key->cache_subkeys[idx]);
} else {
/* No such key ! */
return NULL;
return WERR_NO_MORE_ITEMS;
}
} else {
ret = key->handle->functions->get_subkey_by_index(key, idx);
WERROR status = key->handle->functions->get_subkey_by_index(key, idx, subkey);
if(!NT_STATUS_IS_OK(status)) return status;
}
if(ret && !ret->path) {
ret->path = talloc_asprintf(ret->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name);
ret->handle = key->handle;
}
(*subkey)->path = talloc_asprintf((*subkey)->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", (*subkey)->name);
(*subkey)->handle = key->handle;
return ret;
return WERR_OK;;
}
REG_KEY *reg_key_get_subkey_by_name(REG_KEY *key, const char *name)
WERROR reg_key_get_subkey_by_name(REG_KEY *key, const char *name, REG_KEY **subkey)
{
int i, max;
int i;
REG_KEY *ret = NULL;
WERROR error = WERR_OK;
if(!key) return NULL;
if(!key) return WERR_INVALID_PARAM;
if(key->handle->functions->get_subkey_by_name) {
ret = key->handle->functions->get_subkey_by_name(key,name);
error = key->handle->functions->get_subkey_by_name(key,name,subkey);
} else {
max = reg_key_num_subkeys(key);
for(i = 0; i < max; i++) {
REG_KEY *v = reg_key_get_subkey_by_index(key, i);
if(v && !strcmp(v->name, name)) {
ret = v;
for(i = 0; W_ERROR_IS_OK(error); i++) {
error = reg_key_get_subkey_by_index(key, i, subkey);
if(W_ERROR_IS_OK(error) && !strcmp((*subkey)->name, name)) {
break;
}
reg_key_free(v);
reg_key_free(*subkey);
}
}
if(ret && !ret->path) {
ret->path = talloc_asprintf(ret->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name);
ret->handle = key->handle;
}
if(!W_ERROR_IS_OK(error) && W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS))
return error;
ret->path = talloc_asprintf(ret->mem_ctx, "%s%s%s", key->path, key->path[strlen(key->path)-1] == '\\'?"":"\\", ret->name);
ret->handle = key->handle;
*subkey = ret;
return ret;
return WERR_OK;
}
REG_VAL *reg_key_get_value_by_name(REG_KEY *key, const char *name)
WERROR reg_key_get_value_by_name(REG_KEY *key, const char *name, REG_VAL **val)
{
int i, max;
REG_VAL *ret = NULL;
WERROR error = WERR_OK;
if(!key) return NULL;
if(!key) return WERR_INVALID_PARAM;
if(key->handle->functions->get_value_by_name) {
ret = key->handle->functions->get_value_by_name(key,name);
error = key->handle->functions->get_value_by_name(key,name, val);
} else {
max = reg_key_num_values(key);
for(i = 0; i < max; i++) {
REG_VAL *v = reg_key_get_value_by_index(key, i);
if(v && StrCaseCmp(v->name, name)) {
ret = v;
for(i = 0; W_ERROR_IS_OK(error); i++) {
error = reg_key_get_value_by_index(key, i, val);
if(W_ERROR_IS_OK(error) && StrCaseCmp((*val)->name, name)) {
break;
}
reg_val_free(v);
}
}
if(ret) {
ret->parent = key;
ret->handle = key->handle;
}
return ret;
}
BOOL reg_key_del(REG_KEY *key)
{
if(key->handle->functions->del_key) {
if(key->handle->functions->del_key(key)) {
/* Invalidate cache */
key->cache_subkeys = NULL;
key->cache_subkeys_count = 0;
return True;
reg_val_free(*val);
}
}
return False;
if(!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS))
return error;
(*val)->parent = key;
(*val)->handle = key->handle;
return WERR_OK;
}
BOOL reg_sync(REG_HANDLE *h, const char *location)
WERROR reg_key_del(REG_KEY *key)
{
if(!h->functions->sync)
return True;
WERROR error;
if(!key) return WERR_INVALID_PARAM;
if(!key->handle->functions->del_key)
return WERR_NOT_SUPPORTED;
error = key->handle->functions->del_key(key);
if(!W_ERROR_IS_OK(error)) return error;
return h->functions->sync(h, location);
/* Invalidate cache */
key->cache_subkeys = NULL;
key->cache_subkeys_count = 0;
return WERR_OK;
}
BOOL reg_key_del_recursive(REG_KEY *key)
WERROR reg_sync(REG_KEY *h, const char *location)
{
if(!h->handle->functions->sync_key)
return WERR_OK;
return h->handle->functions->sync_key(h, location);
}
WERROR reg_key_del_recursive(REG_KEY *key)
{
BOOL succeed = True;
WERROR error = WERR_OK;
int i;
/* Delete all values for specified key */
for(i = 0; i < reg_key_num_values(key); i++) {
if(!reg_val_del(reg_key_get_value_by_index(key, i)))
succeed = False;
for(i = 0; W_ERROR_IS_OK(error); i++) {
REG_VAL *val;
error = reg_key_get_value_by_index(key, i, &val);
if(!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS))
return error;
if(W_ERROR_IS_OK(error)) {
error = reg_val_del(val);
if(!W_ERROR_IS_OK(error)) return error;
}
}
error = WERR_OK;
/* Delete all keys below this one */
for(i = 0; i < reg_key_num_subkeys(key); i++) {
if(!reg_key_del_recursive(reg_key_get_subkey_by_index(key, i)))
succeed = False;
for(i = 0; W_ERROR_IS_OK(error); i++) {
REG_KEY *subkey;
error = reg_key_get_subkey_by_index(key, i, &subkey);
if(!W_ERROR_IS_OK(error)) return error;
error = reg_key_del_recursive(subkey);
if(!W_ERROR_IS_OK(error)) return error;
}
if(succeed)reg_key_del(key);
return succeed;
return reg_key_del(key);
}
BOOL reg_val_del(REG_VAL *val)
WERROR reg_val_del(REG_VAL *val)
{
WERROR error;
if (!val) return WERR_INVALID_PARAM;
if (!val->handle->functions->del_value) {
DEBUG(1, ("Backend '%s' doesn't support method del_value\n", val->handle->functions->name));
return False;
return WERR_NOT_SUPPORTED;
}
if(val->handle->functions->del_value(val)) {
val->parent->cache_values = NULL;
val->parent->cache_values_count = 0;
return True;
}
return False;
error = val->handle->functions->del_value(val);
if(!W_ERROR_IS_OK(error)) return error;
val->parent->cache_values = NULL;
val->parent->cache_values_count = 0;
return WERR_OK;
}
BOOL reg_key_add_name_recursive(REG_KEY *parent, const char *path)
WERROR reg_key_add_name_recursive(REG_KEY *parent, const char *path)
{
REG_KEY *cur, *prevcur = parent;
WERROR error;
char *begin = (char *)path, *end;
while(1) {
end = strchr(begin, '\\');
if(end) *end = '\0';
cur = reg_key_get_subkey_by_name(prevcur, begin);
if(!cur) {
if(!reg_key_add_name(prevcur, begin)) { printf("foo\n"); return False; }
cur = reg_key_get_subkey_by_name(prevcur, begin);
if(!cur) {
DEBUG(0, ("Can't find key after adding it : %s\n", begin));
return False;
}
error = reg_key_get_subkey_by_name(prevcur, begin, &cur);
/* Key is not there, add it */
if(W_ERROR_EQUAL(error, WERR_DEST_NOT_FOUND)) {
error = reg_key_add_name(prevcur, begin, 0, NULL, &cur);
if(!W_ERROR_IS_OK(error)) return error;
}
if(!W_ERROR_IS_OK(error)) {
if(end) *end = '\\';
return error;
}
if(!end) break;
@ -403,28 +441,36 @@ BOOL reg_key_add_name_recursive(REG_KEY *parent, const char *path)
begin = end+1;
prevcur = cur;
}
return True;
return WERR_OK;
}
BOOL reg_key_add_name(REG_KEY *parent, const char *name)
WERROR reg_key_add_name(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *desc, REG_KEY **newkey)
{
if (!parent) return False;
WERROR error;
if (!parent) return WERR_INVALID_PARAM;
if (!parent->handle->functions->add_key) {
DEBUG(1, ("Backend '%s' doesn't support method add_key\n", parent->handle->functions->name));
return False;
return WERR_NOT_SUPPORTED;
}
if(parent->handle->functions->add_key(parent, name)) {
parent->cache_subkeys = NULL;
parent->cache_subkeys_count = 0;
return True;
}
return False;
error = parent->handle->functions->add_key(parent, name, access_mask, desc, newkey);
if(!W_ERROR_IS_OK(error)) return error;
(*newkey)->handle = parent->handle;
(*newkey)->backend_data = talloc_asprintf((*newkey)->mem_ctx, "%s\\%s", reg_key_get_path(parent), name);
parent->cache_subkeys = NULL;
parent->cache_subkeys_count = 0;
return WERR_OK;
}
BOOL reg_val_update(REG_VAL *val, int type, void *data, int len)
WERROR reg_val_update(REG_VAL *val, int type, void *data, int len)
{
WERROR error;
/* A 'real' update function has preference */
if (val->handle->functions->update_value)
return val->handle->functions->update_value(val, type, data, len);
@ -433,18 +479,19 @@ BOOL reg_val_update(REG_VAL *val, int type, void *data, int len)
if (val->handle->functions->add_value &&
val->handle->functions->del_value) {
REG_VAL *new;
if(!val->handle->functions->del_value(val))
return False;
if(!W_ERROR_IS_OK(error = val->handle->functions->del_value(val)))
return error;
new = val->handle->functions->add_value(val->parent, val->name, type, data, len);
error = val->handle->functions->add_value(val->parent, val->name, type, data, len);
if(!W_ERROR_IS_OK(error)) return error;
memcpy(val, new, sizeof(REG_VAL));
val->parent->cache_values = NULL;
val->parent->cache_values_count = 0;
return True;
return WERR_OK;
}
DEBUG(1, ("Backend '%s' doesn't support method update_value\n", val->handle->functions->name));
return False;
return WERR_NOT_SUPPORTED;
}
void reg_free(REG_HANDLE *h)
@ -454,37 +501,44 @@ void reg_free(REG_HANDLE *h)
h->functions->close_registry(h);
}
REG_KEY *reg_get_root(REG_HANDLE *h)
WERROR reg_get_root(REG_HANDLE *h, REG_KEY **key)
{
REG_KEY *ret = NULL;
WERROR ret;
if(h->functions->open_root_key) {
ret = h->functions->open_root_key(h);
ret = h->functions->open_root_key(h, key);
} else if(h->functions->open_key) {
ret = h->functions->open_key(h, "\\");
ret = h->functions->open_key(h, "\\", key);
} else {
DEBUG(0, ("Backend '%s' has neither open_root_key nor open_key method implemented\n", h->functions->name));
ret = WERR_NOT_SUPPORTED;
}
if(ret) {
ret->handle = h;
ret->path = talloc_strdup(ret->mem_ctx, "\\");
if(W_ERROR_IS_OK(ret)) {
(*key)->handle = h;
(*key)->path = talloc_strdup((*key)->mem_ctx, "\\");
}
return ret;
}
REG_VAL *reg_key_add_value(REG_KEY *key, const char *name, int type, void *value, size_t vallen)
WERROR reg_key_add_value(REG_KEY *key, const char *name, int type, void *value, size_t vallen)
{
REG_VAL *ret;
WERROR ret = WERR_OK;
if(!key->handle->functions->add_value)
return NULL;
return WERR_NOT_SUPPORTED;
ret = key->handle->functions->add_value(key, name, type, value, vallen);
ret->parent = key;
ret->handle = key->handle;
if(!W_ERROR_IS_OK(ret)) return ret;
/* Invalidate the cache */
key->cache_values = NULL;
key->cache_values_count = 0;
return ret;
}
WERROR reg_save(REG_HANDLE *h, const char *location)
{
/* FIXME */
return WERR_NOT_SUPPORTED;
}

View File

@ -96,22 +96,26 @@ BOOL reg_val_set_string(REG_VAL *val, char *str)
return False;
}
REG_VAL *reg_key_get_subkey_val(REG_KEY *key, const char *subname, const char *valname)
WERROR reg_key_get_subkey_val(REG_KEY *key, const char *subname, const char *valname, REG_VAL **val)
{
REG_KEY *k = reg_key_get_subkey_by_name(key, subname);
if(!k) return NULL;
REG_KEY *k;
WERROR error = reg_key_get_subkey_by_name(key, subname, &k);
if(!W_ERROR_IS_OK(error)) return error;
return reg_key_get_value_by_name(k, valname);
return reg_key_get_value_by_name(k, valname, val);
}
BOOL reg_key_set_subkey_val(REG_KEY *key, const char *subname, const char *valname, uint32 type, uint8 *data, int real_len)
WERROR reg_key_set_subkey_val(REG_KEY *key, const char *subname, const char *valname, uint32 type, uint8 *data, int real_len)
{
REG_KEY *k = reg_key_get_subkey_by_name(key, subname);
REG_KEY *k;
REG_VAL *v;
if(!k) return False;
WERROR error;
v = reg_key_get_value_by_name(k, valname);
if(!v) return False;
error = reg_key_get_subkey_by_name(key, subname, &k);
if(!W_ERROR_IS_OK(error)) return error;
error = reg_key_get_value_by_name(k, valname, &v);
if(!W_ERROR_IS_OK(error)) return error;
return reg_val_update(v, type, data, real_len);
}

View File

@ -57,42 +57,55 @@ struct reg_val_s {
int ref;
};
/* FIXME */
typedef void (*key_notification_function) ();
typedef void (*value_notification_function) ();
/*
* Container for function pointers to enumeration routines
* for virtual registry view
*/
struct reg_ops_s {
struct registry_ops {
const char *name;
BOOL (*open_registry) (REG_HANDLE *, const char *location, BOOL try_complete_load);
BOOL (*sync)(REG_HANDLE *, const char *location);
BOOL (*close_registry) (REG_HANDLE *);
WERROR (*open_registry) (REG_HANDLE *, const char *location, const char *credentials);
WERROR (*sync_key)(REG_KEY *, const char *location);
WERROR (*close_registry) (REG_HANDLE *);
/* Either implement these */
REG_KEY *(*open_root_key) (REG_HANDLE *);
int (*num_subkeys) (REG_KEY *);
int (*num_values) (REG_KEY *);
REG_KEY *(*get_subkey_by_index) (REG_KEY *, int idx);
REG_KEY *(*get_subkey_by_name) (REG_KEY *, const char *name);
REG_VAL *(*get_value_by_index) (REG_KEY *, int idx);
REG_VAL *(*get_value_by_name) (REG_KEY *, const char *name);
WERROR (*open_root_key) (REG_HANDLE *, REG_KEY **);
WERROR (*num_subkeys) (REG_KEY *, int *count);
WERROR (*num_values) (REG_KEY *, int *count);
WERROR (*get_subkey_by_index) (REG_KEY *, int idx, REG_KEY **);
WERROR (*get_subkey_by_name) (REG_KEY *, const char *name, REG_KEY **);
WERROR (*get_value_by_index) (REG_KEY *, int idx, REG_VAL **);
WERROR (*get_value_by_name) (REG_KEY *, const char *name, REG_VAL **);
/* Or these */
REG_KEY *(*open_key) (REG_HANDLE *, const char *name);
BOOL (*fetch_subkeys) (REG_KEY *, int *count, REG_KEY ***);
BOOL (*fetch_values) (REG_KEY *, int *count, REG_VAL ***);
WERROR (*open_key) (REG_HANDLE *, const char *name, REG_KEY **);
WERROR (*fetch_subkeys) (REG_KEY *, int *count, REG_KEY ***);
WERROR (*fetch_values) (REG_KEY *, int *count, REG_VAL ***);
/* Security control */
WERROR (*key_get_sec_desc) (REG_KEY *, SEC_DESC **);
WERROR (*key_set_sec_desc) (REG_KEY *, SEC_DESC *);
/* Notification */
WERROR (*request_key_change_notify) (REG_KEY *, key_notification_function);
WERROR (*request_value_change_notify) (REG_VAL *, value_notification_function);
/* Key management */
BOOL (*add_key)(REG_KEY *, const char *name);
BOOL (*del_key)(REG_KEY *);
WERROR (*add_key)(REG_KEY *, const char *name, uint32 access_mask, SEC_DESC *, REG_KEY **);
WERROR (*del_key)(REG_KEY *);
/* Value management */
REG_VAL *(*add_value)(REG_KEY *, const char *name, int type, void *data, int len);
BOOL (*del_value)(REG_VAL *);
WERROR (*add_value)(REG_KEY *, const char *name, int type, void *data, int len);
WERROR (*del_value)(REG_VAL *);
/* If update is not available, value will first be deleted and then added
* again */
BOOL (*update_value)(REG_VAL *, int type, void *data, int len);
WERROR (*update_value)(REG_VAL *, int type, void *data, int len);
void (*free_key_backend_data) (REG_KEY *);
void (*free_val_backend_data) (REG_VAL *);
@ -105,7 +118,7 @@ typedef struct reg_sub_tree_s {
} REG_SUBTREE;
struct reg_handle_s {
REG_OPS *functions;
struct registry_ops *functions;
REG_SUBTREE *subtrees;
char *location;
void *backend_data;
@ -114,7 +127,7 @@ struct reg_handle_s {
struct reg_init_function_entry {
/* Function to create a member of the pdb_methods list */
REG_OPS *functions;
struct registry_ops *functions;
struct reg_init_function_entry *prev, *next;
};

View File

@ -8,9 +8,12 @@ LIBWINREG=libwinregistry
PKG_CHECK_MODULES(GCONF, gconf-2.0, [ SMB_MODULE_DEFAULT(reg_gconf,STATIC)
CFLAGS="$CFLAGS $GCONF_CFLAGS";], [AC_MSG_WARN([GConf not found, not building reg_gconf])])
PKG_CHECK_MODULES(GTK, glib-2.0 gtk+-2.0, [ CFLAGS="$CFLAGS $GTK_CFLAGS"; ], [ AC_MSG_WARN([Will be unable to build gregedit])])
SMB_MODULE(reg_nt4, REG, STATIC, lib/registry/reg_backend_nt4/reg_backend_nt4.o)
SMB_MODULE(reg_dir, REG, STATIC, lib/registry/reg_backend_dir/reg_backend_dir.o)
SMB_MODULE(reg_rpc, REG, STATIC, lib/registry/reg_backend_rpc/reg_backend_rpc.o)
SMB_MODULE(reg_gconf, REG, NOT, lib/registry/reg_backend_gconf/reg_backend_gconf.o, [], [$GCONF_LIBS])
SMB_MODULE(reg_ldb, REG, STATIC, lib/registry/reg_backend_ldb/reg_backend_ldb.o)
SMB_SUBSYSTEM(REG,lib/registry/common/reg_interface.o,[lib/registry/common/reg_objects.o lib/registry/common/reg_util.o],lib/registry/common/winregistry_proto.h,[])
AC_CONFIG_FILES(lib/registry/winregistry.pc)

View File

@ -21,7 +21,7 @@
#include "includes.h"
#include "lib/registry/common/registry.h"
static BOOL reg_dir_add_key(REG_KEY *parent, const char *name)
static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *desc)
{
char *path;
int ret;
@ -29,15 +29,16 @@ static BOOL reg_dir_add_key(REG_KEY *parent, const char *name)
path = reg_path_win2unix(path);
ret = mkdir(path, 0700);
SAFE_FREE(path);
return (ret == 0);
if(ret == 0)return WERR_OK;
return WERR_INVALID_PARAM;
}
static BOOL reg_dir_del_key(REG_KEY *k)
static WERROR reg_dir_del_key(REG_KEY *k)
{
return (rmdir((char *)k->backend_data) == 0);
return (rmdir((char *)k->backend_data) == 0)?WERR_OK:WERR_GENERAL_FAILURE;
}
static REG_KEY *reg_dir_open_key(REG_HANDLE *h, const char *name)
static WERROR reg_dir_open_key(REG_HANDLE *h, const char *name, REG_KEY **subkey)
{
DIR *d;
char *fullpath;
@ -45,7 +46,7 @@ static REG_KEY *reg_dir_open_key(REG_HANDLE *h, const char *name)
TALLOC_CTX *mem_ctx = talloc_init("tmp");
if(!name) {
DEBUG(0, ("NULL pointer passed as directory name!"));
return NULL;
return WERR_INVALID_PARAM;
}
fullpath = talloc_asprintf(mem_ctx, "%s%s", h->location, name);
fullpath = reg_path_win2unix(fullpath);
@ -54,16 +55,17 @@ static REG_KEY *reg_dir_open_key(REG_HANDLE *h, const char *name)
if(!d) {
DEBUG(3,("Unable to open '%s': %s\n", fullpath, strerror(errno)));
talloc_destroy(mem_ctx);
return NULL;
return WERR_BADFILE;
}
closedir(d);
ret = reg_key_new_abs(name, h, fullpath);
talloc_steal(mem_ctx, ret->mem_ctx, fullpath);
talloc_destroy(mem_ctx);
return ret;
*subkey = ret;
return WERR_OK;
}
static BOOL reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r)
static WERROR reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r)
{
struct dirent *e;
int max = 200;
@ -75,7 +77,7 @@ static BOOL reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r)
d = opendir(fullpath);
if(!d) return False;
if(!d) return WERR_INVALID_PARAM;
while((e = readdir(d))) {
if(e->d_type == DT_DIR &&
@ -96,35 +98,35 @@ static BOOL reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r)
closedir(d);
*r = ar;
return True;
return WERR_OK;
}
static BOOL reg_dir_open(REG_HANDLE *h, const char *loc, BOOL try) {
if(!loc) return False;
return True;
static WERROR reg_dir_open(REG_HANDLE *h, const char *loc, const char *credentials) {
if(!loc) return WERR_INVALID_PARAM;
return WERR_OK;
}
static REG_VAL *reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len)
static WERROR reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len, REG_VAL **value)
{
REG_VAL *ret = reg_val_new(p, NULL);
char *fullpath;
FILE *fd;
ret->name = name?talloc_strdup(ret->mem_ctx, name):NULL;
fullpath = reg_path_win2unix(strdup(reg_val_get_path(ret)));
*value = reg_val_new(p, NULL);
(*value)->name = name?talloc_strdup((*value)->mem_ctx, name):NULL;
fullpath = reg_path_win2unix(strdup(reg_val_get_path(*value)));
fd = fopen(fullpath, "w+");
/* FIXME */
return NULL;
return WERR_NOT_SUPPORTED;
}
static BOOL reg_dir_del_value(REG_VAL *v)
static WERROR reg_dir_del_value(REG_VAL *v)
{
/* FIXME*/
return False;
return WERR_NOT_SUPPORTED;
}
static REG_OPS reg_backend_dir = {
static struct registry_ops reg_backend_dir = {
.name = "dir",
.open_registry = reg_dir_open,
.open_key = reg_dir_open_key,

View File

@ -22,18 +22,26 @@
#include "lib/registry/common/registry.h"
#include <gconf/gconf-client.h>
static BOOL reg_open_gconf(REG_HANDLE *h, const char *location, BOOL try_complete_load)
static WERROR gerror_to_werror(GError *error)
{
if(error == NULL) return WERR_OK;
/* FIXME */
return WERR_FOOBAR;
}
static WERROR reg_open_gconf(REG_HANDLE *h, const char *location, const char *credentials)
{
h->backend_data = (void *)gconf_client_get_default();
return True;
if(!h->backend_data) return WERR_FOOBAR;
return WERR_OK;
}
static BOOL reg_close_gconf(REG_HANDLE *h)
static WERROR reg_close_gconf(REG_HANDLE *h)
{
return True;
return WERR_OK;
}
static REG_KEY *gconf_open_key (REG_HANDLE *h, const char *name)
static WERROR gconf_open_key (REG_HANDLE *h, const char *name, REG_KEY **key)
{
REG_KEY *ret;
char *fullpath = reg_path_win2unix(strdup(name));
@ -41,16 +49,17 @@ static REG_KEY *gconf_open_key (REG_HANDLE *h, const char *name)
/* Check if key exists */
if(!gconf_client_dir_exists((GConfClient *)h->backend_data, fullpath, NULL)) {
SAFE_FREE(fullpath);
return NULL;
return WERR_DEST_NOT_FOUND;
}
ret = reg_key_new_abs(name, h, NULL);
ret->backend_data = talloc_strdup(ret->mem_ctx, fullpath);
SAFE_FREE(fullpath);
return ret;
*key = ret;
return WERR_OK;
}
static BOOL gconf_fetch_values(REG_KEY *p, int *count, REG_VAL ***vals)
static WERROR gconf_fetch_values(REG_KEY *p, int *count, REG_VAL ***vals)
{
GSList *entries;
GSList *cur;
@ -113,22 +122,24 @@ static BOOL gconf_fetch_values(REG_KEY *p, int *count, REG_VAL ***vals)
g_slist_free(entries);
*vals = ar;
return True;
return WERR_OK;
}
static BOOL gconf_fetch_subkeys(REG_KEY *p, int *count, REG_KEY ***subs)
static WERROR gconf_fetch_subkeys(REG_KEY *p, int *count, REG_KEY ***subs)
{
GSList *dirs;
GSList *cur;
REG_KEY **ar = malloc(sizeof(REG_KEY *));
REG_KEY **ar = talloc_array_p(p->mem_ctx, REG_KEY *, 1);
char *fullpath = p->backend_data;
cur = dirs = gconf_client_all_dirs((GConfClient*)p->handle->backend_data, fullpath,NULL);
(*count) = 0;
while(cur) {
ar[(*count)] = reg_key_new_abs(reg_path_unix2win((char *)cur->data), p->handle,NULL);
ar[(*count)]->backend_data = talloc_strdup(ar[*count]->mem_ctx, cur->data);
ar = realloc(ar, sizeof(REG_KEY *) * ((*count)+2));
char *winpath = reg_path_unix2win(strdup((char *)cur->data));
ar[(*count)] = reg_key_new_abs(winpath, p->handle,NULL);
free(winpath);
ar[(*count)]->backend_data = reg_path_win2unix(talloc_strdup(ar[*count]->mem_ctx, cur->data));
ar = talloc_realloc_p(p->mem_ctx, ar, REG_KEY *, (*count)+2);
(*count)++;
g_free(cur->data);
cur = cur->next;
@ -136,10 +147,10 @@ static BOOL gconf_fetch_subkeys(REG_KEY *p, int *count, REG_KEY ***subs)
g_slist_free(dirs);
*subs = ar;
return True;
return WERR_OK;
}
static BOOL gconf_update_value(REG_VAL *val, int type, void *data, int len)
static WERROR gconf_update_value(REG_VAL *val, int type, void *data, int len)
{
GError *error = NULL;
char *keypath = val->backend_data;
@ -152,22 +163,23 @@ static BOOL gconf_update_value(REG_VAL *val, int type, void *data, int len)
case REG_EXPAND_SZ:
gconf_client_set_string((GConfClient *)val->handle->backend_data, valpath, data, &error);
free(valpath);
return (error == NULL);
return gerror_to_werror(error);
case REG_DWORD:
gconf_client_set_int((GConfClient *)val->handle->backend_data, valpath,
*((int *)data), &error);
free(valpath);
return (error == NULL);
return gerror_to_werror(error);
default:
DEBUG(0, ("Unsupported type: %d\n", type));
free(valpath);
return False;
return WERR_NOT_SUPPORTED;
}
return False;
return WERR_NOT_SUPPORTED;
}
static REG_OPS reg_backend_gconf = {
static struct registry_ops reg_backend_gconf = {
.name = "gconf",
.open_registry = reg_open_gconf,
.close_registry = reg_close_gconf,

View File

@ -20,51 +20,96 @@
#include "includes.h"
#include "lib/registry/common/registry.h"
#include "lib/ldb/include/ldb.h"
char *reg_path_to_ldb(TALLOC_CTX *mem_ctx, const char *path)
{
char *ret = talloc_strdup(mem_ctx, "(dn=");
char *begin = (char *)path;
char *end = NULL;
while(begin) {
end = strchr(begin, '\\');
if(end)end = '\0';
if(end - begin != 0) ret = talloc_asprintf_append(mem_ctx, ret, "key=%s,", begin);
if(end) {
*end = '\\';
begin = end+1;
} else begin = NULL;
}
ret[strlen(ret)-1] = ')';
return ret;
}
/*
* Saves the dn as private_data for every key/val
*/
static BOOL ldb_open_registry(REG_HANDLE *handle, const char *location, BOOL try_full_load)
static WERROR ldb_open_registry(REG_HANDLE *handle, const char *location, const char *credentials)
{
struct ldb_context *c;
c = ldb_connect(location, 0, NULL);
if(!c) return False;
if(!c) return WERR_FOOBAR;
handle->backend_data = c;
return True;
return WERR_OK;
}
static BOOL ldb_close_registry(REG_HANDLE *h)
static WERROR ldb_close_registry(REG_HANDLE *h)
{
ldb_close(h);
return True;
ldb_close((struct ldb_context *)h->backend_data);
return WERR_OK;
}
static BOOL ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys)
static WERROR ldb_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***subkeys)
{
ldb_search();
struct ldb_context *c = k->handle->backend_data;
char *path;
struct ldb_message **msg;
char *ldap_path;
TALLOC_CTX *mem_ctx = talloc_init("ldb_path");
REG_KEY *key = NULL;
ldap_path = reg_path_to_ldb(mem_ctx, reg_key_get_path(k));
if(ldb_search(c, NULL, LDB_SCOPE_ONELEVEL, ldap_path, NULL,&msg) > 0) {
key = reg_key_new_abs(reg_key_get_path(k), k->handle, ldap_path);
talloc_steal(mem_ctx, key->mem_ctx, ldap_path);
/* FIXME */
}
ldap_search_free(c, msg);
talloc_destroy(mem_ctx);
return WERR_OK;
}
static REG_KEY *ldb_open_key(REG_HANDLE *h, const char *name)
static WERROR ldb_open_key(REG_HANDLE *h, const char *name, REG_KEY **key)
{
struct ldb_context *c = h->backend_data;
char *path;
struct ldb_message **msg;
REG_KEY *key = NULL;
(dn=key=Systems,
if(ldb_search(c, NULL, LDP_SCOPE_BASE, "", NULL,&msg) > 0) {
key = reg_key_new_abs(name, h, base);
char *ldap_path;
TALLOC_CTX *mem_ctx = talloc_init("ldb_path");
ldap_path = reg_path_to_ldb(mem_ctx, name);
if(ldb_search(c, NULL, LDB_SCOPE_BASE, ldap_path, NULL,&msg) > 0) {
*key = reg_key_new_abs(name, h, ldap_path);
talloc_steal(mem_ctx, (*key)->mem_ctx, ldap_path);
/* FIXME */
}
ldap_search_free(c, msg);
talloc_destroy(mem_ctx);
return key;
return WERR_OK;;
}
static REG_OPS reg_backend_ldb = {
static struct registry_ops reg_backend_ldb = {
.name = "ldb",
.open_registry = ldb_open_registry,
.close_registry = ldb_close_registry,

View File

@ -881,7 +881,7 @@ static KEY_SEC_DESC *process_sk(REG_HANDLE *regf, SK_HDR *sk_hdr, int sk_off, in
/*
* Process a VK header and return a value
*/
static REG_VAL *vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size)
static WERROR vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size, REG_VAL **value)
{
char val_name[1024];
REGF *regf = parent->handle->backend_data;
@ -889,12 +889,12 @@ static REG_VAL *vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size)
const char *val_type;
REG_VAL *tmp = NULL;
if (!vk_hdr) return NULL;
if (!vk_hdr) return WERR_INVALID_PARAM;
if ((vk_id = SVAL(&vk_hdr->VK_ID,0)) != str_to_dword("vk")) {
DEBUG(0, ("Unrecognized VK header ID: %0X, block: %0X, %s\n",
vk_id, (int)vk_hdr, parent->handle->location));
return NULL;
return WERR_GENERAL_FAILURE;
}
nam_len = SVAL(&vk_hdr->nam_len,0);
@ -943,7 +943,8 @@ static REG_VAL *vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size)
tmp->data_len = dat_len;
}
return tmp;
*value = tmp;
return WERR_OK;
}
static BOOL vl_verify(VL_TYPE vl, int count, int size)
@ -956,63 +957,67 @@ static BOOL vl_verify(VL_TYPE vl, int count, int size)
return True;
}
static BOOL lf_verify(REG_HANDLE *h, LF_HDR *lf_hdr, int size)
static WERROR lf_verify(REG_HANDLE *h, LF_HDR *lf_hdr, int size)
{
int lf_id;
if ((lf_id = SVAL(&lf_hdr->LF_ID,0)) != str_to_dword("lf")) {
DEBUG(0, ("Unrecognized LF Header format: %0X, Block: %0X, %s.\n",
lf_id, (int)lf_hdr, h->location));
return False;
return WERR_INVALID_PARAM;
}
return True;
return WERR_OK;
}
static int lf_num_entries(REG_HANDLE *h, LF_HDR *lf_hdr, int size)
static WERROR lf_num_entries(REG_HANDLE *h, LF_HDR *lf_hdr, int size, int *count)
{
int count;
WERROR error;
if(!lf_verify(h, lf_hdr, size)) return 0;
error = lf_verify(h, lf_hdr, size);
if(!W_ERROR_IS_OK(error)) return error;
SMB_REG_ASSERT(size < 0);
count = SVAL(&lf_hdr->key_count,0);
DEBUG(2, ("Key Count: %u\n", count));
if (count <= 0) return 0;
*count = SVAL(&lf_hdr->key_count,0);
DEBUG(2, ("Key Count: %u\n", *count));
if (*count <= 0) return WERR_INVALID_PARAM;
return count;
return WERR_OK;
}
static REG_KEY *nk_to_key(REG_HANDLE *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent);
static WERROR nk_to_key(REG_HANDLE *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent, REG_KEY **);
/*
* Process an LF Header and return a list of sub-keys
*/
static REG_KEY *lf_get_entry(REG_KEY *parent, LF_HDR *lf_hdr, int size, int n)
static WERROR lf_get_entry(REG_KEY *parent, LF_HDR *lf_hdr, int size, int n, REG_KEY **key)
{
REGF *regf = parent->handle->backend_data;
int count, nk_off;
NK_HDR *nk_hdr;
WERROR error;
if (!lf_hdr) return NULL;
if (!lf_hdr) return WERR_INVALID_PARAM;
if(!lf_verify(parent->handle, lf_hdr, size)) return NULL;
error = lf_verify(parent->handle, lf_hdr, size);
if(!W_ERROR_IS_OK(error)) return error;
SMB_REG_ASSERT(size < 0);
count = SVAL(&lf_hdr->key_count,0);
DEBUG(2, ("Key Count: %u\n", count));
if (count <= 0 || n > count) return NULL;
if (count <= 0) return WERR_GENERAL_FAILURE;
if (n >= count) return WERR_NO_MORE_ITEMS;
nk_off = IVAL(&lf_hdr->hr[n].nk_off,0);
DEBUG(2, ("NK Offset: %0X\n", nk_off));
nk_hdr = (NK_HDR *)LOCN(regf->base, nk_off);
return nk_to_key(parent->handle, nk_hdr, BLK_SIZE(nk_hdr), parent);
return nk_to_key(parent->handle, nk_hdr, BLK_SIZE(nk_hdr), parent, key);
}
static REG_KEY *nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent)
static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent, REG_KEY **key)
{
REGF *regf = h->backend_data;
REG_KEY *tmp = NULL, *own;
@ -1022,12 +1027,12 @@ static REG_KEY *nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *pare
int type;
char key_name[1024], cls_name[1024];
if (!nk_hdr) return NULL;
if (!nk_hdr) return WERR_INVALID_PARAM;
if ((nk_id = SVAL(&nk_hdr->NK_ID,0)) != str_to_dword("nk")) {
DEBUG(0, ("Unrecognized NK Header format: %08X, Block: %0X. %s\n",
nk_id, (int)nk_hdr, parent->handle->location));
return NULL;
return WERR_INVALID_PARAM;
}
SMB_REG_ASSERT(size < 0);
@ -1047,7 +1052,7 @@ static REG_KEY *nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *pare
DEBUG(0, ("Incorrect NK_HDR size: %d, %0X\n", -size, (int)nk_hdr));
DEBUG(0, ("Sizeof NK_HDR: %d, name_len %d, clsname_len %d\n",
sizeof(NK_HDR), name_len, clsname_len));
/*return NULL;*/
return WERR_GENERAL_FAILURE;
}
DEBUG(2, ("NK HDR: Name len: %d, class name len: %d\n", name_len, clsname_len));
@ -1062,7 +1067,7 @@ static REG_KEY *nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *pare
type = (SVAL(&nk_hdr->type,0)==0x2C?REG_ROOT_KEY:REG_SUB_KEY);
if(type == REG_ROOT_KEY && parent) {
DEBUG(0,("Root key encountered below root level!\n"));
return NULL;
return WERR_GENERAL_FAILURE;
}
if(type == REG_ROOT_KEY) tmp = reg_key_new_abs(key_name, h, nk_hdr);
@ -1121,7 +1126,8 @@ static REG_KEY *nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *pare
}
return tmp;
*key = tmp;
return WERR_OK;
}
/*
@ -1559,7 +1565,7 @@ error:
return NULL;
}
static BOOL nt_close_registry (REG_HANDLE *h)
static WERROR nt_close_registry (REG_HANDLE *h)
{
REGF *regf = h->backend_data;
if (regf->base) munmap(regf->base, regf->sbuf.st_size);
@ -1570,10 +1576,10 @@ static BOOL nt_close_registry (REG_HANDLE *h)
regf->sk_count = regf->sk_map_size = 0;
free(regf);
return False;
return WERR_OK;
}
static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load)
static WERROR nt_open_registry (REG_HANDLE *h, const char *location, const char *credentials)
{
REGF *regf = (REGF *)malloc(sizeof(REGF));
REGF_HDR *regf_hdr;
@ -1582,7 +1588,7 @@ static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load
memset(regf, 0, sizeof(REGF));
regf->mem_ctx = talloc_init("regf");
regf->owner_sid_str = def_owner_sid_str;
regf->owner_sid_str = credentials;
h->backend_data = regf;
DEBUG(5, ("Attempting to load registry file\n"));
@ -1591,7 +1597,7 @@ static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load
if ((regf_hdr = nt_get_regf_hdr(h)) == NULL) {
DEBUG(0, ("Unable to get header\n"));
return False;
return WERR_GENERAL_FAILURE;
}
/* Now process that header and start to read the rest in */
@ -1599,7 +1605,7 @@ static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load
if ((regf_id = IVAL(&regf_hdr->REGF_ID,0)) != str_to_dword("regf")) {
DEBUG(0, ("Unrecognized NT registry header id: %0X, %s\n",
regf_id, h->location));
return False;
return WERR_GENERAL_FAILURE;
}
/*
@ -1608,7 +1614,7 @@ static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load
if (!valid_regf_hdr(regf_hdr)) {
DEBUG(0, ("Registry file header does not validate: %s\n",
h->location));
return False;
return WERR_GENERAL_FAILURE;
}
/* Update the last mod date, and then go get the first NK record and on */
@ -1625,7 +1631,7 @@ static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load
if ((hbin_id = IVAL(&hbin_hdr->HBIN_ID,0)) != str_to_dword("hbin")) {
DEBUG(0, ("Unrecognized registry hbin hdr ID: %0X, %s\n",
hbin_id, h->location));
return False;
return WERR_GENERAL_FAILURE;
}
/*
@ -1655,15 +1661,15 @@ static BOOL nt_open_registry (REG_HANDLE *h, const char *location, BOOL try_load
h->backend_data = regf;
return True;
return WERR_OK;
}
static REG_KEY *nt_get_root_key(REG_HANDLE *h)
static WERROR nt_get_root_key(REG_HANDLE *h, REG_KEY **key)
{
return nk_to_key(h, ((REGF *)h->backend_data)->first_key, BLK_SIZE(((REGF *)h->backend_data)->first_key), NULL);
return nk_to_key(h, ((REGF *)h->backend_data)->first_key, BLK_SIZE(((REGF *)h->backend_data)->first_key), NULL, key);
}
static int nt_num_subkeys(REG_KEY *k)
static WERROR nt_num_subkeys(REG_KEY *k, int *num)
{
REGF *regf = k->handle->backend_data;
LF_HDR *lf_hdr;
@ -1671,19 +1677,23 @@ static int nt_num_subkeys(REG_KEY *k)
NK_HDR *nk_hdr = k->backend_data;
lf_off = IVAL(&nk_hdr->lf_off,0);
DEBUG(2, ("SubKey list offset: %0X\n", lf_off));
if(lf_off == -1) return 0;
if(lf_off == -1) {
*num = 0;
return WERR_OK;
}
lf_hdr = (LF_HDR *)LOCN(regf->base, lf_off);
return lf_num_entries(k->handle, lf_hdr, BLK_SIZE(lf_hdr));
return lf_num_entries(k->handle, lf_hdr, BLK_SIZE(lf_hdr), num);
}
static int nt_num_values(REG_KEY *k)
static WERROR nt_num_values(REG_KEY *k, int *count)
{
NK_HDR *nk_hdr = k->backend_data;
return IVAL(&nk_hdr->val_cnt,0);
*count = IVAL(&nk_hdr->val_cnt,0);
return WERR_OK;
}
static REG_VAL *nt_value_by_index(REG_KEY *k, int n)
static WERROR nt_value_by_index(REG_KEY *k, int n, REG_VAL **value)
{
VL_TYPE *vl;
int val_off, vk_off;
@ -1696,10 +1706,10 @@ static REG_VAL *nt_value_by_index(REG_KEY *k, int n)
vk_off = IVAL(&vl[n],0);
vk_hdr = (VK_HDR *)LOCN(regf->base, vk_off);
return vk_to_val(k, vk_hdr, BLK_SIZE(vk_hdr));
return vk_to_val(k, vk_hdr, BLK_SIZE(vk_hdr), value);
}
static REG_KEY *nt_key_by_index(REG_KEY *k, int n)
static WERROR nt_key_by_index(REG_KEY *k, int n, REG_KEY **subkey)
{
REGF *regf = k->handle->backend_data;
int lf_off;
@ -1714,13 +1724,13 @@ static REG_KEY *nt_key_by_index(REG_KEY *k, int n)
if (lf_off != -1) {
lf_hdr = (LF_HDR *)LOCN(regf->base, lf_off);
return lf_get_entry(k, lf_hdr, BLK_SIZE(lf_hdr), n);
return lf_get_entry(k, lf_hdr, BLK_SIZE(lf_hdr), n, subkey);
}
return NULL;
return WERR_NO_MORE_ITEMS;
}
static REG_OPS reg_backend_nt4 = {
static struct registry_ops reg_backend_nt4 = {
.name = "nt4",
.open_registry = nt_open_registry,
.close_registry = nt_close_registry,

View File

@ -77,12 +77,18 @@ struct {
{ NULL, NULL }
};
static BOOL rpc_open_registry(REG_HANDLE *h, const char *location, BOOL try_full)
static WERROR rpc_open_registry(REG_HANDLE *h, const char *location, const char *credentials)
{
BOOL res = True;
struct rpc_data *mydata = talloc(h->mem_ctx, sizeof(struct rpc_data));
char *binding = strdup(location);
NTSTATUS status;
char *user, *pass;
if(!credentials || !location) return WERR_INVALID_PARAM;
user = talloc_strdup(h->mem_ctx, credentials);
pass = strchr(user, '%');
*pass = '\0'; pass++;
ZERO_STRUCTP(mydata);
@ -90,26 +96,26 @@ static BOOL rpc_open_registry(REG_HANDLE *h, const char *location, BOOL try_full
DCERPC_WINREG_UUID,
DCERPC_WINREG_VERSION,
lp_workgroup(),
"tridge", "samba");
user, pass);
if(!NT_STATUS_IS_OK(status)) return False;
h->backend_data = mydata;
return True;
return ntstatus_to_werror(status);
}
static REG_KEY *rpc_open_root(REG_HANDLE *h)
static WERROR rpc_open_root(REG_HANDLE *h, REG_KEY **k)
{
/* There's not really a 'root' key here */
return reg_key_new_abs("\\", h, h->backend_data);
*k = reg_key_new_abs("\\", h, h->backend_data);
return WERR_OK;
}
static BOOL rpc_close_registry(REG_HANDLE *h)
static WERROR rpc_close_registry(REG_HANDLE *h)
{
dcerpc_pipe_close(((struct rpc_data *)h->backend_data)->pipe);
free(h->backend_data);
return True;
return WERR_OK;
}
static struct policy_handle *rpc_get_key_handle(REG_HANDLE *h, const char *path)
@ -161,12 +167,15 @@ static struct policy_handle *rpc_get_key_handle(REG_HANDLE *h, const char *path)
return key_handle;
}
static REG_KEY *rpc_open_key(REG_HANDLE *h, const char *name)
static WERROR rpc_open_key(REG_HANDLE *h, const char *name, REG_KEY **key)
{
return reg_key_new_abs(name, h, rpc_get_key_handle(h, name));
struct policy_handle *pol = rpc_get_key_handle(h, name);
if(!pol) return WERR_DEST_NOT_FOUND;
*key = reg_key_new_abs(name, h, pol);
return WERR_OK;
}
static BOOL rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys)
static WERROR rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys)
{
struct winreg_EnumKey r;
struct winreg_EnumKeyNameRequest keyname;
@ -188,12 +197,12 @@ static BOOL rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys)
*subkeys = ar;
return True;
return WERR_OK;
}
if(!parent->backend_data) parent->backend_data = rpc_get_key_handle(parent->handle, reg_key_get_path(parent));
if(!parent->backend_data) return False;
if(!parent->backend_data) return WERR_GENERAL_FAILURE;
(*count) = 0;
r.in.handle = parent->backend_data;
@ -219,10 +228,10 @@ static BOOL rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys)
}
*subkeys = ar;
return True;
return r.out.result;
}
static BOOL rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values)
static WERROR rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values)
{
struct winreg_EnumValue r;
struct winreg_Uint8buf value;
@ -238,12 +247,12 @@ static BOOL rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values)
/* Root */
if(parent->backend_data == parent->handle->backend_data) {
*values = ar;
return True;
return WERR_OK;
}
if(!parent->backend_data) parent->backend_data = rpc_get_key_handle(parent->handle, reg_key_get_path(parent));
if(!parent->backend_data) return False;
if(!parent->backend_data) return WERR_GENERAL_FAILURE;
r.in.handle = parent->backend_data;
r.in.enum_index = 0;
@ -283,22 +292,48 @@ static BOOL rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values)
*values = ar;
return True;
return r.out.result;
}
static BOOL rpc_add_key(REG_KEY *parent, const char *name)
static WERROR rpc_add_key(REG_KEY *parent, const char *name)
{
/* FIXME */
return False;
return WERR_NOT_SUPPORTED;
}
static BOOL rpc_del_key(REG_KEY *k)
static struct policy_handle*get_hive(REG_KEY *k)
{
/* FIXME */
return False;
int i;
struct rpc_data *mydata = k->handle->backend_data;
for(i = 0; known_hives[i].name; i++) {
if(!strncmp(known_hives[i].name, reg_key_get_path(k)+1, strlen(known_hives[i].name)))
return mydata->hives[i];
}
return NULL;
}
static REG_OPS reg_backend_rpc = {
static WERROR rpc_del_key(REG_KEY *k)
{
NTSTATUS status;
struct rpc_data *mydata = k->handle->backend_data;
struct winreg_DeleteKey r;
char *hivepath;
struct policy_handle *hive = get_hive(k);
printf("first: %s\n", reg_key_get_path(k));
hivepath = strchr(reg_key_get_path(k), '\\');
hivepath = strchr(hivepath+1, '\\');
printf("asfter: %s\n", hivepath+1);
r.in.handle = hive;
init_winreg_String(&r.in.key, hivepath+1);
status = dcerpc_winreg_DeleteKey(mydata->pipe, k->mem_ctx, &r);
return r.out.result;
}
static struct registry_ops reg_backend_rpc = {
.name = "rpc",
.open_registry = rpc_open_registry,
.close_registry = rpc_close_registry,

View File

@ -20,6 +20,7 @@
#include "includes.h"
#include "lib/registry/common/registry.h"
#include "windows/registry.h"
static REG_OPS reg_backend_wine = {
.name = "wine",

View File

@ -0,0 +1,758 @@
/*
Unix SMB/CIFS implementation.
Gtk registry frontend
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.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include "includes.h"
GtkWidget *openfilewin;
GtkWidget *savefilewin;
GtkTreeStore *store_keys;
GtkListStore *store_vals;
GtkWidget *tree_keys;
GtkWidget *aboutwin;
GtkWidget *mainwin;
GtkWidget *rpcwin;
GtkWidget *rpcwin_host;
GtkWidget *rpcwin_user;
GtkWidget *rpcwin_password;
GtkWidget *save;
GtkWidget *save_as;
GtkWidget* create_openfilewin (void);
GtkWidget* create_savefilewin (void);
static GtkWidget* create_aboutwin (void);
REG_HANDLE *registry = NULL;
static void gtk_show_werror(WERROR err)
{
GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(mainwin),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Registry error: %s\n", win_errstr(err));
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
}
static void treeview_add_val(REG_VAL *val)
{
GtkTreeIter iter;
gtk_list_store_append(store_vals, &iter);
gtk_list_store_set (store_vals,
&iter,
0,
reg_val_name(val),
1,
str_regtype(reg_val_type(val)),
2,
reg_val_data_string(val),
3,
val,
-1);
}
static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath *arg2)
{
GtkTreeIter iter, tmpiter;
REG_KEY *k, *sub;
char *name;
GValue value;
WERROR error;
int i;
/* See if this row has ever had a name gtk_tree_store_set()'ed to it.
If not, read the directory contents */
gtk_tree_model_get(GTK_TREE_MODEL(store_keys), parent,
0, &name, -1);
if(!name) return;
gtk_tree_model_get(GTK_TREE_MODEL(store_keys), parent, 1, &k, -1);
g_assert(k);
for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(k, i, &sub)); i++) {
/* Replace the blank child with the first directory entry
You may be tempted to remove the blank child node and then
append a new one. Don't. If you remove the blank child
node GTK gets confused and won't expand the parent row. */
if(i == 0) {
gtk_tree_model_iter_children(GTK_TREE_MODEL(store_keys),
&iter, parent);
} else {
gtk_tree_store_append(store_keys, &iter, parent);
}
gtk_tree_store_set (store_keys,
&iter,
0,
reg_key_name(sub),
1,
sub,
-1);
gtk_tree_store_append(store_keys, &tmpiter, &iter);
}
/* Remove placeholder child */
if(i == 0) {
gtk_tree_model_iter_children(GTK_TREE_MODEL(store_keys),
&iter, parent);
gtk_tree_store_remove(store_keys, &iter);
}
if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) gtk_show_werror(error);
}
static void registry_load_root()
{
REG_KEY *root;
GtkTreeIter iter, tmpiter;
WERROR error;
if(!registry) return;
error = reg_get_root(registry, &root);
if(!W_ERROR_IS_OK(error)) {
gtk_show_werror(error);
return;
}
gtk_tree_store_clear(store_keys);
/* Add the root */
gtk_tree_store_append(store_keys, &iter, NULL);
gtk_tree_store_set (store_keys,
&iter,
0,
reg_key_name(root),
1,
root,
-1);
gtk_tree_store_append(store_keys, &tmpiter, &iter);
gtk_widget_set_sensitive( save, True );
gtk_widget_set_sensitive( save_as, True );
}
GtkWidget* create_rpcwin (void)
{
GtkWidget *dialog_vbox1;
GtkWidget *table1;
GtkWidget *label1;
GtkWidget *label2;
GtkWidget *label3;
GtkWidget *dialog_action_area1;
GtkWidget *cancelbutton1;
GtkWidget *okbutton1;
rpcwin = gtk_dialog_new ();
gtk_window_set_title (GTK_WINDOW (rpcwin), "Connect to remote server");
dialog_vbox1 = GTK_DIALOG (rpcwin)->vbox;
gtk_widget_show (dialog_vbox1);
table1 = gtk_table_new (3, 2, FALSE);
gtk_widget_show (table1);
gtk_box_pack_start (GTK_BOX (dialog_vbox1), table1, TRUE, TRUE, 0);
label1 = gtk_label_new ("Host:");
gtk_widget_show (label1);
gtk_table_attach (GTK_TABLE (table1), label1, 0, 1, 0, 1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
gtk_misc_set_alignment (GTK_MISC (label1), 0, 0.5);
label2 = gtk_label_new ("User:");
gtk_widget_show (label2);
gtk_table_attach (GTK_TABLE (table1), label2, 0, 1, 1, 2,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
gtk_misc_set_alignment (GTK_MISC (label2), 0, 0.5);
label3 = gtk_label_new ("Password:");
gtk_widget_show (label3);
gtk_table_attach (GTK_TABLE (table1), label3, 0, 1, 2, 3,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
gtk_misc_set_alignment (GTK_MISC (label3), 0, 0.5);
rpcwin_host = gtk_entry_new ();
gtk_widget_show (rpcwin_host);
gtk_table_attach (GTK_TABLE (table1), rpcwin_host, 1, 2, 0, 1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
rpcwin_user = gtk_entry_new ();
gtk_widget_show (rpcwin_user);
gtk_table_attach (GTK_TABLE (table1), rpcwin_user, 1, 2, 1, 2,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
rpcwin_password = gtk_entry_new ();
gtk_widget_show (rpcwin_password);
gtk_table_attach (GTK_TABLE (table1), rpcwin_password, 1, 2, 2, 3,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
gtk_entry_set_visibility (GTK_ENTRY (rpcwin_password), FALSE);
dialog_action_area1 = GTK_DIALOG (rpcwin)->action_area;
gtk_widget_show (dialog_action_area1);
gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);
cancelbutton1 = gtk_button_new_from_stock ("gtk-cancel");
gtk_widget_show (cancelbutton1);
gtk_dialog_add_action_widget (GTK_DIALOG (rpcwin), cancelbutton1, GTK_RESPONSE_CANCEL);
GTK_WIDGET_SET_FLAGS (cancelbutton1, GTK_CAN_DEFAULT);
okbutton1 = gtk_button_new_from_stock ("gtk-ok");
gtk_widget_show (okbutton1);
gtk_dialog_add_action_widget (GTK_DIALOG (rpcwin), okbutton1, GTK_RESPONSE_OK);
GTK_WIDGET_SET_FLAGS (okbutton1, GTK_CAN_DEFAULT);
return rpcwin;
}
static void on_open_nt4_activate (GtkMenuItem *menuitem, gpointer user_data)
{
gint result = gtk_dialog_run(GTK_DIALOG(create_openfilewin()));
char *filename;
WERROR error;
switch(result) {
case GTK_RESPONSE_OK:
filename = strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(openfilewin)));
error = reg_open("nt4", filename, NULL, &registry);
if(!W_ERROR_IS_OK(error)) {
gtk_show_werror(error);
return;
}
registry_load_root();
break;
default:
break;
}
gtk_widget_destroy(openfilewin);
}
void on_open_gconf_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
WERROR error = reg_open("gconf", NULL, NULL, &registry);
if(!W_ERROR_IS_OK(error)) {
gtk_show_werror(error);
return;
}
registry_load_root();
}
void
on_open_remote_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
char *location, *credentials;
gint result = gtk_dialog_run(GTK_DIALOG(create_rpcwin()));
WERROR error;
switch(result) {
case GTK_RESPONSE_OK:
asprintf(&location, "ncacn_np:%s", gtk_entry_get_text(GTK_ENTRY(rpcwin_host)));
asprintf(&credentials, "%s%%%s", gtk_entry_get_text(GTK_ENTRY(rpcwin_user)), gtk_entry_get_text(GTK_ENTRY(rpcwin_password)));
error = reg_open("rpc", location, credentials, &registry);
if(!W_ERROR_IS_OK(error)) {
gtk_show_werror(error);
return;
}
free(location); free(credentials);
registry_load_root();
break;
default:
break;
}
gtk_widget_destroy(rpcwin);
}
void
on_save_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
WERROR error = reg_save(registry, NULL);
if(!W_ERROR_IS_OK(error)) {
gtk_show_werror(error);
}
}
void
on_save_as_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
gint result;
WERROR error;
create_savefilewin();
result = gtk_dialog_run(GTK_DIALOG(savefilewin));
switch(result) {
case GTK_RESPONSE_OK:
error = reg_save(registry, gtk_file_selection_get_filename(GTK_FILE_SELECTION(savefilewin)));
if(!W_ERROR_IS_OK(error)) {
gtk_show_werror(error);
}
break;
default:
break;
}
gtk_widget_destroy(savefilewin);
}
void
on_quit_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
gtk_main_quit();
}
void
on_cut_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
/* FIXME */
}
void
on_copy_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
/* FIXME */
}
void
on_paste_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
/* FIXME */
}
void
on_delete_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
/* FIXME */
}
void
on_about_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
gtk_dialog_run(GTK_DIALOG(create_aboutwin()));
gtk_widget_destroy(aboutwin);
}
void on_key_activate (GtkTreeView *treeview,
GtkTreePath *path,
gpointer user_data)
{
int i;
REG_KEY *k;
REG_VAL *val;
WERROR error;
//FIXME gtk_tree_model_get(GTK_TREE_MODEL(store_keys), iter, 1, &k, -1);
gtk_list_store_clear(store_vals);
for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(k, i, &val)); i++) {
treeview_add_val(val);
}
if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) gtk_show_werror(error);
return;
}
GtkWidget* create_mainwin (void)
{
GtkWidget *vbox1;
GtkWidget *menubar;
GtkWidget *menu_file;
GtkWidget *menu_file_menu;
GtkWidget *open_nt4;
GtkWidget *open_gconf;
GtkWidget *open_remote;
GtkWidget *separatormenuitem1;
GtkWidget *quit;
GtkWidget *men_edit;
GtkWidget *men_edit_menu;
GtkWidget *cut;
GtkWidget *copy;
GtkWidget *paste;
GtkWidget *delete;
GtkCellRenderer *renderer;
GtkTreeViewColumn *curcol;
GtkWidget *help;
GtkWidget *help_menu;
GtkWidget *about;
GtkWidget *hbox1;
GtkWidget *scrolledwindow1;
GtkWidget *scrolledwindow2;
GtkWidget *tree_vals;
GtkWidget *statusbar;
GtkAccelGroup *accel_group;
GtkTreeIter iter, child;
accel_group = gtk_accel_group_new ();
mainwin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (mainwin), "Registry editor");
gtk_window_set_default_size (GTK_WINDOW (mainwin), 642, 562);
vbox1 = gtk_vbox_new (FALSE, 0);
gtk_widget_show (vbox1);
gtk_container_add (GTK_CONTAINER (mainwin), vbox1);
menubar = gtk_menu_bar_new ();
gtk_widget_show (menubar);
gtk_box_pack_start (GTK_BOX (vbox1), menubar, FALSE, FALSE, 0);
menu_file = gtk_menu_item_new_with_mnemonic ("_File");
gtk_widget_show (menu_file);
gtk_container_add (GTK_CONTAINER (menubar), menu_file);
menu_file_menu = gtk_menu_new ();
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_file), menu_file_menu);
open_nt4 = gtk_image_menu_item_new_with_mnemonic("_Open NT4 file");
gtk_widget_show (open_nt4);
gtk_container_add (GTK_CONTAINER (menu_file_menu), open_nt4);
open_gconf = gtk_image_menu_item_new_with_mnemonic ("_Open GConf");
gtk_widget_show (open_gconf);
gtk_container_add (GTK_CONTAINER (menu_file_menu), open_gconf);
open_remote = gtk_menu_item_new_with_mnemonic ("_Open Remote");
gtk_widget_show (open_remote);
gtk_container_add (GTK_CONTAINER (menu_file_menu), open_remote);
save = gtk_image_menu_item_new_from_stock ("gtk-save", accel_group);
gtk_widget_show (save);
gtk_widget_set_sensitive( save, False );
gtk_container_add (GTK_CONTAINER (menu_file_menu), save);
save_as = gtk_image_menu_item_new_from_stock ("gtk-save-as", accel_group);
gtk_widget_show (save_as);
gtk_widget_set_sensitive( save_as, False );
gtk_container_add (GTK_CONTAINER (menu_file_menu), save_as);
separatormenuitem1 = gtk_menu_item_new ();
gtk_widget_show (separatormenuitem1);
gtk_container_add (GTK_CONTAINER (menu_file_menu), separatormenuitem1);
gtk_widget_set_sensitive (separatormenuitem1, FALSE);
quit = gtk_image_menu_item_new_from_stock ("gtk-quit", accel_group);
gtk_widget_show (quit);
gtk_container_add (GTK_CONTAINER (menu_file_menu), quit);
men_edit = gtk_menu_item_new_with_mnemonic ("_Edit");
gtk_widget_show (men_edit);
gtk_container_add (GTK_CONTAINER (menubar), men_edit);
men_edit_menu = gtk_menu_new ();
gtk_menu_item_set_submenu (GTK_MENU_ITEM (men_edit), men_edit_menu);
cut = gtk_image_menu_item_new_from_stock ("gtk-cut", accel_group);
gtk_widget_show (cut);
gtk_widget_set_sensitive(cut, False);
gtk_container_add (GTK_CONTAINER (men_edit_menu), cut);
copy = gtk_image_menu_item_new_from_stock ("gtk-copy", accel_group);
gtk_widget_show (copy);
gtk_widget_set_sensitive(copy, False);
gtk_container_add (GTK_CONTAINER (men_edit_menu), copy);
paste = gtk_image_menu_item_new_from_stock ("gtk-paste", accel_group);
gtk_widget_show (paste);
gtk_widget_set_sensitive(paste, False);
gtk_container_add (GTK_CONTAINER (men_edit_menu), paste);
delete = gtk_image_menu_item_new_from_stock ("gtk-delete", accel_group);
gtk_widget_show (delete);
gtk_widget_set_sensitive(delete, False);
gtk_container_add (GTK_CONTAINER (men_edit_menu), delete);
help = gtk_menu_item_new_with_mnemonic ("_Help");
gtk_widget_show (help);
gtk_container_add (GTK_CONTAINER (menubar), help);
help_menu = gtk_menu_new ();
gtk_menu_item_set_submenu (GTK_MENU_ITEM (help), help_menu);
about = gtk_menu_item_new_with_mnemonic ("_About");
gtk_widget_show (about);
gtk_container_add (GTK_CONTAINER (help_menu), about);
hbox1 = gtk_hbox_new (FALSE, 0);
gtk_widget_show (hbox1);
gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0);
scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_show (scrolledwindow1);
gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow1, TRUE, TRUE, 0);
tree_keys = gtk_tree_view_new ();
/* Column names */
curcol = gtk_tree_view_column_new ();
gtk_tree_view_column_set_title(curcol, "Name");
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(curcol, renderer, True);
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_keys), curcol);
gtk_tree_view_column_add_attribute(curcol, renderer, "text", 0);
gtk_widget_show (tree_keys);
gtk_container_add (GTK_CONTAINER (scrolledwindow1), tree_keys);
store_keys = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
gtk_tree_view_set_model(GTK_TREE_VIEW(tree_keys), GTK_TREE_MODEL(store_keys));
g_object_unref(store_keys);
g_signal_connect ((gpointer) tree_keys, "row-activated",
G_CALLBACK (on_key_activate),
NULL);
g_signal_connect ((gpointer) tree_keys, "row-expanded",
G_CALLBACK (expand_key),
NULL);
scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_show (scrolledwindow2);
gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow2, TRUE, TRUE, 0);
tree_vals = gtk_tree_view_new ();
/* Column names */
curcol = gtk_tree_view_column_new_with_attributes ("Name", gtk_cell_renderer_text_new(), NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_vals), curcol);
curcol = gtk_tree_view_column_new_with_attributes ("Type", gtk_cell_renderer_text_new(), NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_vals), curcol);
curcol = gtk_tree_view_column_new_with_attributes ("Value", gtk_cell_renderer_text_new(), NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_vals), curcol);
gtk_widget_show (tree_vals);
gtk_container_add (GTK_CONTAINER (scrolledwindow2), tree_vals);
store_vals = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
gtk_tree_view_set_model(GTK_TREE_VIEW(tree_vals), GTK_TREE_MODEL(store_vals));
g_object_unref(store_vals);
statusbar = gtk_statusbar_new ();
gtk_widget_show (statusbar);
gtk_box_pack_start (GTK_BOX (vbox1), statusbar, FALSE, FALSE, 0);
gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (statusbar), FALSE);
g_signal_connect ((gpointer) open_nt4, "activate",
G_CALLBACK (on_open_nt4_activate),
NULL);
g_signal_connect ((gpointer) open_gconf, "activate",
G_CALLBACK (on_open_gconf_activate),
NULL);
g_signal_connect ((gpointer) open_remote, "activate",
G_CALLBACK (on_open_remote_activate),
NULL);
g_signal_connect ((gpointer) save, "activate",
G_CALLBACK (on_save_activate),
NULL);
g_signal_connect ((gpointer) save_as, "activate",
G_CALLBACK (on_save_as_activate),
NULL);
g_signal_connect ((gpointer) quit, "activate",
G_CALLBACK (on_quit_activate),
NULL);
g_signal_connect ((gpointer) cut, "activate",
G_CALLBACK (on_cut_activate),
NULL);
g_signal_connect ((gpointer) copy, "activate",
G_CALLBACK (on_copy_activate),
NULL);
g_signal_connect ((gpointer) paste, "activate",
G_CALLBACK (on_paste_activate),
NULL);
g_signal_connect ((gpointer) delete, "activate",
G_CALLBACK (on_delete_activate),
NULL);
g_signal_connect ((gpointer) about, "activate",
G_CALLBACK (on_about_activate),
NULL);
gtk_window_add_accel_group (GTK_WINDOW (mainwin), accel_group);
return mainwin;
}
static GtkWidget* create_aboutwin (void)
{
GtkWidget *dialog_vbox1;
GtkWidget *image1;
GtkWidget *label1;
GtkWidget *label2;
GtkWidget *dialog_action_area1;
GtkWidget *closebutton1;
aboutwin = gtk_dialog_new ();
gtk_window_set_title (GTK_WINDOW (aboutwin), "About GRegEdit");
gtk_window_set_resizable (GTK_WINDOW (aboutwin), FALSE);
dialog_vbox1 = GTK_DIALOG (aboutwin)->vbox;
gtk_widget_show (dialog_vbox1);
/* FIXME: Samba logo ?
image1 = create_pixmap (aboutwin, "samba.png");
gtk_widget_show (image1);
gtk_box_pack_start (GTK_BOX (dialog_vbox1), image1, FALSE, TRUE, 0); */
label1 = gtk_label_new ("GRegEdit 0.1");
gtk_widget_show (label1);
gtk_box_pack_start (GTK_BOX (dialog_vbox1), label1, FALSE, FALSE, 0);
gtk_label_set_use_markup (GTK_LABEL (label1), TRUE);
label2 = gtk_label_new_with_mnemonic ("(C) 2004 Jelmer Vernooij <jelmer@samba.org>\nPart of Samba\nhttp://www.samba.org/\n");
gtk_widget_show (label2);
gtk_box_pack_start (GTK_BOX (dialog_vbox1), label2, TRUE, FALSE, 0);
gtk_label_set_use_markup (GTK_LABEL (label2), TRUE);
dialog_action_area1 = GTK_DIALOG (aboutwin)->action_area;
gtk_widget_show (dialog_action_area1);
gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);
closebutton1 = gtk_button_new_from_stock ("gtk-close");
gtk_widget_show (closebutton1);
gtk_dialog_add_action_widget (GTK_DIALOG (aboutwin), closebutton1, GTK_RESPONSE_CLOSE);
GTK_WIDGET_SET_FLAGS (closebutton1, GTK_CAN_DEFAULT);
return aboutwin;
}
GtkWidget* create_openfilewin (void)
{
GtkWidget *ok_button;
GtkWidget *cancel_button;
openfilewin = gtk_file_selection_new ("Select File");
gtk_container_set_border_width (GTK_CONTAINER (openfilewin), 10);
ok_button = GTK_FILE_SELECTION (openfilewin)->ok_button;
gtk_widget_show (ok_button);
GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT);
cancel_button = GTK_FILE_SELECTION (openfilewin)->cancel_button;
gtk_widget_show (cancel_button);
GTK_WIDGET_SET_FLAGS (cancel_button, GTK_CAN_DEFAULT);
return openfilewin;
}
GtkWidget* create_savefilewin (void)
{
GtkWidget *ok_button;
GtkWidget *cancel_button;
savefilewin = gtk_file_selection_new ("Select File");
gtk_container_set_border_width (GTK_CONTAINER (savefilewin), 10);
ok_button = GTK_FILE_SELECTION (savefilewin)->ok_button;
gtk_widget_show (ok_button);
GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT);
cancel_button = GTK_FILE_SELECTION (savefilewin)->cancel_button;
gtk_widget_show (cancel_button);
GTK_WIDGET_SET_FLAGS (cancel_button, GTK_CAN_DEFAULT);
return savefilewin;
}
int main (int argc, char *argv[])
{
poptContext pc;
const char *backend = NULL, *credentials = NULL, *location;
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
};
gtk_init (&argc, &argv);
pc = poptGetContext(argv[0], argc, (const char **) argv, long_options,0);
while((opt = poptGetNextOpt(pc)) != -1) {
}
location = poptGetArg(pc);
if(location) {
WERROR error;
if(!backend) {
if(credentials)backend = "rpc";
else backend = "nt4";
}
error = reg_open(backend, location, credentials, &registry);
if(!W_ERROR_IS_OK(error)) {
gtk_show_werror(error);
return -1;
}
mainwin = create_mainwin ();
registry_load_root();
} else
mainwin = create_mainwin ();
gtk_widget_show (mainwin);
gtk_main ();
if(registry)reg_free(registry);
return 0;
}

View File

@ -201,6 +201,7 @@ int main (int argc, char **argv)
REG_HANDLE *h;
struct poptOption long_options[] = {
POPT_AUTOHELP
POPT_COMMON_SAMBA
{"backend", 'b', POPT_ARG_STRING, &backend, 0, "backend to use", NULL},
POPT_TABLEEND
};

View File

@ -72,11 +72,11 @@
[in,out,ref] policy_handle *handle,
[in] winreg_String key,
[in] winreg_String class,
[in,out] uint32 reserved,
[in] uint32 reserved,
[out] uint32 *unknown,
[in] uint32 access_mask,
[in] uint32 sec_info,
[in] sec_desc_buf *sec_desc,
[in] uint32 reserved2
[in,ref] uint32 *sec_info,
[in] sec_desc_buf *sec_desc
);
/******************/
@ -150,6 +150,14 @@
/******************/
/* Function: 0x0c */
WERROR winreg_GetKeySecurity(
[in,ref] policy_handle *handle,
[in] uint32 sec_info,
[in] uint32 *len1,
[in] uint32 empty,
[in] uint32 len2,
[in] uint32 unknown1,
[in] uint32 unknown2,
[out] sec_desc_buf *data
);
/******************/
@ -211,11 +219,24 @@
/******************/
/* Function: 0x15 */
WERROR winreg_SetKeySecurity(
[in,ref] policy_handle *handle,
[in] uint32 sec_info,
[in] sec_desc_buf *sec_desc
);
typedef struct {
uint32 max_len;
[length_is(buf_max_len)] uint8 *buffer;
uint32 len;
} winreg_Value;
/******************/
/* Function: 0x16 */
WERROR winreg_SetValue(
[in,ref] policy_handle *handle,
[in] winreg_String name,
[in] uint32 type,
[in] winreg_Value value
);
/******************/
@ -226,11 +247,15 @@
/******************/
/* Function: 0x18 */
WERROR winreg_InitiateSystemShutdown(
[in] winreg_String message,
[in] uint32 timeout,
[in] uint16 flags
);
/******************/
/* Function: 0x19 */
WERROR winreg_AbortSystemShutdown(
[in,ref] uint16 *server
);
/******************/
@ -264,7 +289,7 @@
/******************/
/* Function: 0x1e */
WERROR winreg_InitiateSystemShutdownEx(
);
);
/******************/
/* Function: 0x1f */

View File

@ -22,6 +22,18 @@
#include "includes.h"
/**
* General notes for the current implementation:
*
* - All hives are currently openened as subkeys of one single registry file
* (e.g. HKCR from \HKEY_CURRENT_USER, etc). This might be changed in
* the future and we might want to make it possible to configure
* what registries are behind which hives (e.g.
* \HKEY_CURRENT_USER -> gconf,
* \HKEY_LOCAL_MACHINE -> tdb,
* etc
*/
enum handle_types { HTYPE_REGKEY, HTYPE_REGVAL };
struct _privatedata {
@ -39,9 +51,10 @@ static void winreg_unbind(struct dcesrv_connection *dc, const struct dcesrv_inte
static NTSTATUS winreg_bind(struct dcesrv_call_state *dc, const struct dcesrv_interface *di)
{
struct _privatedata *data;
data = talloc(dc->mem_ctx, sizeof(struct _privatedata));
data->registry = reg_open(lp_parm_string(-1,"winreg","subsystem"),lp_parm_string(-1,"winreg", "file"), False);
if(!data->registry) return NT_STATUS_UNSUCCESSFUL;
WERROR error;
data = talloc(dc->conn->mem_ctx, sizeof(struct _privatedata));
error = reg_open("dir", "/tmp/reg", "", &data->registry);
if(!W_ERROR_IS_OK(error)) return werror_to_ntstatus(error);
dc->conn->private = data;
return NT_STATUS_OK;
}
@ -49,70 +62,34 @@ static NTSTATUS winreg_bind(struct dcesrv_call_state *dc, const struct dcesrv_in
#define DCESRV_INTERFACE_WINREG_BIND winreg_bind
#define DCESRV_INTERFACE_WINREG_UNBIND winreg_unbind
/*
winreg_OpenHKCR
*/
static NTSTATUS winreg_OpenHKCR(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct winreg_OpenHKCR *r)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
/*
winreg_OpenHKCU
*/
static NTSTATUS winreg_OpenHKCU(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct winreg_OpenHKCU *r)
{
struct _privatedata *data = dce_call->conn->private;
REG_KEY *root = reg_get_root(data->registry);
REG_KEY *k = reg_open_key(root, "\\HKEY_CURRENT_USER");
if(!k) {
r->out.result = WERR_BADFILE;
} else {
struct dcesrv_handle *h = dcesrv_handle_new(dce_call->conn, HTYPE_REGKEY);
h->data = k;
r->out.handle = &h->wire_handle;
}
r->out.result = WERR_OK;
return NT_STATUS_OK;
}
/*
winreg_OpenHKLM
*/
static NTSTATUS winreg_OpenHKLM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct winreg_OpenHKLM *r)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
/*
winreg_OpenHKPD
*/
static NTSTATUS winreg_OpenHKPD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct winreg_OpenHKPD *r)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
/*
winreg_OpenHKU
*/
static NTSTATUS winreg_OpenHKU(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct winreg_OpenHKU *r)
{
return NT_STATUS_NOT_IMPLEMENTED;
#define func_winreg_OpenHive(k,n) static NTSTATUS winreg_Open ## k (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_Open ## k *r) \
{ \
struct _privatedata *data = dce_call->conn->private; \
REG_KEY *root/* = reg_get_root(data->registry)*/; \
REG_KEY *k/* = reg_open_key(root, n)*/; \
\
if(!k) { \
r->out.result = WERR_BADFILE; \
} else { \
struct dcesrv_handle *h = dcesrv_handle_new(dce_call->conn, HTYPE_REGKEY); \
h->data = k; \
r->out.handle = &h->wire_handle; \
} \
\
r->out.result = WERR_OK; \
\
return NT_STATUS_OK; \
}
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_CC")
func_winreg_OpenHive(HKDD,"\\HKEY_DD")
func_winreg_OpenHive(HKPT,"\\HKEY_PT")
func_winreg_OpenHive(HKPN,"\\HKEY_PN")
/*
winreg_CloseKey
@ -120,7 +97,15 @@ static NTSTATUS winreg_OpenHKU(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
static NTSTATUS winreg_CloseKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct winreg_CloseKey *r)
{
return NT_STATUS_NOT_IMPLEMENTED;
struct dcesrv_handle *h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
if(!h) {
return NT_STATUS_INVALID_HANDLE;
}
reg_key_free((REG_KEY *)h->data);
dcesrv_handle_destroy(dce_call->conn, h);
return NT_STATUS_OK;
}
@ -130,7 +115,25 @@ static NTSTATUS winreg_CloseKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *
static NTSTATUS winreg_CreateKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct winreg_CreateKey *r)
{
return NT_STATUS_NOT_IMPLEMENTED;
struct dcesrv_handle *h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
WERROR error;
REG_KEY *parent;
if(!h) {
return NT_STATUS_INVALID_HANDLE;
}
parent = h->data;
error = reg_key_add_name_recursive(parent, r->in.key.name);
if(W_ERROR_IS_OK(error)) {
struct dcesrv_handle *newh = dcesrv_handle_new(dce_call->conn, HTYPE_REGKEY);
error = reg_open_key(parent, r->in.key.name, (REG_KEY **)&newh->data);
if(W_ERROR_IS_OK(error)) r->out.handle = &newh->wire_handle;
else dcesrv_handle_destroy(dce_call->conn, newh);
}
r->out.result = error;
return NT_STATUS_OK;
}
@ -140,7 +143,19 @@ static NTSTATUS winreg_CreateKey(struct dcesrv_call_state *dce_call, TALLOC_CTX
static NTSTATUS winreg_DeleteKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct winreg_DeleteKey *r)
{
return NT_STATUS_NOT_IMPLEMENTED;
struct dcesrv_handle *h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
REG_KEY *parent, *key;
WERROR error;
if(!h) {
return NT_STATUS_INVALID_HANDLE;
}
parent = h->data;
r->out.result = reg_open_key(parent, r->in.key.name, &key);
if(W_ERROR_IS_OK(r->out.result)) {
r->out.result = reg_key_del(key);
}
return NT_STATUS_OK;
}
@ -160,6 +175,14 @@ static NTSTATUS winreg_DeleteValue(struct dcesrv_call_state *dce_call, TALLOC_CT
static NTSTATUS winreg_EnumKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct winreg_EnumKey *r)
{
struct dcesrv_handle *h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
REG_KEY *key;
if(!h) {
return NT_STATUS_INVALID_HANDLE;
}
key = h->data;
return NT_STATUS_NOT_IMPLEMENTED;
}
@ -221,11 +244,22 @@ static NTSTATUS winreg_OpenKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
struct winreg_OpenKey *r)
{
struct dcesrv_handle *h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
REG_KEY *k, *subkey;
if(!h) {
return NT_STATUS_INVALID_HANDLE;
}
k = h->data;
r->out.result = reg_open_key(k, r->in.keyname.name, &subkey);
if(W_ERROR_IS_OK(r->out.result)) {
struct dcesrv_handle *newh = dcesrv_handle_new(dce_call->conn, HTYPE_REGKEY);
h->data = subkey;
r->out.handle = &h->wire_handle;
}
return NT_STATUS_NOT_IMPLEMENTED;
return NT_STATUS_OK;
}
@ -339,26 +373,6 @@ static NTSTATUS winreg_GetVersion(struct dcesrv_call_state *dce_call, TALLOC_CTX
}
/*
winreg_OpenHKCC
*/
static NTSTATUS winreg_OpenHKCC(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct winreg_OpenHKCC *r)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
/*
winreg_OpenHKDD
*/
static NTSTATUS winreg_OpenHKDD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct winreg_OpenHKDD *r)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
/*
winreg_QueryMultipleValues
*/
@ -389,26 +403,6 @@ static NTSTATUS winreg_SaveKeyEx(struct dcesrv_call_state *dce_call, TALLOC_CTX
}
/*
winreg_OpenHKPT
*/
static NTSTATUS winreg_OpenHKPT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct winreg_OpenHKPT *r)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
/*
winreg_OpenHKPN
*/
static NTSTATUS winreg_OpenHKPN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct winreg_OpenHKPN *r)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
/*
winreg_QueryMultipleValues2
*/

View File

@ -54,27 +54,24 @@ static BOOL test_GetVersion(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
}
static BOOL test_CreateKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *handle, const char *name, const char *class)
struct policy_handle *handle, char *name, const char *class)
{
struct winreg_CreateKey r;
struct policy_handle newhandle;
NTSTATUS status;
struct sec_desc_buf sec_desc;
uint32 sec_info = 0;
printf("\ntesting CreateKey\n");
r.in.handle = handle;
r.out.handle = &newhandle;
init_winreg_String(&r.in.key, name);
init_winreg_String(&r.in.class, class);
init_winreg_String(&r.in.class, class);
r.in.reserved = 0x0;
r.in.reserved2 = 0x0;
r.in.access_mask = 0x02000000;
r.out.reserved = 0x0;
r.in.sec_info = 0x0;
sec_desc.size = 0;
sec_desc.sd = NULL;
r.in.sec_desc = &sec_desc;
r.in.sec_info = &sec_info;
r.in.sec_desc = NULL;
status = dcerpc_winreg_CreateKey(p, mem_ctx, &r);
@ -148,6 +145,11 @@ static BOOL test_OpenKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
status = dcerpc_winreg_OpenKey(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
printf("OpenKey failed - %s\n", nt_errstr(status));
return False;
}
if (!W_ERROR_IS_OK(r.out.result)) {
printf("OpenKey failed - %s\n", win_errstr(r.out.result));
return False;
@ -195,6 +197,11 @@ static BOOL test_QueryInfoKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
status = dcerpc_winreg_QueryInfoKey(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
printf("QueryInfoKey failed - %s\n", nt_errstr(status));
return False;
}
if (!W_ERROR_IS_OK(r.out.result)) {
printf("QueryInfoKey failed - %s\n", win_errstr(r.out.result));
return False;
@ -371,6 +378,53 @@ static BOOL test_OpenHKCR(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return ret;
}
static BOOL test_InitiateSystemShutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
const char *msg, uint32 timeout)
{
struct winreg_InitiateSystemShutdown r;
NTSTATUS status;
init_winreg_String(&r.in.message, msg);
r.in.flags = 0;
r.in.timeout = timeout;
status = dcerpc_winreg_InitiateSystemShutdown(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
printf("InitiateSystemShutdown failed - %s\n", nt_errstr(status));
return False;
}
if (!W_ERROR_IS_OK(r.out.result)) {
printf("InitiateSystemShutdown failed - %s\n", win_errstr(r.out.result));
return False;
}
return True;
}
static BOOL test_AbortSystemShutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
{
struct winreg_AbortSystemShutdown r;
NTSTATUS status;
r.in.server = 0x0;
status = dcerpc_winreg_AbortSystemShutdown(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
printf("AbortSystemShutdown failed - %s\n", nt_errstr(status));
return False;
}
if (!W_ERROR_IS_OK(r.out.result)) {
printf("AbortSystemShutdown failed - %s\n", win_errstr(r.out.result));
return False;
}
return True;
}
static BOOL test_OpenHKCU(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *handle)
{
@ -433,17 +487,7 @@ static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
if (!open_fn(p, mem_ctx, &handle))
return False;
if (!test_GetVersion(p, mem_ctx, &handle)) {
printf("GetVersion failed\n");
ret = False;
}
if (!test_FlushKey(p, mem_ctx, &handle)) {
printf("FlushKey failed\n");
ret = False;
}
if (!test_CreateKey(p, mem_ctx, &handle, "spottyfoot", "foo")) {
if (!test_CreateKey(p, mem_ctx, &handle, "spottyfoot", NULL)) {
printf("CreateKey failed\n");
ret = False;
}
@ -463,6 +507,16 @@ static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
ret = False;
}
if (!test_GetVersion(p, mem_ctx, &handle)) {
printf("GetVersion failed\n");
ret = False;
}
if (!test_FlushKey(p, mem_ctx, &handle)) {
printf("FlushKey failed\n");
ret = False;
}
/* The HKCR hive has a very large fanout */
@ -482,7 +536,7 @@ static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
BOOL torture_rpc_winreg(int dummy)
{
NTSTATUS status;
struct dcerpc_pipe *p;
struct dcerpc_pipe *p;
TALLOC_CTX *mem_ctx;
BOOL ret = True;
winreg_open_fn *open_fns[] = { test_OpenHKLM, test_OpenHKU,
@ -500,6 +554,9 @@ BOOL torture_rpc_winreg(int dummy)
return False;
}
if(!test_InitiateSystemShutdown(p, mem_ctx, "spottyfood", 30))
ret = False;
for (i = 0; i < ARRAY_SIZE(open_fns); i++) {
if (!test_Open(p, mem_ctx, open_fns[i]))
ret = False;