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 = &reg_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(&regf_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