svn commit: samba r24179 - in branches/4.0-regwrite: . source/lib/policy source/lib/registry

jelmer at samba.org jelmer at samba.org
Sat Aug 4 13:13:44 GMT 2007


Author: jelmer
Date: 2007-08-04 13:13:40 +0000 (Sat, 04 Aug 2007)
New Revision: 24179

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=24179

Log:
Improvements towards write support for regf by Jelmer Vernooij and me.

Modified:
   branches/4.0-regwrite/
   branches/4.0-regwrite/source/lib/policy/parse_adm.y
   branches/4.0-regwrite/source/lib/registry/reg_backend_regf.c
   branches/4.0-regwrite/source/lib/registry/regf.idl


Changeset:

Property changes on: branches/4.0-regwrite
___________________________________________________________________
Name: bzr:revision-info
   - timestamp: Sun 2007-01-14 14:43:18.105000019 +0100
committer: Wilco Baan Hofman <wilco at baanhofman.nl>
properties: 
	branch-nick: 4.0-regwrite
	rebase-of: wilco at baanhofman.nl-20070114134318-79ylyc0gzh43xhqi

   + timestamp: Sun 2007-01-14 16:15:41.398000002 +0100
committer: Wilco Baan Hofman <wilco at baanhofman.nl>
properties: 
	branch-nick: 4.0-regwrite
	rebase-of: wilco at baanhofman.nl-20070114151541-6adzkudwihn30k9j

Name: bzr:file-ids
   - source/script/tests/test_blackbox.sh	20748 at 0c0555d6-39d7-0310-84fc-f1cc0bd64818:branches%2FSAMBA_4_0:source%2Fscript%2Ftests%2Ftest_blackbox.sh
testprogs/blackbox	20746 at 0c0555d6-39d7-0310-84fc-f1cc0bd64818:branches%2FSAMBA_4_0:testprogs%2Fblackbox
testprogs/blackbox/test_smbclient.sh	20746 at 0c0555d6-39d7-0310-84fc-f1cc0bd64818:branches%2FSAMBA_4_0:testprogs%2Fblackbox%2Ftest_smbclient.sh
testprogs/blackbox/test_cifsdd.sh	20747 at 0c0555d6-39d7-0310-84fc-f1cc0bd64818:branches%2FSAMBA_4_0:testprogs%2Fblackbox%2Ftest_cifsdd.sh

   + 
Name: bzr:revision-id:v3-trunk0
   - 11140 jelmer at samba.org-20070113195019-yrx40nap220myng0-svn3-upgrade
11142 jelmer at samba.org-20070113195431-nshumfy5z00cpnaj-svn3-upgrade
11143 jelmer at samba.org-20070113195555-am0swaxzsoxp05p0-svn3-upgrade
11144 wilco at baanhofman.nl-20070114042604-b7pwqobkrbmlbp8p-svn3-upgrade
11145 wilco at baanhofman.nl-20070114042644-fa3gbnlhall7nkry-svn3-upgrade
11146 wilco at baanhofman.nl-20070114042712-7ueqyvk12ki1frc5-svn3-upgrade
11147 wilco at baanhofman.nl-20070114042737-pwu8etpcs7lmwsms-svn3-upgrade
11148 wilco at baanhofman.nl-20070114043501-7g3vsn55rrr643z6-svn3-upgrade
11149 wilco at baanhofman.nl-20070114061526-fpg1tdt07virwgdk-svn3-upgrade
11150 wilco at baanhofman.nl-20070114133602-npguwp5mbuki5qlp-svn3-upgrade
11151 wilco at baanhofman.nl-20070114134318-79ylyc0gzh43xhqi-svn3-upgrade

   + 11140 jelmer at samba.org-20070113195019-yrx40nap220myng0-svn3-upgrade
11142 jelmer at samba.org-20070113195431-nshumfy5z00cpnaj-svn3-upgrade
11143 jelmer at samba.org-20070113195555-am0swaxzsoxp05p0-svn3-upgrade
11144 wilco at baanhofman.nl-20070114042604-b7pwqobkrbmlbp8p-svn3-upgrade
11145 wilco at baanhofman.nl-20070114042644-fa3gbnlhall7nkry-svn3-upgrade
11146 wilco at baanhofman.nl-20070114042712-7ueqyvk12ki1frc5-svn3-upgrade
11147 wilco at baanhofman.nl-20070114042737-pwu8etpcs7lmwsms-svn3-upgrade
11148 wilco at baanhofman.nl-20070114043501-7g3vsn55rrr643z6-svn3-upgrade
11149 wilco at baanhofman.nl-20070114061526-fpg1tdt07virwgdk-svn3-upgrade
11150 wilco at baanhofman.nl-20070114133602-npguwp5mbuki5qlp-svn3-upgrade
11151 wilco at baanhofman.nl-20070114134318-79ylyc0gzh43xhqi-svn3-upgrade
11152 wilco at baanhofman.nl-20070114151541-6adzkudwihn30k9j-svn3-upgrade


Modified: branches/4.0-regwrite/source/lib/policy/parse_adm.y
===================================================================
--- branches/4.0-regwrite/source/lib/policy/parse_adm.y	2007-08-04 13:13:30 UTC (rev 24178)
+++ branches/4.0-regwrite/source/lib/policy/parse_adm.y	2007-08-04 13:13:40 UTC (rev 24179)
@@ -23,8 +23,10 @@
 
 %{
 #include "config.h"
-
+void error_message (const char *format, ...);
+int yyparse (void);
 void yyerror (const char *s);
+extern int yylex (void);
 
 %}
 

Modified: branches/4.0-regwrite/source/lib/registry/reg_backend_regf.c
===================================================================
--- branches/4.0-regwrite/source/lib/registry/reg_backend_regf.c	2007-08-04 13:13:30 UTC (rev 24178)
+++ branches/4.0-regwrite/source/lib/registry/reg_backend_regf.c	2007-08-04 13:13:40 UTC (rev 24179)
@@ -30,6 +30,7 @@
  *  - Locking
  */
 
+static WERROR regf_save_hbin(struct registry_hive *hive);
 /*
  * Read HBIN blocks into memory
  */
@@ -40,6 +41,11 @@
 	struct regf_hdr *header;
 };
 
+struct regf_key_data {
+	uint32_t offset;
+	struct nk_block *nk;
+};
+
 static struct hbin_block *hbin_by_offset (const struct regf_data *data, uint32_t offset, uint32_t *rel_offset)
 {
 	int i;
@@ -48,7 +54,7 @@
 		if (offset >= data->hbins[i]->offset_from_first && 
 			offset < data->hbins[i]->offset_from_first+
 					 data->hbins[i]->offset_to_next) {
-			if (rel_offset)
+			if (rel_offset != NULL)
 				*rel_offset = offset - data->hbins[i]->offset_from_first - 0x20;
 			return data->hbins[i];
 		}
@@ -148,10 +154,10 @@
 
 	for (i = 0; (hbin = data->hbins[i]); i++) {
 		int j;
-		uint32_t my_size;
+		int32_t my_size;
 		for (j = 0; j < hbin->offset_to_next-0x20; j+= my_size) {
 			uint32_t header = IVAL(hbin->data, j + 4);
-			my_size = IVAL(hbin->data, j);
+			my_size = IVALS(hbin->data, j);
 
 			if (my_size == 0x0) {
 				DEBUG(0, ("Invalid zero-length block! File is corrupt.\n"));
@@ -162,9 +168,9 @@
 				DEBUG(0, ("Encountered non-aligned block!\n"));
 			}
 
-			if (my_size & 0x80000000) { /* Used... */
-				my_size = (my_size ^ 0xffffffff) + 1;
-			} else if (my_size == size) { /* exact match */
+			if (my_size < 0) { /* Used... */
+				my_size = -my_size;
+			} else if (-my_size == size) { /* exact match */
 				rel_offset = j;
 				DEBUG(4, ("Found free block of exact size %d in middle of HBIN\n", size));
 				break;
@@ -219,7 +225,7 @@
 	}
 
 	/* Set size and mark as used */
-	SIVAL(hbin->data, rel_offset, size | 0x80000000);
+	SIVAL(hbin->data, rel_offset, -size);
 
 	ret.data = hbin->data + rel_offset + 0x4; /* Skip past length */
 	ret.length = size - 0x4;
@@ -265,7 +271,7 @@
 /* Free existing data */
 static void hbin_free (struct regf_data *data, uint32_t offset)
 {
-	uint32_t size;
+	int32_t size;
 	uint32_t rel_offset;
 	struct hbin_block *hbin;
 
@@ -277,28 +283,28 @@
 		return;
 	
 	/* Get original size */
-	size = IVAL(hbin->data, rel_offset);
+	size = IVALS(hbin->data, rel_offset);
 
-	if (!(size & 0x80000000)) {
+	if (size > 0) {
 		DEBUG(1, ("Trying to free already freed block at 0x%04x\n", offset));
 		return;
 	}
 
 	/* Mark block as free */
-	SIVAL(hbin->data, rel_offset, size &~ 0x80000000);
+	SIVALS(hbin->data, rel_offset, -size);
 }
 
-/* Store a data blob data was already stored, but hsa 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)
 {
 	uint32_t rel_offset;
 	struct hbin_block *hbin = hbin_by_offset(data, orig_offset, &rel_offset);
-	uint32_t my_size;
-	uint32_t orig_size;
-	uint32_t needed_size;
-	uint32_t possible_size;
+	int32_t my_size;
+	int32_t orig_size;
+	int32_t needed_size;
+	int32_t possible_size;
 	int i;
 
 	SMB_ASSERT(orig_offset > 0);
@@ -307,7 +313,7 @@
 		return hbin_store(data, blob);
 
 	/* Get original size */
-	orig_size = IVAL(hbin->data, rel_offset);
+	orig_size = IVALS(hbin->data, rel_offset);
 
 	needed_size = blob.length + 4; /* Add uint32 containing length */
 	needed_size = (needed_size + 7) & ~7; /* Align */
@@ -321,14 +327,12 @@
 	possible_size = orig_size;
 
 	/* Check if it can be combined with the next few free records */
-	for (i = rel_offset; 
-		 i < hbin->offset_to_next - 0x20; 
-		 i += my_size) {
+	for (i = rel_offset; i < hbin->offset_to_next - 0x20; i += my_size) {
 		uint32_t header;
-		if (IVAL(hbin->data, i) & 0x80000000) /* Used */
+		if (IVALS(hbin->data, i) < 0) /* Used */
 			break;
 
-		my_size = IVAL(hbin->data, i);
+		my_size = IVALS(hbin->data, i);
 		header = IVAL(hbin->data, i + 4);
 		if (header == 0xffffffff) {
 			possible_size = hbin->offset_to_next - 0x20 - rel_offset;
@@ -340,7 +344,7 @@
 		}
 
 		if (possible_size >= blob.length) {
-			SIVAL(hbin->data, rel_offset, possible_size);
+			SIVAL(hbin->data, rel_offset, -possible_size);
 			memcpy(hbin->data + rel_offset + 0x4, blob.data, blob.length);
 			return orig_offset;
 		}
@@ -372,18 +376,18 @@
 
 static WERROR regf_num_subkeys (const struct registry_key *key, uint32_t *count)
 {
-	struct nk_block *nk = key->backend_data;
+	struct regf_key_data *private_data = key->backend_data;
 
-	*count = nk->num_subkeys;
+	*count = private_data->nk->num_subkeys;
 	
 	return WERR_OK;
 }
 
 static WERROR regf_num_values (const struct registry_key *key, uint32_t *count)
 {
-	struct nk_block *nk = key->backend_data;
+	struct regf_key_data *private_data = key->backend_data;
 
-	*count = nk->num_values;
+	*count = private_data->nk->num_values;
 
 	return WERR_OK;
 }
@@ -392,9 +396,13 @@
 {
 	struct registry_key *ret;
 	struct nk_block *nk;
+	struct regf_key_data *private_data;
 
 	ret = talloc_zero(ctx, struct registry_key);
+	private_data = talloc_zero(ret, struct regf_key_data);
+	private_data->offset = offset;
 	nk = talloc(ret, struct nk_block);
+	private_data->nk = nk;
 	if (!hbin_get_tdr(regf, offset, nk, (tdr_pull_fn_t)tdr_pull_nk_block, nk)) {
 		DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset));
 		return NULL;
@@ -413,29 +421,29 @@
 		DATA_BLOB data = hbin_get(regf, nk->clsname_offset);
 		ret->class_name = talloc_strndup(ret, (char*)data.data, nk->clsname_length);
 	}
-	ret->backend_data = nk;
+	ret->backend_data = private_data;
 
 	return ret;
 }
 
 static WERROR regf_get_value (TALLOC_CTX *ctx, const struct registry_key *key, int idx, struct registry_value **ret)
 {
-	struct nk_block *nk = key->backend_data;
+	struct regf_key_data *private_data = key->backend_data;
 	struct vk_block *vk;
 	struct regf_data *regf = key->hive->backend_data;
 	uint32_t vk_offset;
 	DATA_BLOB data;
 
-	if (idx >= nk->num_values)
+	if (idx >= private_data->nk->num_values)
 		return WERR_NO_MORE_ITEMS;
 
-	data = hbin_get(regf, nk->values_offset);
+	data = hbin_get(regf, private_data->nk->values_offset);
 	if (!data.data) {
 		DEBUG(0, ("Unable to find value list\n"));
 		return WERR_GENERAL_FAILURE;
 	}
 
-	if (data.length < nk->num_values * 4) {
+	if (data.length < private_data->nk->num_values * 4) {
 		DEBUG(1, ("Value counts mismatch\n"));
 	}
 
@@ -474,7 +482,8 @@
 static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, const struct registry_key *key, int idx, struct registry_key **ret)
 {
 	DATA_BLOB data;
-	struct nk_block *nk = key->backend_data;
+	struct regf_key_data *private_data = key->backend_data;
+	struct nk_block *nk = private_data->nk;
 	uint32_t key_off=0;
 
 	if (idx >= nk->num_subkeys)
@@ -663,7 +672,8 @@
 static WERROR regf_get_subkey_by_name (TALLOC_CTX *ctx, const struct registry_key *key, const char *name, struct registry_key **ret)
 {
 	DATA_BLOB data;
-	struct nk_block *nk = key->backend_data;
+	struct regf_key_data *private_data = key->backend_data;
+	struct nk_block *nk = private_data->nk;
 	uint32_t key_off = 0;
 
 	data = hbin_get(key->hive->backend_data, nk->subkeys_offset);
@@ -871,12 +881,12 @@
 
 static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, struct security_descriptor **sd)
 {
-	struct nk_block *nk = key->backend_data;
+	struct regf_key_data *private_data = key->backend_data;
 	struct sk_block sk;
 	struct regf_data *regf = key->hive->backend_data;
 	DATA_BLOB data;
 
-	if (!hbin_get_tdr(regf, nk->sk_offset, ctx, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) {
+	if (!hbin_get_tdr(regf, private_data->nk->sk_offset, ctx, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) {
 		DEBUG(0, ("Unable to find security descriptor\n"));
 		return WERR_GENERAL_FAILURE;
 	}
@@ -938,11 +948,11 @@
 
 static WERROR regf_del_key (const struct registry_key *parent, const char *name)
 {
-	struct nk_block *nk = parent->backend_data;
+	struct regf_key_data *private_data = parent->backend_data;
 
-	SMB_ASSERT(nk);
+	SMB_ASSERT(private_data);
 	
-	if (nk->subkeys_offset == -1) 
+	if (private_data->nk->subkeys_offset == -1) 
 		return WERR_BADFILE;
 
 	/* FIXME */
@@ -950,9 +960,11 @@
 	return WERR_NOT_SUPPORTED;
 }
 
-static WERROR regf_add_key (TALLOC_CTX *ctx, const struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *sec_desc, struct registry_key **ret)
+static WERROR regf_add_key (TALLOC_CTX *ctx, const struct registry_key *parent, const char *name, 
+                            uint32_t access_mask, struct security_descriptor *sec_desc, struct registry_key **ret)
 {
-	struct nk_block *parent_nk = parent->backend_data, nk;
+	struct regf_key_data *private_data = parent->backend_data;
+	struct nk_block *parent_nk = private_data->nk, nk;
 	struct regf_data *regf = parent->hive->backend_data;
 	uint32_t offset;
 
@@ -960,13 +972,13 @@
 	nk.type = REG_SUB_KEY;
 	unix_to_nt_time(&nk.last_change, time(NULL));
 	nk.uk1 = 0;
-	nk.parent_offset = 0; /* FIXME */
+	nk.parent_offset = private_data->offset;
 	nk.num_subkeys = 0;
 	nk.uk2 = 0;
 	nk.subkeys_offset = -1;
 	nk.unknown_offset = -1;
 	nk.num_values = 0;
-	nk.sk_offset = 0;
+	nk.sk_offset = -1;
 	memset(nk.unk3, 0, 5);
 	nk.clsname_offset = -1;
 	nk.clsname_length = 0;
@@ -974,16 +986,17 @@
 	
 	offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_nk_block, &nk);
 
-	parent_nk->subkeys_offset = lf_add_entry(regf, parent_nk->subkeys_offset, name, nk.parent_offset);
-
+	/* FIXME: Support other formats than just 'lf' */
+	parent_nk->subkeys_offset = lf_add_entry(regf, parent_nk->subkeys_offset, name, offset);
 	parent_nk->num_subkeys++;
 
+	/* Since the subkey offset of the parent can change, store it again */
 	hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, nk.parent_offset, parent_nk);
 
 	*ret = regf_get_key(ctx, regf, offset);
 
 	/* FIXME: Set sec desc ! */
-	return WERR_OK;
+	return regf_save_hbin(parent->hive);
 }
 
 static WERROR regf_set_value (const struct registry_key *key, const char *name, uint32_t type, const DATA_BLOB data)
@@ -993,28 +1006,35 @@
 	return WERR_NOT_SUPPORTED;
 }
 
-#if 0 /* Unused */
-
-static WERROR regf_save_hbin(struct registry_hive *hive, struct hbin_block *hbin)
+static WERROR regf_save_hbin(struct registry_hive *hive)
 {
 	struct regf_data *regf = hive->backend_data;
+	int i;
 
-	/* go to right offset */
-	if (lseek(regf->fd, SEEK_SET, regf->header->data_offset + hbin->offset_from_first) == -1) {
+	if (lseek(regf->fd, SEEK_SET, 0) == -1) {
 		DEBUG(0, ("Error lseeking in regf file\n"));
 		return WERR_GENERAL_FAILURE;
 	}
 
-	if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, (tdr_push_fn_t)tdr_push_hbin_block, hbin))) {
-		DEBUG(0, ("Error writing HBIN block\n"));	
+	if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, (tdr_push_fn_t)tdr_push_regf_hdr, regf->header))) {
+		DEBUG(0, ("Error writing registry file header\n"));
 		return WERR_GENERAL_FAILURE;
 	}
 
+	if (lseek(regf->fd, SEEK_SET, 0x1000) == -1) {
+		DEBUG(0, ("Error lseeking to 0x1000 in regf file\n"));
+		return WERR_GENERAL_FAILURE;
+	}
+	for (i = 0; regf->hbins[i]; i++) {
+		if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, (tdr_push_fn_t)tdr_push_hbin_block, regf->hbins[i]))) {
+			DEBUG(0, ("Error writing HBIN block\n"));	
+			return WERR_GENERAL_FAILURE;
+		}
+	}
+
 	return WERR_OK;
 }
 
-#endif
-
 static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key)
 {
 	struct regf_data *regf;

Modified: branches/4.0-regwrite/source/lib/registry/regf.idl
===================================================================
--- branches/4.0-regwrite/source/lib/registry/regf.idl	2007-08-04 13:13:30 UTC (rev 24178)
+++ branches/4.0-regwrite/source/lib/registry/regf.idl	2007-08-04 13:13:40 UTC (rev 24179)
@@ -66,7 +66,7 @@
 		uint8 data[offset_to_next-0x20]; 
 		/* data is filled with:
 		 	uint32 length; 			
-				Negative if in used, positive otherwise
+				Negative if in use, positive otherwise
 				Always a multiple of 8
 			uint8_t data[length];  
 				Free space marker if 0xffffffff



More information about the samba-cvs mailing list