1
0
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:
Jelmer Vernooij 2004-04-11 23:16:47 +00:00 committed by Gerald (Jerry) Carter
parent c60c5ebb91
commit 639afabf40
9 changed files with 317 additions and 198 deletions

View File

@ -214,7 +214,11 @@ WERROR reg_key_num_subkeys(REG_KEY *key, int *count)
{ {
if(!key) return WERR_INVALID_PARAM; 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) if(!key->cache_subkeys)
key->handle->functions->fetch_subkeys(key, &key->cache_subkeys_count, &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 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) 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) WERROR reg_key_get_value_by_name(REG_KEY *key, const char *name, REG_VAL **val)
{ {
int i, max; int i;
REG_VAL *ret = NULL;
WERROR error = WERR_OK; WERROR error = WERR_OK;
if(!key) return WERR_INVALID_PARAM; 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) WERROR reg_key_del_recursive(REG_KEY *key)
{ {
BOOL succeed = True;
WERROR error = WERR_OK; WERROR error = WERR_OK;
int i; int i;
@ -543,3 +558,27 @@ WERROR reg_save(REG_HANDLE *h, const char *location)
/* FIXME */ /* FIXME */
return WERR_NOT_SUPPORTED; 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;
}

View File

@ -58,8 +58,8 @@ struct reg_val_s {
}; };
/* FIXME */ /* FIXME */
typedef void (*key_notification_function) (); typedef void (*key_notification_function) (void);
typedef void (*value_notification_function) (); typedef void (*value_notification_function) (void);
/* /*

View File

@ -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])]) 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_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_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_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_gconf, REG, NOT, lib/registry/reg_backend_gconf/reg_backend_gconf.o, [], [$GCONF_LIBS])

View File

@ -21,7 +21,7 @@
#include "includes.h" #include "includes.h"
#include "lib/registry/common/registry.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; char *path;
int ret; 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); path = reg_path_win2unix(path);
ret = mkdir(path, 0700); ret = mkdir(path, 0700);
SAFE_FREE(path); SAFE_FREE(path);
if(ret == 0)return WERR_OK; if(ret == 0)return WERR_OK; /* FIXME */
return WERR_INVALID_PARAM; 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 && if(e->d_type == DT_DIR &&
strcmp(e->d_name, ".") && strcmp(e->d_name, ".") &&
strcmp(e->d_name, "..")) { strcmp(e->d_name, "..")) {
char *newfullpath;
ar[(*count)] = reg_key_new_rel(e->d_name, k, NULL); 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); ar[(*count)]->backend_data = talloc_asprintf(ar[*count]->mem_ctx, "%s/%s", fullpath, e->d_name);
if(ar[(*count)])(*count)++; 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; 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 */ /* FIXME */
return WERR_NOT_SUPPORTED; return WERR_NOT_SUPPORTED;
} }

View File

@ -165,7 +165,7 @@ Offset Size Contents
To determine the number of values, you have to look at the owner-nk-record! To determine the number of values, you have to look at the owner-nk-record!
Der vk-Record The vk-Record
============= =============
Offset Size Contents Offset Size Contents
0x0000 Word ID: ASCII-"vk" = 0x6B76 0x0000 Word ID: ASCII-"vk" = 0x6B76
@ -473,7 +473,7 @@ typedef struct regf_struct_s {
int fd; int fd;
struct stat sbuf; struct stat sbuf;
char *base; char *base;
int modified; BOOL modified;
NTTIME last_mod_time; NTTIME last_mod_time;
NK_HDR *first_key; NK_HDR *first_key;
int sk_count, sk_map_size; 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 * keys when we are preparing to write them to a file
*/ */
HBIN_BLK *blk_head, *blk_tail, *free_space; HBIN_BLK *blk_head, *blk_tail, *free_space;
TALLOC_CTX *mem_ctx;
} REGF; } REGF;
DWORD str_to_dword(const char *a) { 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]; char val_name[1024];
REGF *regf = parent->handle->backend_data; REGF *regf = parent->handle->backend_data;
int nam_len, dat_len, flag, dat_type, dat_off, vk_id; int nam_len, dat_len, flag, dat_type, dat_off, vk_id;
const char *val_type;
REG_VAL *tmp = NULL; REG_VAL *tmp = NULL;
if (!vk_hdr) return WERR_INVALID_PARAM; 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; REGF *regf = h->backend_data;
REG_KEY *tmp = NULL, *own; 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; unsigned int nk_id;
SK_HDR *sk_hdr; SK_HDR *sk_hdr;
int type; 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); 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); clsname_len = SVAL(&nk_hdr->clsnam_len,0);
/* /*
* The value of -size should be ge * 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 -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 * the name in the structure. clsname_len is the length of the thing
* pointed to by clsnam_off * 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, ("Incorrect NK_HDR size: %d, %0X\n", -size, (int)nk_hdr));
DEBUG(0, ("Sizeof NK_HDR: %d, name_len %d, clsname_len %d\n", 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; 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 */ /* 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); strncpy(key_name, nk_hdr->key_nam, namlen);
key_name[name_len] = '\0'; key_name[namlen] = '\0';
type = (SVAL(&nk_hdr->type,0)==0x2C?REG_ROOT_KEY:REG_SUB_KEY); type = (SVAL(&nk_hdr->type,0)==0x2C?REG_ROOT_KEY:REG_SUB_KEY);
if(type == REG_ROOT_KEY && parent) { 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); clsnamep = (smb_ucs2_t *)LOCN(regf->base, clsnam_off);
DEBUG(2, ("Class Name Offset: %0X\n", 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)); DEBUGADD(2,(" Class Name: %s\n", cls_name));
@ -1572,22 +1570,17 @@ static WERROR nt_close_registry (REG_HANDLE *h)
regf->base = NULL; regf->base = NULL;
close(regf->fd); /* Ignore the error :-) */ close(regf->fd); /* Ignore the error :-) */
free(regf->sk_map);
regf->sk_count = regf->sk_map_size = 0;
free(regf);
return WERR_OK; return WERR_OK;
} }
static WERROR nt_open_registry (REG_HANDLE *h, const char *location, const char *credentials) 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; REGF_HDR *regf_hdr;
unsigned int regf_id, hbin_id; unsigned int regf_id, hbin_id;
HBIN_HDR *hbin_hdr; HBIN_HDR *hbin_hdr;
memset(regf, 0, sizeof(REGF)); memset(regf, 0, sizeof(REGF));
regf->mem_ctx = talloc_init("regf");
regf->owner_sid_str = credentials; regf->owner_sid_str = credentials;
h->backend_data = regf; h->backend_data = regf;

View File

@ -20,6 +20,13 @@
#include "includes.h" #include "includes.h"
#include "lib/registry/common/registry.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) static void init_winreg_String(struct winreg_String *name, const char *s)
{ {
name->name = 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) \ #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_Open ## u r; \
struct winreg_OpenUnknown unknown; \ struct winreg_OpenUnknown unknown; \
struct policy_handle *hnd = malloc(sizeof(struct policy_handle)); \ struct policy_handle *hnd = malloc(sizeof(struct policy_handle)); \
@ -66,7 +72,7 @@ struct rpc_data {
}; };
struct { struct {
char *name; const char *name;
struct policy_handle *(*open) (struct dcerpc_pipe *p, REG_HANDLE *h); struct policy_handle *(*open) (struct dcerpc_pipe *p, REG_HANDLE *h);
} known_hives[] = { } known_hives[] = {
{ "HKEY_LOCAL_MACHINE", open_HKLM }, { "HKEY_LOCAL_MACHINE", open_HKLM },
@ -98,7 +104,6 @@ static WERROR rpc_open_registry(REG_HANDLE *h, const char *location, const char
lp_workgroup(), lp_workgroup(),
user, pass); user, pass);
h->backend_data = mydata; h->backend_data = mydata;
return ntstatus_to_werror(status); return ntstatus_to_werror(status);
@ -118,64 +123,66 @@ static WERROR rpc_close_registry(REG_HANDLE *h)
return WERR_OK; 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; struct policy_handle *key_handle, *hive = NULL;
int i = 0;
struct rpc_data *mydata = h->backend_data;
struct policy_handle *hive = NULL;
char *end = strchr(path+1, '\\');
NTSTATUS status;
struct winreg_OpenKey r; struct winreg_OpenKey r;
struct policy_handle *key_handle = talloc(h->mem_ctx, sizeof(struct policy_handle)); int i;
TALLOC_CTX *mem_ctx; struct rpc_data *mydata = k->handle->backend_data;
char *realkeyname, *hivename;
if(end) hivename = strndup(path+1, end-path-1); if(k->backend_data) return WERR_OK;
else hivename = strdup(path+1);
/* 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++) { for(i = 0; known_hives[i].name; i++) {
if(!strcmp(hivename, known_hives[i].name)) { 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]; hive = mydata->hives[i];
break;
} }
} }
if(!hive) { if(!hive) {
DEBUG(0, ("No such hive: %s\n", hivename)); 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)); memset(&r, 0, sizeof(struct winreg_OpenKey));
r.in.handle = hive; 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.unknown = 0x00000000;
r.in.access_mask = 0x02000000; r.in.access_mask = 0x02000000;
r.out.handle = key_handle; 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) static WERROR rpc_open_key(REG_HANDLE *h, const char *name, REG_KEY **key)
{ {
struct policy_handle *pol = rpc_get_key_handle(h, name); WERROR error;
if(!pol) return WERR_DEST_NOT_FOUND; *key = reg_key_new_abs(name, h, NULL);
*key = reg_key_new_abs(name, h, pol); return rpc_key_put_policy_handle(*key);
return WERR_OK;
} }
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_EnumKey r;
struct winreg_EnumKeyNameRequest keyname; 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 winreg_Time tm;
struct rpc_data *mydata = parent->handle->backend_data; struct rpc_data *mydata = parent->handle->backend_data;
int i; int i;
REG_KEY **ar = talloc(parent->mem_ctx, sizeof(REG_KEY *)); NTSTATUS status;
NTSTATUS status = NT_STATUS_OK;
TALLOC_CTX *mem_ctx; TALLOC_CTX *mem_ctx;
/* List the hives */ /* If parent is the root key, list the hives */
if(parent->backend_data == parent->handle->backend_data) { if(parent->backend_data == mydata) {
for(i = 0; known_hives[i].name; i++) { if(!known_hives[n].name) return WERR_NO_MORE_ITEMS;
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));
}
*subkeys = ar; *subkey = reg_key_new_rel(known_hives[n].name, parent, known_hives[n].open(mydata->pipe, parent->handle));
return WERR_OK; 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; r.in.handle = parent->backend_data;
keyname.unknown = 0x0000020a; keyname.unknown = 0x0000020a;
init_winreg_String(&keyname.key_name, NULL); 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.in.last_changed_time = &tm;
r.out.result.v = 0; 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 = n;
r.in.enum_index = i; r.in.unknown = r.out.unknown = 0x0414;
r.in.unknown = r.out.unknown = 0x0414; r.in.key_name_len = r.out.key_name_len = 0;
r.in.key_name_len = r.out.key_name_len = 0; status = dcerpc_winreg_EnumKey(mydata->pipe, parent->mem_ctx, &r);
status = dcerpc_winreg_EnumKey(mydata->pipe, parent->mem_ctx, &r); if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
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);
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 *));
}
} }
*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; 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 */ /* FIXME */
return WERR_NOT_SUPPORTED; 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) static WERROR rpc_del_key(REG_KEY *k)
{ {
NTSTATUS status; NTSTATUS status;
struct rpc_data *mydata = k->handle->backend_data; struct rpc_data *mydata = k->handle->backend_data;
struct winreg_DeleteKey r; struct winreg_DeleteKey r;
char *hivepath; REG_KEY *parent;
struct policy_handle *hive = get_hive(k); 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)); r.in.handle = parent->backend_data;
hivepath = strchr(reg_key_get_path(k), '\\'); init_winreg_String(&r.in.key, k->name);
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); status = dcerpc_winreg_DeleteKey(mydata->pipe, k->mem_ctx, &r);
return r.out.result; return r.out.result;
} }
static void rpc_close_key(REG_KEY *k)
{
reg_key_free(k);
}
static struct registry_ops reg_backend_rpc = { static struct registry_ops reg_backend_rpc = {
.name = "rpc", .name = "rpc",
.open_registry = rpc_open_registry, .open_registry = rpc_open_registry,
.close_registry = rpc_close_registry, .close_registry = rpc_close_registry,
.open_root_key = rpc_open_root, .open_root_key = rpc_open_root,
.open_key = rpc_open_key, .open_key = rpc_open_key,
.fetch_subkeys = rpc_fetch_subkeys, .get_subkey_by_index = rpc_get_subkey_by_index,
.fetch_values = rpc_fetch_values,
.add_key = rpc_add_key, .add_key = rpc_add_key,
.del_key = rpc_del_key, .del_key = rpc_del_key,
.free_key_backend_data = rpc_close_key,
}; };
NTSTATUS reg_rpc_init(void) NTSTATUS reg_rpc_init(void)

View 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, &regc->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(&regc_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", &reg_backend_w95);
}

View File

@ -84,6 +84,7 @@ static void expand_key(GtkTreeView *treeview, GtkTreeIter *parent, GtkTreePath *
g_assert(k); g_assert(k);
for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(k, i, &sub)); i++) { for(i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(k, i, &sub)); i++) {
int count;
/* Replace the blank child with the first directory entry /* Replace the blank child with the first directory entry
You may be tempted to remove the blank child node and then You may be tempted to remove the blank child node and then
append a new one. Don't. If you remove the blank child 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, sub,
-1); -1);
gtk_tree_store_append(store_keys, &tmpiter, &iter); if(W_ERROR_IS_OK(reg_key_num_subkeys(sub, &count)) && count > 0)
} 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); if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) gtk_show_werror(error);

View File

@ -493,6 +493,11 @@ static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
ret = False; ret = False;
} }
if (!test_FlushKey(p, mem_ctx, &handle)) {
printf("FlushKey failed\n");
ret = False;
}
if (!test_OpenKey(p, mem_ctx, &handle, "spottyfoot", &newhandle)) { if (!test_OpenKey(p, mem_ctx, &handle, "spottyfoot", &newhandle)) {
printf("CreateKey failed (OpenKey after Create didn't work)\n"); printf("CreateKey failed (OpenKey after Create didn't work)\n");
ret = False; ret = False;
@ -503,6 +508,11 @@ static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
ret = False; ret = False;
} }
if (!test_FlushKey(p, mem_ctx, &handle)) {
printf("FlushKey failed\n");
ret = False;
}
if (test_OpenKey(p, mem_ctx, &handle, "spottyfoot", &newhandle)) { if (test_OpenKey(p, mem_ctx, &handle, "spottyfoot", &newhandle)) {
printf("DeleteKey failed (OpenKey after Delete didn't work)\n"); printf("DeleteKey failed (OpenKey after Delete didn't work)\n");
ret = False; ret = False;
@ -513,12 +523,6 @@ static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, void *fn)
ret = False; ret = False;
} }
if (!test_FlushKey(p, mem_ctx, &handle)) {
printf("FlushKey failed\n");
ret = False;
}
/* The HKCR hive has a very large fanout */ /* The HKCR hive has a very large fanout */
if (open_fn == test_OpenHKCR) { if (open_fn == test_OpenHKCR) {