Rev 11189: Support creating regf files, run tests against regf. in
file:///home/jelmer/bzr.samba-old/4.0-regwrite/
Jelmer Vernooij
jelmer at samba.org
Wed Jun 13 17:37:59 GMT 2007
At file:///home/jelmer/bzr.samba-old/4.0-regwrite/
------------------------------------------------------------
revno: 11189
revision-id: jelmer at samba.org-20070612231137-i8mbl1sgmcfkb5vn
parent: jelmer at samba.org-20070612202736-meu8bltye0rberi6
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: 4.0-regwrite
timestamp: Wed 2007-06-13 01:11:37 +0200
message:
Support creating regf files, run tests against regf.
modified:
source/lib/registry/hive.h hive.h-20070423140448-w1nvzs8d2qxvyswz-1
source/lib/registry/regf.c svn-v2:4132 at 0c0555d6-39d7-0310-84fc-f1cc0bd64818-branches%2fSAMBA_4_0-source%2flib%2fregistry%2freg_backend_nt4.c
source/lib/registry/tests/hive.c hive.c-20070612151642-hsxkm8j4r69ej3px-1
=== modified file 'source/lib/registry/hive.h'
--- a/source/lib/registry/hive.h 2007-06-12 20:08:26 +0000
+++ b/source/lib/registry/hive.h 2007-06-12 23:11:37 +0000
@@ -167,6 +167,10 @@
WERROR reg_create_directory(TALLOC_CTX *parent_ctx,
const char *location, struct hive_key **key);
+WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx,
+ const char *location,
+ int major_version,
+ struct hive_key **key);
#endif /* __REGISTRY_HIVE_H__ */
=== modified file 'source/lib/registry/regf.c'
--- a/source/lib/registry/regf.c 2007-06-12 20:08:26 +0000
+++ b/source/lib/registry/regf.c 2007-06-12 23:11:37 +0000
@@ -26,6 +26,8 @@
#include "librpc/gen_ndr/ndr_security.h"
#include "librpc/gen_ndr/winreg.h"
+static struct hive_operations reg_backend_regf;
+
/**
* There are several places on the web where the REGF format is explained;
*
@@ -127,7 +129,7 @@
return ret;
}
-static BOOL hbin_get_tdr (struct regf_data *regf, uint32_t offset,
+static bool hbin_get_tdr (struct regf_data *regf, uint32_t offset,
TALLOC_CTX *ctx, tdr_pull_fn_t pull_fn, void *p)
{
struct tdr_pull pull;
@@ -137,15 +139,15 @@
pull.data = hbin_get(regf, offset);
if (!pull.data.data) {
DEBUG(1, ("Unable to get data at 0x%04x\n", offset));
- return False;
+ return false;
}
if (NT_STATUS_IS_ERR(pull_fn(&pull, ctx, p))) {
DEBUG(1, ("Error parsing record at 0x%04x using tdr\n", offset));
- return False;
+ return false;
}
- return True;
+ return true;
}
/* Allocate some new data */
@@ -306,7 +308,8 @@
SIVALS(hbin->data, rel_offset, size);
}
-/* Store a data blob data was already stored, but has changed in size
+/**
+ * Store a data blob data was already stored, but has changed in size
* Will try to save it at the current location if possible, otherwise
* does a free + store */
static uint32_t hbin_store_resize (struct regf_data *data, uint32_t orig_offset, DATA_BLOB blob)
@@ -370,7 +373,8 @@
return hbin_store(data, blob);
}
-static uint32_t hbin_store_tdr_resize (struct regf_data *regf, tdr_push_fn_t push_fn, uint32_t orig_offset, void *p)
+static uint32_t hbin_store_tdr_resize (struct regf_data *regf, tdr_push_fn_t push_fn,
+ uint32_t orig_offset, void *p)
{
struct tdr_push *push = talloc_zero(regf, struct tdr_push);
uint32_t ret;
@@ -387,7 +391,8 @@
return ret;
}
-static uint32_t regf_create_lh_hash(const char *name) {
+static uint32_t regf_create_lh_hash(const char *name)
+{
char *hash_name;
uint32_t ret = 0;
uint16_t i;
@@ -411,16 +416,21 @@
const struct regf_key_data *private_data =
(const struct regf_key_data *)key;
- *num_subkeys = private_data->nk->num_subkeys;
- *num_values = private_data->nk->num_values;
-
- if (private_data->nk->clsname_offset != -1) {
- DATA_BLOB data = hbin_get(private_data->hive,
- private_data->nk->clsname_offset);
- *classname = talloc_strndup(mem_ctx,
- (char*)data.data, private_data->nk->clsname_length);
- } else
- *classname = NULL;
+ if (num_subkeys != NULL)
+ *num_subkeys = private_data->nk->num_subkeys;
+
+ if (num_values != NULL)
+ *num_values = private_data->nk->num_values;
+
+ if (classname != NULL) {
+ if (private_data->nk->clsname_offset != -1) {
+ DATA_BLOB data = hbin_get(private_data->hive,
+ private_data->nk->clsname_offset);
+ *classname = talloc_strndup(mem_ctx,
+ (char*)data.data, private_data->nk->clsname_length);
+ } else
+ *classname = NULL;
+ }
/* FIXME: Last mod time */
@@ -435,6 +445,7 @@
struct regf_key_data *ret;
ret = talloc_zero(ctx, struct regf_key_data);
+ ret->key.ops = ®_backend_regf;
ret->hive = talloc_reference(ret, regf);
ret->offset = offset;
nk = talloc(ret, struct nk_block);
@@ -656,7 +667,8 @@
break;
} else {
DEBUG(0,("Unknown sublist in ri block\n"));
- SMB_ASSERT(0);
+
+ return WERR_GENERAL_FAILURE;
}
}
@@ -769,7 +781,7 @@
break;
}
if (key_off == 0)
- return WERR_DEST_NOT_FOUND;
+ return WERR_NOT_FOUND;
} else if (!strncmp((char *)data.data, "lf", 2)) {
struct lf_block lf;
struct tdr_pull pull;
@@ -799,7 +811,7 @@
break;
}
if (key_off == 0)
- return WERR_DEST_NOT_FOUND;
+ return WERR_NOT_FOUND;
} else if (!strncmp((char *)data.data, "lh", 2)) {
struct lh_block lh;
struct tdr_pull pull;
@@ -831,7 +843,7 @@
break;
}
if (key_off == 0)
- return WERR_DEST_NOT_FOUND;
+ return WERR_NOT_FOUND;
} else if (!strncmp((char *)data.data, "ri", 2)) {
struct ri_block ri;
struct tdr_pull pull;
@@ -900,7 +912,7 @@
break;
}
if (!key_off)
- return WERR_DEST_NOT_FOUND;
+ return WERR_NOT_FOUND;
} else {
DEBUG(0, ("Unknown subkey list type.\n"));
return WERR_GENERAL_FAILURE;
@@ -920,7 +932,7 @@
struct nk_block root;
DATA_BLOB data;
uint32_t sk_offset, cur_sk_offset;
- BOOL update_cur_sk = false;
+ bool update_cur_sk = false;
/* Get the root nk */
hbin_get_tdr(regf, regf->header->data_offset, regf,
@@ -1214,7 +1226,7 @@
struct li_block li;
struct tdr_pull pull;
uint16_t i;
- BOOL found_offset = false;
+ bool found_offset = false;
DEBUG(10, ("Subkeys in LI list\n"));
@@ -1255,7 +1267,7 @@
struct lf_block lf;
struct tdr_pull pull;
uint16_t i;
- BOOL found_offset = false;
+ bool found_offset = false;
DEBUG(10, ("Subkeys in LF list\n"));
@@ -1298,7 +1310,7 @@
struct lh_block lh;
struct tdr_pull pull;
uint16_t i;
- BOOL found_offset = false;
+ bool found_offset = false;
DEBUG(10, ("Subkeys in LH list\n"));
@@ -1356,7 +1368,7 @@
struct nk_block *nk = private_data->nk;
struct vk_block vk;
uint32_t vk_offset;
- BOOL found_offset = false;
+ bool found_offset = false;
DATA_BLOB values;
uint32_t i;
@@ -1415,15 +1427,15 @@
parent_nk = private_data->nk;
if (parent_nk->subkeys_offset == -1) {
- DEBUG(0, ("Subkey list is empty, this key cannot contain subkeys.\n"));
- return WERR_DEST_NOT_FOUND;
+ DEBUG(4, ("Subkey list is empty, this key cannot contain subkeys.\n"));
+ return WERR_NOT_FOUND;
}
/* Find the key */
if (!W_ERROR_IS_OK(regf_get_subkey_by_name(parent_nk, parent, name,
(struct hive_key **)&key))) {
DEBUG(0, ("Key '%s' not found\n", name));
- return WERR_DEST_NOT_FOUND;
+ return WERR_NOT_FOUND;
}
if (key->nk->subkeys_offset != -1 ||
@@ -1483,7 +1495,6 @@
nk.clsname_length = 0;
nk.key_name = name;
-
/* Get the security descriptor of the root key */
root = talloc_zero(ctx, struct nk_block);
if (!hbin_get_tdr(regf, regf->header->data_offset, root, (tdr_pull_fn_t)tdr_pull_nk_block, root)) {
@@ -1645,6 +1656,86 @@
return WERR_OK;
}
+WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx,
+ const char *location,
+ int minor_version,
+ struct hive_key **key)
+{
+ struct regf_data *regf;
+ struct regf_hdr *regf_hdr;
+ struct tdr_pull pull;
+ int i;
+ struct nk_block nk;
+ WERROR error;
+
+ regf = (struct regf_data *)talloc_zero(NULL, struct regf_data);
+
+ DEBUG(5, ("Attempting to create registry file\n"));
+
+ /* Get the header */
+ regf->fd = creat(location, 0644);
+
+ if (regf->fd == -1) {
+ DEBUG(0,("Could not create file: %s, %s\n", location,
+ strerror(errno)));
+ talloc_free(regf);
+ return WERR_GENERAL_FAILURE;
+ }
+
+ regf_hdr = talloc_zero(regf, struct regf_hdr);
+ regf_hdr->REGF_ID = "regf";
+ unix_to_nt_time(®f_hdr->modtime, time(NULL));
+ regf_hdr->version.major = 1;
+ regf_hdr->version.minor = minor_version;
+ regf_hdr->last_block = 0x1000; /* Block size */
+ regf_hdr->description = talloc_strdup(regf_hdr, "registry created by Samba 4");
+ regf_hdr->chksum = 0;
+
+ regf->header = regf_hdr;
+
+ pull.offset = 0x1000;
+
+ i = 0;
+ /* Read in all hbin blocks */
+ regf->hbins = talloc_array(regf, struct hbin_block *, 1);
+ regf->hbins[0] = NULL;
+
+ regf_hdr->data_offset = -1; /* FIXME */
+
+ nk.header = "nk";
+ nk.type = REG_SUB_KEY;
+ unix_to_nt_time(&nk.last_change, time(NULL));
+ nk.uk1 = 0;
+ nk.parent_offset = -1;
+ nk.num_subkeys = 0;
+ nk.uk2 = 0;
+ nk.subkeys_offset = -1;
+ nk.unknown_offset = -1;
+ nk.num_values = 0;
+ nk.values_offset = -1;
+ memset(nk.unk3, 0, 5);
+ nk.clsname_offset = -1; /* FIXME: fill in */
+ nk.clsname_length = 0;
+ nk.key_name = "";
+
+ nk.sk_offset = -1; /* FIXME: fill in */
+
+ /* Store the new nk key */
+ regf->header->data_offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_nk_block, &nk);
+
+ *key = (struct hive_key *)regf_get_key(parent_ctx, regf, regf->header->data_offset);
+
+ /* We can drop our own reference now that *key will have created one */
+ talloc_free(regf);
+
+ error = regf_save_hbin(regf);
+ if (!W_ERROR_IS_OK(error)) {
+ return error;
+ }
+
+ return WERR_OK;
+}
+
WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx,
const char *location, struct hive_key **key)
{
@@ -1691,11 +1782,6 @@
return WERR_GENERAL_FAILURE;
}
- DEBUG(1, ("Registry '%s' read. Version %d.%d.%d.%d\n",
- regf_hdr->description, regf_hdr->version.major,
- regf_hdr->version.minor, regf_hdr->version.release,
- regf_hdr->version.build));
-
/*
* Validate the header ...
*/
=== modified file 'source/lib/registry/tests/hive.c'
--- a/source/lib/registry/tests/hive.c 2007-06-12 20:27:36 +0000
+++ b/source/lib/registry/tests/hive.c 2007-06-12 23:11:37 +0000
@@ -119,7 +119,22 @@
*data = key;
return true;
-
+}
+
+static bool hive_setup_regf(struct torture_context *tctx, void **data)
+{
+ struct hive_key *key;
+ WERROR error;
+
+ error = reg_create_regf_file(tctx, "bla-regf", 5, &key);
+ if (!W_ERROR_IS_OK(error)) {
+ fprintf(stderr, "Unable to create new regf file\n");
+ return false;
+ }
+
+ *data = key;
+
+ return true;
}
static bool test_dir_refuses_null_location(struct torture_context *tctx)
@@ -147,5 +162,10 @@
tcase = torture_suite_add_tcase(suite, "ldb");
torture_tcase_set_fixture(tcase, hive_setup_ldb, NULL);
tcase_add_tests(tcase);
+
+ tcase = torture_suite_add_tcase(suite, "regf");
+ torture_tcase_set_fixture(tcase, hive_setup_regf, NULL);
+ tcase_add_tests(tcase);
+
return suite;
}
More information about the samba-cvs
mailing list