mirror of
https://github.com/samba-team/samba.git
synced 2025-03-01 04:58:35 +03:00
r168: - Cleanups in rpc backend
- Small fixess in nt4 and dir backends - Start on w95 file backend (This used to be commit aa739e8d3c7108f6f2089af2d8d522feacc7f698)
This commit is contained in:
parent
c60c5ebb91
commit
639afabf40
@ -214,7 +214,11 @@ WERROR reg_key_num_subkeys(REG_KEY *key, int *count)
|
||||
{
|
||||
if(!key) return WERR_INVALID_PARAM;
|
||||
|
||||
if(!key->handle->functions->num_subkeys) {
|
||||
if(key->handle->functions->num_subkeys) {
|
||||
return key->handle->functions->num_subkeys(key, count);
|
||||
}
|
||||
|
||||
if(key->handle->functions->fetch_subkeys) {
|
||||
if(!key->cache_subkeys)
|
||||
key->handle->functions->fetch_subkeys(key, &key->cache_subkeys_count, &key->cache_subkeys);
|
||||
|
||||
@ -222,7 +226,20 @@ WERROR reg_key_num_subkeys(REG_KEY *key, int *count)
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
return key->handle->functions->num_subkeys(key, count);
|
||||
if(key->handle->functions->get_subkey_by_index) {
|
||||
int i;
|
||||
WERROR error;
|
||||
REG_KEY *dest;
|
||||
for(i = 0; W_ERROR_IS_OK(error = key->handle->functions->get_subkey_by_index(key, i, &dest)); i++) {
|
||||
reg_key_free(dest);
|
||||
}
|
||||
|
||||
*count = i;
|
||||
if(W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) return WERR_OK;
|
||||
return error;
|
||||
}
|
||||
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
WERROR reg_key_num_values(REG_KEY *key, int *count)
|
||||
@ -306,8 +323,7 @@ WERROR reg_key_get_subkey_by_name(REG_KEY *key, const char *name, REG_KEY **subk
|
||||
|
||||
WERROR reg_key_get_value_by_name(REG_KEY *key, const char *name, REG_VAL **val)
|
||||
{
|
||||
int i, max;
|
||||
REG_VAL *ret = NULL;
|
||||
int i;
|
||||
WERROR error = WERR_OK;
|
||||
|
||||
if(!key) return WERR_INVALID_PARAM;
|
||||
@ -361,7 +377,6 @@ WERROR reg_sync(REG_KEY *h, const char *location)
|
||||
|
||||
WERROR reg_key_del_recursive(REG_KEY *key)
|
||||
{
|
||||
BOOL succeed = True;
|
||||
WERROR error = WERR_OK;
|
||||
int i;
|
||||
|
||||
@ -543,3 +558,27 @@ WERROR reg_save(REG_HANDLE *h, const char *location)
|
||||
/* FIXME */
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
WERROR reg_key_get_parent(REG_KEY *key, REG_KEY **parent)
|
||||
{
|
||||
char *parent_name;
|
||||
char *last;
|
||||
REG_KEY *root;
|
||||
WERROR error;
|
||||
|
||||
error = reg_get_root(key->handle, &root);
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
|
||||
parent_name = strdup(reg_key_get_path(key));
|
||||
last = strrchr(parent_name, '\\');
|
||||
|
||||
if(!last) {
|
||||
SAFE_FREE(parent_name);
|
||||
return WERR_FOOBAR;
|
||||
}
|
||||
*last = '\0';
|
||||
|
||||
error = reg_open_key(root, parent_name, parent);
|
||||
SAFE_FREE(parent_name);
|
||||
return error;
|
||||
}
|
||||
|
@ -58,8 +58,8 @@ struct reg_val_s {
|
||||
};
|
||||
|
||||
/* FIXME */
|
||||
typedef void (*key_notification_function) ();
|
||||
typedef void (*value_notification_function) ();
|
||||
typedef void (*key_notification_function) (void);
|
||||
typedef void (*value_notification_function) (void);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -11,6 +11,7 @@ PKG_CHECK_MODULES(GCONF, gconf-2.0, [ SMB_MODULE_DEFAULT(reg_gconf,STATIC)
|
||||
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_w95, REG, STATIC, lib/registry/reg_backend_w95/reg_backend_w95.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])
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "includes.h"
|
||||
#include "lib/registry/common/registry.h"
|
||||
|
||||
static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *desc)
|
||||
static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *desc, REG_KEY **result)
|
||||
{
|
||||
char *path;
|
||||
int ret;
|
||||
@ -29,7 +29,7 @@ static WERROR reg_dir_add_key(REG_KEY *parent, const char *name, uint32 access_m
|
||||
path = reg_path_win2unix(path);
|
||||
ret = mkdir(path, 0700);
|
||||
SAFE_FREE(path);
|
||||
if(ret == 0)return WERR_OK;
|
||||
if(ret == 0)return WERR_OK; /* FIXME */
|
||||
return WERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
@ -83,7 +83,6 @@ static WERROR reg_dir_fetch_subkeys(REG_KEY *k, int *count, REG_KEY ***r)
|
||||
if(e->d_type == DT_DIR &&
|
||||
strcmp(e->d_name, ".") &&
|
||||
strcmp(e->d_name, "..")) {
|
||||
char *newfullpath;
|
||||
ar[(*count)] = reg_key_new_rel(e->d_name, k, NULL);
|
||||
ar[(*count)]->backend_data = talloc_asprintf(ar[*count]->mem_ctx, "%s/%s", fullpath, e->d_name);
|
||||
if(ar[(*count)])(*count)++;
|
||||
@ -106,16 +105,8 @@ static WERROR reg_dir_open(REG_HANDLE *h, const char *loc, const char *credentia
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static WERROR reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len, REG_VAL **value)
|
||||
static WERROR reg_dir_add_value(REG_KEY *p, const char *name, int type, void *data, int len)
|
||||
{
|
||||
char *fullpath;
|
||||
FILE *fd;
|
||||
*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 WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ Offset Size Contents
|
||||
|
||||
To determine the number of values, you have to look at the owner-nk-record!
|
||||
|
||||
Der vk-Record
|
||||
The vk-Record
|
||||
=============
|
||||
Offset Size Contents
|
||||
0x0000 Word ID: ASCII-"vk" = 0x6B76
|
||||
@ -473,7 +473,7 @@ typedef struct regf_struct_s {
|
||||
int fd;
|
||||
struct stat sbuf;
|
||||
char *base;
|
||||
int modified;
|
||||
BOOL modified;
|
||||
NTTIME last_mod_time;
|
||||
NK_HDR *first_key;
|
||||
int sk_count, sk_map_size;
|
||||
@ -485,7 +485,6 @@ typedef struct regf_struct_s {
|
||||
* keys when we are preparing to write them to a file
|
||||
*/
|
||||
HBIN_BLK *blk_head, *blk_tail, *free_space;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
} REGF;
|
||||
|
||||
DWORD str_to_dword(const char *a) {
|
||||
@ -886,7 +885,6 @@ static WERROR vk_to_val(REG_KEY *parent, VK_HDR *vk_hdr, int size, REG_VAL **val
|
||||
char val_name[1024];
|
||||
REGF *regf = parent->handle->backend_data;
|
||||
int nam_len, dat_len, flag, dat_type, dat_off, vk_id;
|
||||
const char *val_type;
|
||||
REG_VAL *tmp = NULL;
|
||||
|
||||
if (!vk_hdr) return WERR_INVALID_PARAM;
|
||||
@ -1021,7 +1019,7 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent
|
||||
{
|
||||
REGF *regf = h->backend_data;
|
||||
REG_KEY *tmp = NULL, *own;
|
||||
int name_len, clsname_len, sk_off, own_off;
|
||||
int namlen, clsname_len, sk_off, own_off;
|
||||
unsigned int nk_id;
|
||||
SK_HDR *sk_hdr;
|
||||
int type;
|
||||
@ -1037,32 +1035,32 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent
|
||||
|
||||
SMB_REG_ASSERT(size < 0);
|
||||
|
||||
name_len = SVAL(&nk_hdr->nam_len,0);
|
||||
namlen = SVAL(&nk_hdr->nam_len,0);
|
||||
clsname_len = SVAL(&nk_hdr->clsnam_len,0);
|
||||
|
||||
/*
|
||||
* The value of -size should be ge
|
||||
* (sizeof(NK_HDR) - 1 + name_len)
|
||||
* (sizeof(NK_HDR) - 1 + namlen)
|
||||
* The -1 accounts for the fact that we included the first byte of
|
||||
* the name in the structure. clsname_len is the length of the thing
|
||||
* pointed to by clsnam_off
|
||||
*/
|
||||
|
||||
if (-size < (sizeof(NK_HDR) - 1 + name_len)) {
|
||||
if (-size < (sizeof(NK_HDR) - 1 + namlen)) {
|
||||
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));
|
||||
sizeof(NK_HDR), namlen, clsname_len));
|
||||
return WERR_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
DEBUG(2, ("NK HDR: Name len: %d, class name len: %d\n", name_len, clsname_len));
|
||||
DEBUG(2, ("NK HDR: Name len: %d, class name len: %d\n", namlen, clsname_len));
|
||||
|
||||
/* Fish out the key name and process the LF list */
|
||||
|
||||
SMB_REG_ASSERT(name_len < sizeof(key_name));
|
||||
SMB_REG_ASSERT(namlen < sizeof(key_name));
|
||||
|
||||
strncpy(key_name, nk_hdr->key_nam, name_len);
|
||||
key_name[name_len] = '\0';
|
||||
strncpy(key_name, nk_hdr->key_nam, namlen);
|
||||
key_name[namlen] = '\0';
|
||||
|
||||
type = (SVAL(&nk_hdr->type,0)==0x2C?REG_ROOT_KEY:REG_SUB_KEY);
|
||||
if(type == REG_ROOT_KEY && parent) {
|
||||
@ -1088,7 +1086,7 @@ static WERROR nk_to_key(REG_HANDLE *h, NK_HDR *nk_hdr, int size, REG_KEY *parent
|
||||
clsnamep = (smb_ucs2_t *)LOCN(regf->base, clsnam_off);
|
||||
DEBUG(2, ("Class Name Offset: %0X\n", clsnam_off));
|
||||
|
||||
tmp->class_name = talloc_strdup_w(regf->mem_ctx, clsnamep);
|
||||
tmp->class_name = talloc_strdup_w(h->mem_ctx, clsnamep);
|
||||
|
||||
DEBUGADD(2,(" Class Name: %s\n", cls_name));
|
||||
|
||||
@ -1572,22 +1570,17 @@ static WERROR nt_close_registry (REG_HANDLE *h)
|
||||
regf->base = NULL;
|
||||
close(regf->fd); /* Ignore the error :-) */
|
||||
|
||||
free(regf->sk_map);
|
||||
regf->sk_count = regf->sk_map_size = 0;
|
||||
|
||||
free(regf);
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static WERROR nt_open_registry (REG_HANDLE *h, const char *location, const char *credentials)
|
||||
{
|
||||
REGF *regf = (REGF *)malloc(sizeof(REGF));
|
||||
REGF *regf = (REGF *)talloc_p(h->mem_ctx, REGF);
|
||||
REGF_HDR *regf_hdr;
|
||||
unsigned int regf_id, hbin_id;
|
||||
HBIN_HDR *hbin_hdr;
|
||||
|
||||
memset(regf, 0, sizeof(REGF));
|
||||
regf->mem_ctx = talloc_init("regf");
|
||||
regf->owner_sid_str = credentials;
|
||||
h->backend_data = regf;
|
||||
|
||||
|
@ -20,6 +20,13 @@
|
||||
#include "includes.h"
|
||||
#include "lib/registry/common/registry.h"
|
||||
|
||||
/**
|
||||
* This is the RPC backend for the registry library.
|
||||
*
|
||||
* This backend is a little special. The root key is 'virtual'. All
|
||||
* of its subkeys are the hives available on the remote server.
|
||||
*/
|
||||
|
||||
static void init_winreg_String(struct winreg_String *name, const char *s)
|
||||
{
|
||||
name->name = s;
|
||||
@ -35,7 +42,6 @@ static void init_winreg_String(struct winreg_String *name, const char *s)
|
||||
|
||||
#define openhive(u) static struct policy_handle *open_ ## u(struct dcerpc_pipe *p, REG_HANDLE *h) \
|
||||
{ \
|
||||
NTSTATUS status; \
|
||||
struct winreg_Open ## u r; \
|
||||
struct winreg_OpenUnknown unknown; \
|
||||
struct policy_handle *hnd = malloc(sizeof(struct policy_handle)); \
|
||||
@ -66,7 +72,7 @@ struct rpc_data {
|
||||
};
|
||||
|
||||
struct {
|
||||
char *name;
|
||||
const char *name;
|
||||
struct policy_handle *(*open) (struct dcerpc_pipe *p, REG_HANDLE *h);
|
||||
} known_hives[] = {
|
||||
{ "HKEY_LOCAL_MACHINE", open_HKLM },
|
||||
@ -98,7 +104,6 @@ static WERROR rpc_open_registry(REG_HANDLE *h, const char *location, const char
|
||||
lp_workgroup(),
|
||||
user, pass);
|
||||
|
||||
|
||||
h->backend_data = mydata;
|
||||
|
||||
return ntstatus_to_werror(status);
|
||||
@ -118,64 +123,66 @@ static WERROR rpc_close_registry(REG_HANDLE *h)
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static struct policy_handle *rpc_get_key_handle(REG_HANDLE *h, const char *path)
|
||||
static WERROR rpc_key_put_policy_handle(REG_KEY *k)
|
||||
{
|
||||
char *hivename;
|
||||
int i = 0;
|
||||
struct rpc_data *mydata = h->backend_data;
|
||||
struct policy_handle *hive = NULL;
|
||||
char *end = strchr(path+1, '\\');
|
||||
NTSTATUS status;
|
||||
struct policy_handle *key_handle, *hive = NULL;
|
||||
struct winreg_OpenKey r;
|
||||
struct policy_handle *key_handle = talloc(h->mem_ctx, sizeof(struct policy_handle));
|
||||
TALLOC_CTX *mem_ctx;
|
||||
|
||||
if(end) hivename = strndup(path+1, end-path-1);
|
||||
else hivename = strdup(path+1);
|
||||
int i;
|
||||
struct rpc_data *mydata = k->handle->backend_data;
|
||||
char *realkeyname, *hivename;
|
||||
if(k->backend_data) return WERR_OK;
|
||||
|
||||
/* First, ensure the handle to the hive is opened */
|
||||
realkeyname = strchr(k->path, '\\');
|
||||
if(realkeyname) hivename = strndup(k->path+1, realkeyname-k->path-1);
|
||||
else hivename = strdup(k->path+1);
|
||||
|
||||
for(i = 0; known_hives[i].name; i++) {
|
||||
if(!strcmp(hivename, known_hives[i].name)) {
|
||||
if(!mydata->hives[i]) mydata->hives[i] = known_hives[i].open(mydata->pipe, h);
|
||||
if(!mydata->hives[i]) mydata->hives[i] = known_hives[i].open(mydata->pipe, k->handle);
|
||||
hive = mydata->hives[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!hive) {
|
||||
DEBUG(0, ("No such hive: %s\n", hivename));
|
||||
return NULL;
|
||||
return WERR_FOOBAR;
|
||||
}
|
||||
|
||||
DEBUG(2, ("Opening %s, hive: %s\n", path, hivename));
|
||||
if(realkeyname[0] == '\\')realkeyname++;
|
||||
|
||||
if(!end || !(*end) || !(*(end+1))) return hive;
|
||||
if(!realkeyname || !(*realkeyname)) {
|
||||
k->backend_data = hive;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
key_handle = talloc(k->mem_ctx, sizeof(struct policy_handle));
|
||||
|
||||
/* Then, open the handle using the hive */
|
||||
|
||||
memset(&r, 0, sizeof(struct winreg_OpenKey));
|
||||
r.in.handle = hive;
|
||||
init_winreg_String(&r.in.keyname, end+1);
|
||||
init_winreg_String(&r.in.keyname, realkeyname);
|
||||
r.in.unknown = 0x00000000;
|
||||
r.in.access_mask = 0x02000000;
|
||||
r.out.handle = key_handle;
|
||||
|
||||
mem_ctx = talloc_init("openkey");
|
||||
status = dcerpc_winreg_OpenKey(mydata->pipe, mem_ctx, &r);
|
||||
talloc_destroy(mem_ctx);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return key_handle;
|
||||
dcerpc_winreg_OpenKey(mydata->pipe, k->mem_ctx, &r);
|
||||
|
||||
if(W_ERROR_IS_OK(r.out.result)) k->backend_data = key_handle;
|
||||
|
||||
return r.out.result;
|
||||
}
|
||||
|
||||
static WERROR rpc_open_key(REG_HANDLE *h, const char *name, REG_KEY **key)
|
||||
{
|
||||
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;
|
||||
WERROR error;
|
||||
*key = reg_key_new_abs(name, h, NULL);
|
||||
return rpc_key_put_policy_handle(*key);
|
||||
}
|
||||
|
||||
static WERROR rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys)
|
||||
static WERROR rpc_get_subkey_by_index(REG_KEY *parent, int n, REG_KEY **subkey)
|
||||
{
|
||||
struct winreg_EnumKey r;
|
||||
struct winreg_EnumKeyNameRequest keyname;
|
||||
@ -183,28 +190,22 @@ static WERROR rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys)
|
||||
struct winreg_Time tm;
|
||||
struct rpc_data *mydata = parent->handle->backend_data;
|
||||
int i;
|
||||
REG_KEY **ar = talloc(parent->mem_ctx, sizeof(REG_KEY *));
|
||||
NTSTATUS status = NT_STATUS_OK;
|
||||
NTSTATUS status;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
|
||||
/* List the hives */
|
||||
if(parent->backend_data == parent->handle->backend_data) {
|
||||
for(i = 0; known_hives[i].name; i++) {
|
||||
ar[i] = reg_key_new_rel(known_hives[i].name, parent, NULL);
|
||||
(*count)++;
|
||||
ar = talloc_realloc(parent->mem_ctx, ar, sizeof(REG_KEY *) * ((*count)+1));
|
||||
}
|
||||
/* If parent is the root key, list the hives */
|
||||
if(parent->backend_data == mydata) {
|
||||
if(!known_hives[n].name) return WERR_NO_MORE_ITEMS;
|
||||
|
||||
*subkeys = ar;
|
||||
*subkey = reg_key_new_rel(known_hives[n].name, parent, known_hives[n].open(mydata->pipe, parent->handle));
|
||||
|
||||
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) {
|
||||
rpc_key_put_policy_handle(parent);
|
||||
}
|
||||
|
||||
if(!parent->backend_data) return WERR_GENERAL_FAILURE;
|
||||
|
||||
(*count) = 0;
|
||||
r.in.handle = parent->backend_data;
|
||||
keyname.unknown = 0x0000020a;
|
||||
init_winreg_String(&keyname.key_name, NULL);
|
||||
@ -215,134 +216,59 @@ static WERROR rpc_fetch_subkeys(REG_KEY *parent, int *count, REG_KEY ***subkeys)
|
||||
r.in.last_changed_time = &tm;
|
||||
r.out.result.v = 0;
|
||||
|
||||
for(i = 0; NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result); i++) {
|
||||
r.in.enum_index = i;
|
||||
r.in.unknown = r.out.unknown = 0x0414;
|
||||
r.in.key_name_len = r.out.key_name_len = 0;
|
||||
status = dcerpc_winreg_EnumKey(mydata->pipe, parent->mem_ctx, &r);
|
||||
if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
|
||||
ar[(*count)] = reg_key_new_rel(r.out.out_name->name, parent, NULL);
|
||||
(*count)++;
|
||||
ar = talloc_realloc(parent->mem_ctx, ar, ((*count)+1) * sizeof(REG_KEY *));
|
||||
}
|
||||
r.in.enum_index = n;
|
||||
r.in.unknown = r.out.unknown = 0x0414;
|
||||
r.in.key_name_len = r.out.key_name_len = 0;
|
||||
status = dcerpc_winreg_EnumKey(mydata->pipe, parent->mem_ctx, &r);
|
||||
if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
|
||||
*subkey = reg_key_new_rel(r.out.out_name->name, parent, NULL);
|
||||
}
|
||||
|
||||
*subkeys = ar;
|
||||
return r.out.result;
|
||||
}
|
||||
|
||||
static WERROR rpc_fetch_values(REG_KEY *parent, int *count, REG_VAL ***values)
|
||||
{
|
||||
struct winreg_EnumValue r;
|
||||
struct winreg_Uint8buf value;
|
||||
struct winreg_String valuename;
|
||||
struct rpc_data *mydata = parent->handle->backend_data;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
uint32 type, requested_len, returned_len;
|
||||
NTSTATUS status = NT_STATUS_OK;
|
||||
REG_VAL **ar = malloc(sizeof(REG_VAL *));
|
||||
|
||||
(*count) = 0;
|
||||
|
||||
/* Root */
|
||||
if(parent->backend_data == parent->handle->backend_data) {
|
||||
*values = ar;
|
||||
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 WERR_GENERAL_FAILURE;
|
||||
|
||||
r.in.handle = parent->backend_data;
|
||||
r.in.enum_index = 0;
|
||||
|
||||
init_winreg_String(&valuename, NULL);
|
||||
r.in.name = r.out.name = &valuename;
|
||||
|
||||
type = 0;
|
||||
r.in.type = r.out.type = &type;
|
||||
value.max_len = 0x7fff;
|
||||
value.offset = 0;
|
||||
value.len = 0;
|
||||
value.buffer = NULL;
|
||||
|
||||
r.in.value = r.out.value = &value;
|
||||
|
||||
requested_len = value.max_len;
|
||||
r.in.requested_len = &requested_len;
|
||||
returned_len = 0;
|
||||
r.in.returned_len = &returned_len;
|
||||
r.out.result.v = 0;
|
||||
|
||||
while(1) {
|
||||
status = dcerpc_winreg_EnumValue(mydata->pipe, parent->mem_ctx, &r);
|
||||
if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
|
||||
r.in.enum_index++;
|
||||
ar[(*count)] = reg_val_new(parent, NULL);
|
||||
ar[(*count)]->name = talloc_strdup(ar[*count]->mem_ctx, r.out.name->name);
|
||||
ar[(*count)]->data_type = *r.out.type;
|
||||
ar[(*count)]->data_len = value.len;
|
||||
ar[(*count)]->data_blk = talloc(ar[*count]->mem_ctx, value.len);
|
||||
memcpy(ar[(*count)]->data_blk, value.buffer, value.len);
|
||||
(*count)++;
|
||||
ar = talloc_realloc(parent->mem_ctx, ar, ((*count)+1) * sizeof(REG_VAL *));
|
||||
} else break;
|
||||
}
|
||||
|
||||
*values = ar;
|
||||
|
||||
return r.out.result;
|
||||
}
|
||||
|
||||
static WERROR rpc_add_key(REG_KEY *parent, const char *name)
|
||||
static WERROR rpc_add_key(REG_KEY *parent, const char *name, uint32 access_mask, SEC_DESC *sec, REG_KEY **key)
|
||||
{
|
||||
rpc_key_put_policy_handle(parent);
|
||||
/* FIXME */
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static struct policy_handle*get_hive(REG_KEY *k)
|
||||
{
|
||||
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 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);
|
||||
REG_KEY *parent;
|
||||
WERROR error = reg_key_get_parent(k, &parent);
|
||||
if(!W_ERROR_IS_OK(error)) return error;
|
||||
rpc_key_put_policy_handle(parent);
|
||||
|
||||
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);
|
||||
r.in.handle = parent->backend_data;
|
||||
init_winreg_String(&r.in.key, k->name);
|
||||
|
||||
status = dcerpc_winreg_DeleteKey(mydata->pipe, k->mem_ctx, &r);
|
||||
|
||||
return r.out.result;
|
||||
}
|
||||
|
||||
static void rpc_close_key(REG_KEY *k)
|
||||
{
|
||||
reg_key_free(k);
|
||||
}
|
||||
|
||||
static struct registry_ops reg_backend_rpc = {
|
||||
.name = "rpc",
|
||||
.open_registry = rpc_open_registry,
|
||||
.close_registry = rpc_close_registry,
|
||||
.open_root_key = rpc_open_root,
|
||||
.open_key = rpc_open_key,
|
||||
.fetch_subkeys = rpc_fetch_subkeys,
|
||||
.fetch_values = rpc_fetch_values,
|
||||
.get_subkey_by_index = rpc_get_subkey_by_index,
|
||||
.add_key = rpc_add_key,
|
||||
.del_key = rpc_del_key,
|
||||
.free_key_backend_data = rpc_close_key,
|
||||
};
|
||||
|
||||
NTSTATUS reg_rpc_init(void)
|
||||
|
170
source4/lib/registry/reg_backend_w95/reg_backend_w95.c
Normal file
170
source4/lib/registry/reg_backend_w95/reg_backend_w95.c
Normal file
@ -0,0 +1,170 @@
|
||||
/*
|
||||
Samba Unix/Linux SMB client utility libeditreg.c
|
||||
Copyright (C) 2004 Jelmer Vernooij, jelmer@samba.org
|
||||
|
||||
Backend for Windows '95 registry files. Explanation of file format
|
||||
comes from http://www.cs.mun.ca/~michael/regutils/.
|
||||
|
||||
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 "lib/registry/common/registry.h"
|
||||
|
||||
/**
|
||||
* The registry starts with a header that contains pointers to
|
||||
* the rgdb.
|
||||
*
|
||||
* After the main header follows the RGKN header (key index table) */
|
||||
|
||||
typedef unsigned int DWORD;
|
||||
typedef unsigned short WORD;
|
||||
|
||||
typedef struct regc_block {
|
||||
DWORD REGC_ID; /* REGC */
|
||||
DWORD uk1;
|
||||
DWORD rgdb_offset;
|
||||
DWORD chksum;
|
||||
WORD num_rgdb;
|
||||
WORD flags;
|
||||
DWORD uk2;
|
||||
DWORD uk3;
|
||||
DWORD uk4;
|
||||
DWORD uk5;
|
||||
} REGC_HDR;
|
||||
|
||||
typedef struct rgkn_block {
|
||||
DWORD RGKN_ID; /* RGKN */
|
||||
DWORD size;
|
||||
DWORD root_offset;
|
||||
DWORD free_offset;
|
||||
DWORD flags;
|
||||
DWORD chksum;
|
||||
DWORD uk1;
|
||||
DWORD uk2;
|
||||
} RGKN_HDR;
|
||||
|
||||
typedef struct rgkn_key {
|
||||
DWORD inuse;
|
||||
DWORD hash;
|
||||
DWORD next_free;
|
||||
DWORD parent;
|
||||
DWORD child;
|
||||
DWORD next;
|
||||
WORD id;
|
||||
WORD rgdb;
|
||||
} RGKN_KEY;
|
||||
|
||||
typedef struct rgdb_block {
|
||||
DWORD RGDB_ID; /* RGDB */
|
||||
DWORD size;
|
||||
DWORD unused_size;
|
||||
WORD flags;
|
||||
WORD section;
|
||||
DWORD free_offset; /* -1 if there is no free space */
|
||||
WORD max_id;
|
||||
WORD first_free_id;
|
||||
DWORD uk1;
|
||||
DWORD chksum;
|
||||
} RGDB_HDR;
|
||||
|
||||
typedef struct rgdb_key {
|
||||
DWORD inuse;
|
||||
DWORD hash;
|
||||
DWORD next_free;
|
||||
DWORD parent;
|
||||
DWORD child;
|
||||
DWORD next;
|
||||
WORD id;
|
||||
WORD rgdb;
|
||||
} RGDB_KEY;
|
||||
|
||||
typedef struct rgdb_value {
|
||||
DWORD type;
|
||||
DWORD uk1;
|
||||
DWORD name_len;
|
||||
DWORD data_len;
|
||||
} RGDB_VALUE;
|
||||
|
||||
typedef struct regc_struct_s {
|
||||
int fd;
|
||||
struct stat sbuf;
|
||||
BOOL modified;
|
||||
char *base;
|
||||
} REGC;
|
||||
|
||||
static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *credentials)
|
||||
{
|
||||
REGC *regc = talloc_p(h->mem_ctx, REGC);
|
||||
REGC_HDR *regc_hdr;
|
||||
RGKN_HDR *rgkn_hdr;
|
||||
DWORD regc_id, rgkn_id;
|
||||
memset(regc, 0, sizeof(REGC));
|
||||
h->backend_data = regc;
|
||||
|
||||
if((regc->fd = open(location, O_RDONLY, 0000)) < 0) {
|
||||
return WERR_FOOBAR;
|
||||
}
|
||||
|
||||
if(fstat(regc->fd, ®c->sbuf) < 0) {
|
||||
return WERR_FOOBAR;
|
||||
}
|
||||
|
||||
regc->base = mmap(0, regc->sbuf.st_size, PROT_READ, MAP_SHARED, regc->fd, 0);
|
||||
regc_hdr = (REGC_HDR *)regc->base;
|
||||
|
||||
if ((int)regc->base == 1) {
|
||||
return WERR_FOOBAR;
|
||||
}
|
||||
|
||||
if ((regc_id = IVAL(®c_hdr->REGC_ID,0)) != str_to_dword("REGC")) {
|
||||
DEBUG(0, ("Unrecognized Windows 95 registry header id: %0X, %s\n",
|
||||
regc_id, location));
|
||||
return WERR_FOOBAR;
|
||||
}
|
||||
|
||||
rgkn_hdr = (RGKN_HDR *)regc->base + sizeof(REGC_HDR);
|
||||
|
||||
if ((rgkn_id = IVAL(&rgkn_hdr->RGKN_ID,0)) != str_to_dword("RGKN")) {
|
||||
DEBUG(0, ("Unrecognized Windows 95 registry key index id: %0X, %s\n",
|
||||
rgkn_id, location));
|
||||
return WERR_FOOBAR;
|
||||
}
|
||||
|
||||
//rgkn = (RGKN_KEY *)regc->base + sizeof(REGC_HDR) + sizeof(RGKN_HDR);
|
||||
|
||||
/* FIXME */
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static WERROR w95_close_reg(REG_HANDLE *h)
|
||||
{
|
||||
REGC *regc = h->backend_data;
|
||||
if (regc->base) munmap(regc->base, regc->sbuf.st_size);
|
||||
regc->base = NULL;
|
||||
close(regc->fd);
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static struct registry_ops reg_backend_w95 = {
|
||||
.name = "w95",
|
||||
.open_registry = w95_open_reg,
|
||||
.close_registry = w95_close_reg,
|
||||
};
|
||||
|
||||
NTSTATUS reg_w95_init(void)
|
||||
{
|
||||
return register_backend("registry", ®_backend_w95);
|
||||
}
|
@ -84,6 +84,7 @@ static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath *
|
||||
g_assert(k);
|
||||
|
||||
for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(k, i, &sub)); i++) {
|
||||
int count;
|
||||
/* 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
|
||||
@ -103,14 +104,8 @@ static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath *
|
||||
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_IS_OK(reg_key_num_subkeys(sub, &count)) && count > 0)
|
||||
gtk_tree_store_append(store_keys, &tmpiter, &iter);
|
||||
}
|
||||
|
||||
if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) gtk_show_werror(error);
|
||||
|
@ -493,6 +493,11 @@ static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
|
||||
ret = False;
|
||||
}
|
||||
|
||||
if (!test_FlushKey(p, mem_ctx, &handle)) {
|
||||
printf("FlushKey failed\n");
|
||||
ret = False;
|
||||
}
|
||||
|
||||
if (!test_OpenKey(p, mem_ctx, &handle, "spottyfoot", &newhandle)) {
|
||||
printf("CreateKey failed (OpenKey after Create didn't work)\n");
|
||||
ret = False;
|
||||
@ -503,6 +508,11 @@ static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
|
||||
ret = False;
|
||||
}
|
||||
|
||||
if (!test_FlushKey(p, mem_ctx, &handle)) {
|
||||
printf("FlushKey failed\n");
|
||||
ret = False;
|
||||
}
|
||||
|
||||
if (test_OpenKey(p, mem_ctx, &handle, "spottyfoot", &newhandle)) {
|
||||
printf("DeleteKey failed (OpenKey after Delete didn't work)\n");
|
||||
ret = False;
|
||||
@ -513,12 +523,6 @@ static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
|
||||
ret = False;
|
||||
}
|
||||
|
||||
if (!test_FlushKey(p, mem_ctx, &handle)) {
|
||||
printf("FlushKey failed\n");
|
||||
ret = False;
|
||||
}
|
||||
|
||||
|
||||
/* The HKCR hive has a very large fanout */
|
||||
|
||||
if (open_fn == test_OpenHKCR) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user