[SCM] Samba Shared Repository - branch v3-3-test updated - release-3-2-0pre2-2349-ga01d8fe

Michael Adam obnox at samba.org
Thu May 8 16:29:43 GMT 2008


The branch, v3-3-test has been updated
       via  a01d8fe5e89ca9620d23198b11e5ae605a97e5a6 (commit)
       via  3e89217e7edea5d7ec707de065d38b1921ed09af (commit)
       via  f7c8718dead63964481954a86427b8c05d15452c (commit)
       via  97592db08a109ffbea8c85b17686fa565c5cf8c9 (commit)
       via  a03a17365d64f7fe83a9f2e866c4f069a1dd1682 (commit)
       via  986030cdda828f7f87c5464d1837324b7033e27e (commit)
       via  55dd9bdd148fc942e15aacfe9f6b38b1a5c53158 (commit)
       via  52413c94fcc56c4055de4d35bea8a00646352122 (commit)
       via  c27d03bba842ecf99f23b22dc40fa7df33392fa0 (commit)
       via  347bab7f4aca7f26a88affea954a514c25735abf (commit)
       via  727e5a87c0ed3e0a2b9c2b508b1f81e6a6d26732 (commit)
       via  8a2c9d965d332ccd290089b92e9cfbba2413067c (commit)
       via  cf653e101d1b2c38b5e9de35732421a120213170 (commit)
       via  56a58690d3ab2e01ed28388bd59424d3abc7a0d3 (commit)
       via  978aef3a862065be856b36b38d72d581c3ac0ba1 (commit)
       via  477008367f0ac90624b4b751955cd3235b2c9cc6 (commit)
       via  04762cfcdba741afa457c96cd2f24e50cf83b15a (commit)
       via  2b25f480ba13ae125d081bab55ee3cbd3c4f425a (commit)
       via  23d7002b22ddcd2c52650463f31b72449aecaaaa (commit)
      from  ec9f8c4cf67c82f4665ed51e4fd0181f5f147ea0 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-3-test


- Log -----------------------------------------------------------------
commit a01d8fe5e89ca9620d23198b11e5ae605a97e5a6
Author: Michael Adam <obnox at samba.org>
Date:   Thu May 8 18:08:41 2008 +0200

    registry: add removal of secdesc of a key to regdb_store_keys().
    
    Michael

commit 3e89217e7edea5d7ec707de065d38b1921ed09af
Author: Michael Adam <obnox at samba.org>
Date:   Thu May 8 18:05:58 2008 +0200

    registry: add comments to removing lists in regdb_store_keys().
    
    Michael

commit f7c8718dead63964481954a86427b8c05d15452c
Author: Michael Adam <obnox at samba.org>
Date:   Thu May 8 17:59:32 2008 +0200

    registry: change order of deleting value and subkey lists in store_keys().
    
    Next step in the plan to make store_keys safer without transactions.
    
    Michael

commit 97592db08a109ffbea8c85b17686fa565c5cf8c9
Author: Michael Adam <obnox at samba.org>
Date:   Thu May 8 16:55:14 2008 +0200

    registry: adapt comment to first step in regdb_store_keys().
    
    Michael

commit a03a17365d64f7fe83a9f2e866c4f069a1dd1682
Author: Michael Adam <obnox at samba.org>
Date:   Thu May 8 16:32:51 2008 +0200

    registry: adapt comment of last step in regdb_store_keys().
    
    adding number (3) ....
    
    Michael

commit 986030cdda828f7f87c5464d1837324b7033e27e
Author: Michael Adam <obnox at samba.org>
Date:   Thu May 8 14:33:02 2008 +0200

    registry: regdb_store_keys: move storing the subkey list down after removing values.
    
    Michael

commit 55dd9bdd148fc942e15aacfe9f6b38b1a5c53158
Author: Michael Adam <obnox at samba.org>
Date:   Tue May 6 10:06:34 2008 +0200

    registry: add comment explaining workflow to make store_keys safe w/o transactions
    
    /*
     * Make the store operation as safe as possible without transactions:
     *
     * (1) For each subkey removed from ctr compared with old_subkeys:
     *
     *     (a) First delete the value db entry.
     *
     *     (b) Next delete the secdesc db record.
     *
     *     (c) Then delete the subkey list entry.
     *
     * (2) Now write the list of subkeys of the parent key,
     *     deleting removed entries and adding new ones.
     *
     * (3) Finally create the subkey list entries for the added keys.
     *
     * This way if we crash half-way in between deleting the subkeys
     * and storing the parent's list of subkeys, no old data can pop up
     * out of the blue when re-adding keys later on.
     */
    
    The workflow is going to be modified to meet this agendain the next commits.
    
    Michael

commit 52413c94fcc56c4055de4d35bea8a00646352122
Author: Michael Adam <obnox at samba.org>
Date:   Wed May 7 14:01:49 2008 +0200

    registry: check for existence of non base key in regdb_store_keys() before proceeding.
    
    Michael

commit c27d03bba842ecf99f23b22dc40fa7df33392fa0
Author: Michael Adam <obnox at samba.org>
Date:   Thu May 8 00:34:35 2008 +0200

    registry: add a function regdb_key_is_base_key() to check whether is composite.
    
    This partly duplicates code from regdb_key_exists(). Maybe refactor later.
    
    Michael

commit 347bab7f4aca7f26a88affea954a514c25735abf
Author: Michael Adam <obnox at samba.org>
Date:   Wed May 7 13:50:01 2008 +0200

    registry: check for existence of key in regdb_set_secdesc() before proceeding.
    
    Michael

commit 727e5a87c0ed3e0a2b9c2b508b1f81e6a6d26732
Author: Michael Adam <obnox at samba.org>
Date:   Wed May 7 13:48:28 2008 +0200

    registry: check for existence of key in regdb_get_secdesc() before proceeding.
    
    Michael

commit 8a2c9d965d332ccd290089b92e9cfbba2413067c
Author: Michael Adam <obnox at samba.org>
Date:   Wed May 7 13:45:02 2008 +0200

    registry: check for existence of key in regdb_store_values() before proceeding.
    
    Michael

commit cf653e101d1b2c38b5e9de35732421a120213170
Author: Michael Adam <obnox at samba.org>
Date:   Wed May 7 13:42:48 2008 +0200

    registry: check for existence of key in regdb_fetch_keys() before proceeding.
    
    Michael

commit 56a58690d3ab2e01ed28388bd59424d3abc7a0d3
Author: Michael Adam <obnox at samba.org>
Date:   Wed May 7 13:27:56 2008 +0200

    registry: check for existence of key in regdb_fetch_values() first.
    
    This uses the new semantics for existence of a key.
    
    Michael

commit 978aef3a862065be856b36b38d72d581c3ac0ba1
Author: Michael Adam <obnox at samba.org>
Date:   Wed May 7 13:26:13 2008 +0200

    registry: free talloc context on error path in regdb_fetch_values().
    
    Michael

commit 477008367f0ac90624b4b751955cd3235b2c9cc6
Author: Michael Adam <obnox at samba.org>
Date:   Tue May 6 10:05:20 2008 +0200

    registry: Implement new semantics for existence of registry key in tdb.
    
    Existence of a key is defined as follows:
    * If the key is a base key (without separator), the key exists
      iff the corresponding entry exist in the registry tdb.
    * If the key is not a base key, the key exists, iff it exists
      in the list of subkeys of it's parent keyname's tdb entry.
    
    Michael

commit 04762cfcdba741afa457c96cd2f24e50cf83b15a
Author: Michael Adam <obnox at samba.org>
Date:   Tue May 6 22:20:49 2008 +0200

    registry: make normalize_reg_path() strip leading and trailing '/' chars.
    
    Michael

commit 2b25f480ba13ae125d081bab55ee3cbd3c4f425a
Author: Michael Adam <obnox at samba.org>
Date:   Tue May 6 17:15:50 2008 +0200

    registry: free temporary data in regdb_fetch_key_internal().
    
    Michael

commit 23d7002b22ddcd2c52650463f31b72449aecaaaa
Author: Michael Adam <obnox at samba.org>
Date:   Tue May 6 17:09:57 2008 +0200

    registry: change order of arguments of regdb_fetch_key_internal()
    
    list talloc context first.
    
    Michael

-----------------------------------------------------------------------

Summary of changes:
 source/registry/reg_backend_db.c |  209 ++++++++++++++++++++++++++++++++-----
 source/registry/reg_util.c       |   33 +++++--
 2 files changed, 206 insertions(+), 36 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/registry/reg_backend_db.c b/source/registry/reg_backend_db.c
index 8ebe647..0d976be 100644
--- a/source/registry/reg_backend_db.c
+++ b/source/registry/reg_backend_db.c
@@ -28,6 +28,7 @@ static struct db_context *regdb = NULL;
 static int regdb_refcount;
 
 static bool regdb_key_exists(const char *key);
+static bool regdb_key_is_base_key(const char *key);
 
 /* List the deepest path into the registry.  All part components will be created.*/
 
@@ -582,6 +583,10 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr)
 	TALLOC_CTX *ctx = talloc_stackframe();
 	NTSTATUS status;
 
+	if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) {
+		goto fail;
+	}
+
 	/*
 	 * fetch a list of the old subkeys so we can determine if anything has
 	 * changed
@@ -631,15 +636,28 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr)
 
 	regdb_fetch_keys(key, old_subkeys);
 
-	/* store the subkey list for the parent */
-
-	if (!regdb_store_keys_internal(key, ctr) ) {
-		DEBUG(0,("regdb_store_keys: Failed to store new subkey list "
-			 "for parent [%s]\n", key));
-		goto cancel;
-	}
+	/*
+	 * Make the store operation as safe as possible without transactions:
+	 *
+	 * (1) For each subkey removed from ctr compared with old_subkeys:
+	 *
+	 *     (a) First delete the value db entry.
+	 *
+	 *     (b) Next delete the secdesc db record.
+	 *
+	 *     (c) Then delete the subkey list entry.
+	 *
+	 * (2) Now write the list of subkeys of the parent key,
+	 *     deleting removed entries and adding new ones.
+	 *
+	 * (3) Finally create the subkey list entries for the added keys.
+	 *
+	 * This way if we crash half-way in between deleting the subkeys
+	 * and storing the parent's list of subkeys, no old data can pop up
+	 * out of the blue when re-adding keys later on.
+	 */
 
-	/* now delete removed keys */
+	/* (1) delete removed keys' lists (values/secdesc/subkeys) */
 
 	num_subkeys = regsubkey_ctr_numkeys(old_subkeys);
 	for (i=0; i<num_subkeys; i++) {
@@ -653,7 +671,12 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr)
 			continue;
 		}
 
-		path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname);
+		/* (a) Delete the value list for this key */
+
+		path = talloc_asprintf(ctx, "%s/%s/%s",
+				REG_VALUE_PREFIX,
+				key,
+				oldkeyname );
 		if (!path) {
 			goto cancel;
 		}
@@ -661,15 +684,14 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr)
 		if (!path) {
 			goto cancel;
 		}
-		status = dbwrap_delete_bystring(regdb, path);
-		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(1, ("Deleting %s failed\n", path));
-			goto cancel;
-		}
-
+		/* Ignore errors here, we might have no values around */
+		dbwrap_delete_bystring(regdb, path);
 		TALLOC_FREE(path);
+
+		/* (b) Delete the secdesc for this key */
+
 		path = talloc_asprintf(ctx, "%s/%s/%s",
-				REG_VALUE_PREFIX,
+				REG_SECDESC_PREFIX,
 				key,
 				oldkeyname );
 		if (!path) {
@@ -679,17 +701,39 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr)
 		if (!path) {
 			goto cancel;
 		}
-
-		/*
-		 * Ignore errors here, we might have no values around
-		 */
+		/* Ignore errors here, we might have no values around */
 		dbwrap_delete_bystring(regdb, path);
 		TALLOC_FREE(path);
+
+		/* (c) Delete the list of subkeys of this key */
+
+		path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname);
+		if (!path) {
+			goto cancel;
+		}
+		path = normalize_reg_path(ctx, path);
+		if (!path) {
+			goto cancel;
+		}
+		status = dbwrap_delete_bystring(regdb, path);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(1, ("Deleting %s failed\n", path));
+			goto cancel;
+		}
+		TALLOC_FREE(path);
 	}
 
 	TALLOC_FREE(old_subkeys);
 
-	/* now create records for any subkeys that don't already exist */
+	/* (2) store the subkey list for the parent */
+
+	if (!regdb_store_keys_internal(key, ctr) ) {
+		DEBUG(0,("regdb_store_keys: Failed to store new subkey list "
+			 "for parent [%s]\n", key));
+		goto cancel;
+	}
+
+	/* (3) now create records for any subkeys that don't already exist */
 
 	num_subkeys = regsubkey_ctr_numkeys(ctr);
 
@@ -753,28 +797,113 @@ fail:
 }
 
 
-static TDB_DATA regdb_fetch_key_internal(const char *key, TALLOC_CTX *mem_ctx)
+static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key)
 {
 	char *path = NULL;
+	TDB_DATA data;
 
 	path = normalize_reg_path(mem_ctx, key);
 	if (!path) {
 		return make_tdb_data(NULL, 0);
 	}
 
-	return dbwrap_fetch_bystring(regdb, mem_ctx, path);
+	data = dbwrap_fetch_bystring(regdb, mem_ctx, path);
+
+	TALLOC_FREE(path);
+	return data;
+}
+
+
+/**
+ * check whether a given key name represents a base key,
+ * i.e one without a subkey separator ('/' or '\').
+ */
+static bool regdb_key_is_base_key(const char *key)
+{
+	TALLOC_CTX *mem_ctx = talloc_stackframe();
+	bool ret = false;
+	char *path;
+
+	if (key == NULL) {
+		goto done;
+	}
+
+	path = normalize_reg_path(mem_ctx, key);
+	if (path == NULL) {
+		DEBUG(0, ("out of memory! (talloc failed)\n"));
+		goto done;
+	}
+
+	if (*path == '\0') {
+		goto done;
+	}
+
+	ret = (strrchr(path, '/') == NULL);
+
+done:
+	TALLOC_FREE(mem_ctx);
+	return ret;
 }
 
 
+/**
+ * Check for the existence of a key.
+ *
+ * Existence of a key is authoritatively defined by its
+ * existence in the list of subkeys of its parent key.
+ * The exeption of this are keys without a parent key,
+ * i.e. the "base" keys (HKLM, HKCU, ...).
+ */
 static bool regdb_key_exists(const char *key)
 {
 	TALLOC_CTX *mem_ctx = talloc_stackframe();
 	TDB_DATA value;
-	bool ret;
+	bool ret = false;
+	char *path, *p;
+
+	if (key == NULL) {
+		goto done;
+	}
+
+	path = normalize_reg_path(mem_ctx, key);
+	if (path == NULL) {
+		DEBUG(0, ("out of memory! (talloc failed)\n"));
+		goto done;
+	}
+
+	if (*path == '\0') {
+		goto done;
+	}
 
-	value = regdb_fetch_key_internal(key, mem_ctx);
-	ret = (value.dptr != NULL);
+	p = strrchr(path, '/');
+	if (p == NULL) {
+		/* this is a base key */
+		value = regdb_fetch_key_internal(mem_ctx, path);
+		ret = (value.dptr != NULL);
+	} else {
+		/* get the list of subkeys of the parent key */
+		uint32 num_items, len, i;
+		fstring subkeyname;
+
+		*p = '\0';
+		p++;
+		value = regdb_fetch_key_internal(mem_ctx, path);
+		if (value.dptr == NULL) {
+			goto done;
+		}
 
+		len = tdb_unpack(value.dptr, value.dsize, "d", &num_items);
+		for (i = 0; i < num_items; i++) {
+			len += tdb_unpack(value.dptr +len, value.dsize -len,
+					  "f", &subkeyname);
+			if (strequal(subkeyname, p)) {
+				ret = true;
+				goto done;
+			}
+		}
+	}
+
+done:
 	TALLOC_FREE(mem_ctx);
 	return ret;
 }
@@ -799,9 +928,13 @@ int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr)
 
 	DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL"));
 
+	if (!regdb_key_exists(key)) {
+		goto fail;
+	}
+
 	ctr->seqnum = regdb_get_seqnum();
 
-	value = regdb_fetch_key_internal(key, frame);
+	value = regdb_fetch_key_internal(frame, key);
 
 	buf = value.dptr;
 	buflen = value.dsize;
@@ -924,14 +1057,18 @@ int regdb_fetch_values( const char* key, REGVAL_CTR *values )
 
 	DEBUG(10,("regdb_fetch_values: Looking for value of key [%s] \n", key));
 
+	if (!regdb_key_exists(key)) {
+		goto done;
+	}
+
 	keystr = talloc_asprintf(ctx, "%s/%s", REG_VALUE_PREFIX, key);
 	if (!keystr) {
-		return 0;
+		goto done;
 	}
 
 	values->seqnum = regdb_get_seqnum();
 
-	value = regdb_fetch_key_internal(keystr, ctx);
+	value = regdb_fetch_key_internal(ctx, keystr);
 
 	if (!value.dptr) {
 		/* all keys have zero values by default */
@@ -957,6 +1094,10 @@ bool regdb_store_values( const char *key, REGVAL_CTR *values )
 
 	DEBUG(10,("regdb_store_values: Looking for value of key [%s] \n", key));
 
+	if (!regdb_key_exists(key)) {
+		goto done;
+	}
+
 	ZERO_STRUCT(data);
 
 	len = regdb_pack_values(values, data.dptr, data.dsize);
@@ -1012,6 +1153,11 @@ static WERROR regdb_get_secdesc(TALLOC_CTX *mem_ctx, const char *key,
 
 	DEBUG(10, ("regdb_get_secdesc: Getting secdesc of key [%s]\n", key));
 
+	if (!regdb_key_exists(key)) {
+		err = WERR_BADFILE;
+		goto done;
+	}
+
 	tdbkey = talloc_asprintf(tmp_ctx, "%s/%s", REG_SECDESC_PREFIX, key);
 	if (tdbkey == NULL) {
 		err = WERR_NOMEM;
@@ -1048,6 +1194,11 @@ static WERROR regdb_set_secdesc(const char *key,
 	WERROR err = WERR_NOMEM;
 	TDB_DATA tdbdata;
 
+	if (!regdb_key_exists(key)) {
+		err = WERR_BADFILE;
+		goto done;
+	}
+
 	tdbkey = talloc_asprintf(mem_ctx, "%s/%s", REG_SECDESC_PREFIX, key);
 	if (tdbkey == NULL) {
 		goto done;
diff --git a/source/registry/reg_util.c b/source/registry/reg_util.c
index e72353e..714a39f 100644
--- a/source/registry/reg_util.c
+++ b/source/registry/reg_util.c
@@ -83,19 +83,38 @@ bool reg_split_key(char *path, char **base, char **key)
 	return true;
 }
 
-/**********************************************************************
- The full path to the registry key is used as database after the
- \'s are converted to /'s.  Key string is also normalized to UPPER
- case.
-**********************************************************************/
+/**
+ * The full path to the registry key is used as database key
+ * after the \'s are converted to /'s.
+ * Leading and trailing '/' and '\' characters are stripped.
+ * Key string is also normalized to UPPER case.
+ */
 
 char *normalize_reg_path(TALLOC_CTX *ctx, const char *keyname )
 {
-	char *nkeyname = talloc_string_sub(ctx, keyname, "\\", "/");
-	if (!nkeyname) {
+	char *p;
+	char *nkeyname;
+
+	/* skip leading '/' and '\' chars */
+	p = (char *)keyname;
+	while ((*p == '/') || (*p == '\\')) {
+		p++;
+	}
+
+	nkeyname = talloc_string_sub(ctx, p, "\\", "/");
+	if (nkeyname == NULL) {
 		return NULL;
 	}
+
+	/* strip trailing '/' chars */
+	p = strrchr(nkeyname, '/');
+	while ((p != NULL) && (p[1] == '\0')) {
+		*p = '\0';
+		p = strrchr(nkeyname, '/');
+	}
+
 	strupper_m(nkeyname);
+
 	return nkeyname;
 }
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list