[SCM] Samba Shared Repository - branch master updated

Michael Adam obnox at samba.org
Fri Dec 2 21:21:03 MST 2011


The branch, master has been updated
       via  d74b3f9 lib/util: factor out tdb_data_is_empty
       via  789aa9a s3:registry: do not use regdb functions during db upgrade
       via  5bc4449 s3:net: adapt idmap check to new dbwrap_fetch behavior not to return success if not found
      from  a3f6005 s3-winbind: Add an update function for winbind cache.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit d74b3f941f5e28bf4a98dab6d4be25fbaab200b7
Author: Gregor Beck <gbeck at sernet.de>
Date:   Mon Nov 7 09:59:37 2011 +0100

    lib/util: factor out tdb_data_is_empty
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Autobuild-User: Michael Adam <obnox at samba.org>
    Autobuild-Date: Sat Dec  3 05:20:30 CET 2011 on sn-devel-104

commit 789aa9aab2b99ae1466a67e3f505abbc67a3e7cb
Author: Gregor Beck <gbeck at sernet.de>
Date:   Fri Oct 14 10:57:11 2011 +0200

    s3:registry: do not use regdb functions during db upgrade
    
    It is importante to not use the database backend implementation
    in the upgrade. Otherwise this would only work as long as this
    is the newset version. In future versions of the registry, this
    (then) intermediate upgrade step would change in behaviour and not
    work as expected any more.
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 5bc44491d2c28db0a100f4e34f306dbabf84bb55
Author: Gregor Beck <gbeck at sernet.de>
Date:   Fri Nov 4 10:55:47 2011 +0100

    s3:net: adapt idmap check to new dbwrap_fetch behavior not to return success if not found
    
    Signed-off-by: Michael Adam <obnox at samba.org>

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

Summary of changes:
 lib/util/util_tdb.c                |    4 +
 lib/util/util_tdb.h                |    1 +
 source3/Makefile.in                |    6 +-
 source3/registry/reg_backend_db.c  |  194 +++++++++++++++++++++++++----------
 source3/utils/net_idmap_check.c    |   25 ++---
 source3/utils/net_registry_check.c |    4 -
 source3/wscript_build              |    7 +-
 7 files changed, 161 insertions(+), 80 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/util/util_tdb.c b/lib/util/util_tdb.c
index 02c7095..0c30d77 100644
--- a/lib/util/util_tdb.c
+++ b/lib/util/util_tdb.c
@@ -46,6 +46,10 @@ bool tdb_data_equal(TDB_DATA t1, TDB_DATA t2)
 	return (memcmp(t1.dptr, t2.dptr, t1.dsize) == 0);
 }
 
+bool tdb_data_is_empty(TDB_DATA d) {
+	return (d.dsize == 0) || (d.dptr == NULL);
+}
+
 TDB_DATA string_tdb_data(const char *string)
 {
 	return make_tdb_data((const uint8_t *)string, string ? strlen(string) : 0 );
diff --git a/lib/util/util_tdb.h b/lib/util/util_tdb.h
index 2d805d7..3d03b99 100644
--- a/lib/util/util_tdb.h
+++ b/lib/util/util_tdb.h
@@ -27,6 +27,7 @@
 ****************************************************************/
 TDB_DATA make_tdb_data(const uint8_t *dptr, size_t dsize);
 bool tdb_data_equal(TDB_DATA t1, TDB_DATA t2);
+bool tdb_data_is_empty(TDB_DATA d);
 TDB_DATA string_tdb_data(const char *string);
 TDB_DATA string_term_tdb_data(const char *string);
 
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 62504fd..3cdf9b6 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -682,6 +682,8 @@ REG_BASE_OBJ = registry/reg_api.o \
 	       registry/reg_util_internal.o \
 	       lib/util_nttoken.o \
 	       $(REG_BACKENDS_BASE_OBJ) \
+	       registry/reg_parse_internal.o \
+	       lib/cbuf.o lib/srprs.o \
 	       $(REG_INIT_BASIC_OBJ)
 
 REG_SMBCONF_OBJ = $(REG_BASE_OBJ) \
@@ -1219,8 +1221,8 @@ NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_help.o \
 	   rpc_client/init_netlogon.o \
 	   rpc_client/init_samr.o \
 	   registry/reg_parse.o registry/reg_format.o \
-	   registry/reg_parse_internal.o registry/reg_import.o \
-	   lib/cbuf.o lib/srprs.o printing/nt_printing_migrate.o
+	   registry/reg_import.o \
+	   printing/nt_printing_migrate.o
 
 # these are not processed by make proto
 NET_OBJ2 = utils/net_registry_util.o utils/net_help_common.o
diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c
index b306b2c..965d121 100644
--- a/source3/registry/reg_backend_db.c
+++ b/source3/registry/reg_backend_db.c
@@ -26,6 +26,7 @@
 #include "registry.h"
 #include "reg_db.h"
 #include "reg_util_internal.h"
+#include "reg_parse_internal.h"
 #include "reg_backend_db.h"
 #include "reg_objects.h"
 #include "nt_printing.h"
@@ -516,22 +517,100 @@ done:
 	return werr;
 }
 
+static bool tdb_data_read_uint32(TDB_DATA *buf, uint32_t *result)
+{
+	const size_t len = sizeof(uint32_t);
+	if (buf->dsize >= len) {
+		*result = IVAL(buf->dptr, 0);
+		buf->dptr += len;
+		buf->dsize -= len;
+		return true;
+	}
+	return false;
+}
+
+static bool tdb_data_read_cstr(TDB_DATA *buf, char **result)
+{
+	const size_t len = strnlen((char*)buf->dptr, buf->dsize) + 1;
+	if (buf->dsize >= len) {
+		*result = (char*)buf->dptr;
+		buf->dptr += len;
+		buf->dsize -= len;
+		return true;
+	}
+	return false;
+}
+
+static bool tdb_data_is_cstr(TDB_DATA d) {
+	if (tdb_data_is_empty(d) || (d.dptr[d.dsize-1] != '\0')) {
+		return false;
+	}
+	return rawmemchr(d.dptr, '\0') == &d.dptr[d.dsize-1];
+}
+
+static bool upgrade_v2_to_v3_check_subkeylist(struct db_context *db,
+					      const char *key,
+					      const char *subkey)
+{
+	static uint32_t zero = 0;
+	static TDB_DATA empty_subkey_list = {
+		.dptr = (unsigned char*)&zero,
+		.dsize = sizeof(uint32_t),
+	};
+	bool success = false;
+	char *path = talloc_asprintf(talloc_tos(), "%s\\%s", key, subkey);
+	strupper_m(path);
+
+	if (!dbwrap_exists(db, string_term_tdb_data(path))) {
+		NTSTATUS status;
+
+		DEBUG(10, ("regdb_upgrade_v2_to_v3: writing subkey list [%s]\n",
+			   path));
+
+		status = dbwrap_store_bystring(db, path, empty_subkey_list,
+					       TDB_INSERT);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(0, ("regdb_upgrade_v2_to_v3: writing subkey list "
+				  "[%s] failed\n", path));
+			goto done;
+		}
+	}
+	success = true;
+done:
+	talloc_free(path);
+	return success;
+}
+
+static bool upgrade_v2_to_v3_check_parent(struct db_context *db,
+					  const char *key)
+{
+	const char *sep = strrchr_m(key, '\\');
+	if (sep != NULL) {
+		char *pkey = talloc_strndup(talloc_tos(), key, sep-key);
+		if (!dbwrap_exists(db, string_term_tdb_data(pkey))) {
+			DEBUG(0, ("regdb_upgrade_v2_to_v3: missing subkey list "
+				  "[%s]\nrun \"net registry check\"\n", pkey));
+		}
+		talloc_free(pkey);
+	}
+	return true;
+}
+
+
+#define IS_EQUAL(d,s) (((d).dsize == strlen(s)+1) &&	\
+		       (strcmp((char*)(d).dptr, (s)) == 0))
+#define STARTS_WITH(d,s) (((d).dsize > strlen(s)) &&			\
+			  (strncmp((char*)(d).dptr, (s), strlen(s)) == 0))
+#define SSTR(d) (int)(d).dsize , (char*)(d).dptr
+
+
 static int regdb_upgrade_v2_to_v3_fn(struct db_record *rec, void *private_data)
 {
-	const char *keyname;
-	fstring subkeyname;
-	NTSTATUS status;
-	WERROR werr;
-	uint8_t *buf;
-	uint32_t buflen, len;
-	uint32_t num_items;
-	uint32_t i;
-	TDB_DATA key;
-	TDB_DATA value;
 	struct db_context *db = (struct db_context *)private_data;
+	TDB_DATA key = dbwrap_record_get_key(rec);
+	TDB_DATA val = dbwrap_record_get_value(rec);
 
-	key = dbwrap_record_get_key(rec);
-	if (key.dptr == NULL || key.dsize == 0) {
+	if (tdb_data_is_empty(key)) {
 		return 0;
 	}
 
@@ -541,70 +620,73 @@ static int regdb_upgrade_v2_to_v3_fn(struct db_record *rec, void *private_data)
 		return 1;
 	}
 
-	keyname = (const char *)key.dptr;
-
-	if (strncmp(keyname, REGDB_VERSION_KEYNAME,
-		    strlen(REGDB_VERSION_KEYNAME)) == 0)
+	if (IS_EQUAL(key, REGDB_VERSION_KEYNAME) ||
+	    STARTS_WITH(key, REG_VALUE_PREFIX) ||
+	    STARTS_WITH(key, REG_SECDESC_PREFIX))
 	{
+		DEBUG(10, ("regdb_upgrade_v2_to_v3: skipping [%.*s]\n",
+			   SSTR(key)));
 		return 0;
 	}
 
-	if (strncmp(keyname, REG_SORTED_SUBKEYS_PREFIX,
-		    strlen(REG_SORTED_SUBKEYS_PREFIX)) == 0)
-	{
+	if (STARTS_WITH(key, REG_SORTED_SUBKEYS_PREFIX)) {
+		NTSTATUS status;
 		/* Delete the deprecated sorted subkeys cache. */
 
-		DEBUG(10, ("regdb_upgrade_v2_to_v3: deleting [%s]\n", keyname));
+		DEBUG(10, ("regdb_upgrade_v2_to_v3: deleting [%.*s]\n",
+			   SSTR(key)));
 
 		status = dbwrap_record_delete(rec);
 		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(0, ("regdb_upgrade_v2_to_v3: tdb_delete for [%s] "
-				  "failed!\n", keyname));
+			DEBUG(0, ("regdb_upgrade_v2_to_v3: deleting [%.*s] "
+				  "failed!\n", SSTR(key)));
 			return 1;
 		}
 
 		return 0;
 	}
 
-	if (strncmp(keyname, REG_VALUE_PREFIX, strlen(REG_VALUE_PREFIX)) == 0) {
-		DEBUG(10, ("regdb_upgrade_v2_to_v3: skipping [%s]\n", keyname));
-		return 0;
-	}
-
-	if (strncmp(keyname, REG_SECDESC_PREFIX,
-		    strlen(REG_SECDESC_PREFIX)) == 0)
+	if ( tdb_data_is_cstr(key) &&
+	     hive_info((char*)key.dptr) != NULL )
 	{
-		DEBUG(10, ("regdb_upgrade_v2_to_v3: skipping [%s]\n", keyname));
-		return 0;
-	}
+		/*
+		 * Found a regular subkey list record.
+		 * Walk the list and create the list record for those
+		 * subkeys that don't already have one.
+		 */
+		TDB_DATA pos = val;
+		char *subkey, *path = (char*)key.dptr;
+		uint32_t num_items, found_items = 0;
 
-	/*
-	 * Found a regular subkey list record.
-	 * Walk the list and create the list record for those
-	 * subkeys that don't already have one.
-	 */
-	DEBUG(10, ("regdb_upgrade_v2_to_v3: scanning subkey list of [%s]\n",
-		   keyname));
 
-	value = dbwrap_record_get_value(rec);
-	buf = value.dptr;
-	buflen = value.dsize;
+		DEBUG(10, ("regdb_upgrade_v2_to_v3: scanning subkeylist of "
+			   "[%s]\n", path));
 
-	len = tdb_unpack(buf, buflen, "d", &num_items);
-	if (len == (uint32_t)-1) {
-		/* invalid or empty - skip */
-		return 0;
-	}
+		if (!tdb_data_read_uint32(&pos, &num_items)) {
+			/* invalid or empty - skip */
+			return 0;
+		}
 
-	for (i=0; i<num_items; i++) {
-		len += tdb_unpack(buf+len, buflen-len, "f", subkeyname);
-		DEBUG(10, ("regdb_upgrade_v2_to_v3: "
-			   "writing subkey list for [%s\\%s]\n",
-			   keyname, subkeyname));
-		werr = regdb_store_subkey_list(db, keyname, subkeyname);
-		if (!W_ERROR_IS_OK(werr)) {
-			return 1;
+		while (tdb_data_read_cstr(&pos, &subkey)) {
+			found_items++;
+
+			if (!upgrade_v2_to_v3_check_subkeylist(db, path, subkey))
+			{
+				return 1;
+			}
+
+			if (!upgrade_v2_to_v3_check_parent(db, path)) {
+				return 1;
+			}
+		}
+		if (found_items != num_items) {
+			DEBUG(0, ("regdb_upgrade_v2_to_v3: inconsistent subkey "
+				  "list [%s]\nrun \"net registry check\"\n",
+				  path));
 		}
+	} else {
+		DEBUG(10, ("regdb_upgrade_v2_to_v3: skipping invalid [%.*s]\n"
+			   "run \"net registry check\"\n", SSTR(key)));
 	}
 
 	return 0;
diff --git a/source3/utils/net_idmap_check.c b/source3/utils/net_idmap_check.c
index de65406..3f9f3f5 100644
--- a/source3/utils/net_idmap_check.c
+++ b/source3/utils/net_idmap_check.c
@@ -43,9 +43,6 @@ static int traverse_check(struct db_record *rec, void* data);
 static char*    print_data(TALLOC_CTX* mem_ctx, TDB_DATA d);
 static TDB_DATA parse_data(TALLOC_CTX* mem_ctx, const char** ptr);
 static TDB_DATA talloc_copy(TALLOC_CTX* mem_ctx, TDB_DATA data);
-static bool is_empty(TDB_DATA data) {
-	return (data.dsize == 0) || (data.dptr == NULL);
-}
 
 /* record *********************************************************************/
 
@@ -275,10 +272,10 @@ static TDB_DATA_diff unpack_diff(TDB_DATA data) {
 
 #define DEBUG_DIFF(LEV,MEM,MSG,KEY,OLD,NEW)			\
 	DEBUG(LEV, ("%s: %s\n", MSG, print_data(MEM, KEY)));	\
-	if (!is_empty(OLD)) {					\
+	if (!tdb_data_is_empty(OLD)) {				\
 		DEBUGADD(LEV, ("-%s\n", print_data(MEM, OLD)));	\
 	}							\
-	if (!is_empty(NEW)) {					\
+	if (!tdb_data_is_empty(NEW)) {				\
 		DEBUGADD(LEV, ("+%s\n", print_data(MEM, NEW)));	\
 	}
 
@@ -355,11 +352,8 @@ fetch_record(struct check_ctx* ctx, TALLOC_CTX* mem_ctx, TDB_DATA key)
 	NTSTATUS status;
 
 	status = dbwrap_fetch(ctx->diff, mem_ctx, key, &tmp);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("Out of memory!\n"));
-		return tdb_null;
-	}
-	if (tmp.dptr != NULL) {
+
+	if (NT_STATUS_IS_OK(status)) {
 		TDB_DATA_diff diff = unpack_diff(tmp);
 		TDB_DATA ret = talloc_copy(mem_ctx, diff.nval);
 		talloc_free(tmp.dptr);
@@ -368,7 +362,6 @@ fetch_record(struct check_ctx* ctx, TALLOC_CTX* mem_ctx, TDB_DATA key)
 
 	status = dbwrap_fetch(ctx->db, mem_ctx, key, &tmp);
 	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("Out of memory!\n"));
 		return tdb_null;
 	}
 
@@ -505,7 +498,7 @@ int traverse_check(struct db_record *rec, void* data) {
 			}
 			if (!tdb_data_equal(key, r->key)) {
 				TDB_DATA oval = fetch_record(ctx, mem, r->key);
-				if (!is_empty(oval) &&
+				if (!tdb_data_is_empty(oval) &&
 				    !tdb_data_equal(oval, r->val))
 				{
 					action = get_action(&act->record_exists,
@@ -517,7 +510,7 @@ int traverse_check(struct db_record *rec, void* data) {
 			}
 			if (is_map(r)) {
 				TDB_DATA okey = fetch_record(ctx, mem, r->val);
-				if (!is_empty(okey) &&
+				if (!tdb_data_is_empty(okey) &&
 				    !tdb_data_equal(okey, r->key))
 				{
 					action = get_action(&act->record_exists,
@@ -570,7 +563,7 @@ TDB_DATA talloc_copy(TALLOC_CTX* mem_ctx, TDB_DATA data) {
 }
 
 static bool is_cstr(TDB_DATA str) {
-	return !is_empty(str) && str.dptr[str.dsize-1] == '\0';
+	return !tdb_data_is_empty(str) && str.dptr[str.dsize-1] == '\0';
 }
 
 static bool parse_sid (TDB_DATA str, enum DT* type, struct dom_sid* sid) {
@@ -670,7 +663,7 @@ struct record* reverse_record(struct record* in)
 
 char* print_data(TALLOC_CTX* mem_ctx, TDB_DATA d)
 {
-	if (!is_empty(d)) {
+	if (!tdb_data_is_empty(d)) {
 		char* ret = NULL;
 		cbuf* ost = cbuf_new(mem_ctx);
 		int len = cbuf_print_quoted(ost, (const char*)d.dptr, d.dsize);
@@ -757,7 +750,7 @@ static int traverse_commit(struct db_record *diff_rec, void* data) {
 
 	DEBUG_DIFF(0, mem, "Commit", key, diff.oval, diff.nval);
 
-	if (is_empty(diff.nval)) {
+	if (tdb_data_is_empty(diff.nval)) {
 		status = dbwrap_record_delete(rec);
 	} else {
 		status = dbwrap_record_store(rec, diff.nval, 0);
diff --git a/source3/utils/net_registry_check.c b/source3/utils/net_registry_check.c
index ce7032a..9dca219 100644
--- a/source3/utils/net_registry_check.c
+++ b/source3/utils/net_registry_check.c
@@ -207,10 +207,6 @@ static bool tdb_data_read_regval(TDB_DATA *buf, struct regval *result)
 	return true;
 }
 
-static bool tdb_data_is_empty(TDB_DATA d) {
-	return (d.dptr == NULL) || (d.dsize == 0);
-}
-
 static bool tdb_data_is_cstr(TDB_DATA d) {
 	if (tdb_data_is_empty(d)) {
 		return false;
diff --git a/source3/wscript_build b/source3/wscript_build
index c07038c..386e2b8 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -186,6 +186,9 @@ REG_BASE_SRC = '''registry/reg_api.c
                registry/reg_util_internal.c
                lib/util_nttoken.c
                ${REG_BACKENDS_BASE_SRC}
+               registry/reg_parse_internal.c
+	       lib/cbuf.c
+               lib/srprs.c
                ${REG_INIT_BASIC_SRC}'''
 
 REG_SMBCONF_SRC = '''
@@ -543,8 +546,8 @@ NET_SRC1 = '''utils/net.c utils/net_ads.c utils/net_help.c
               utils/net_rpc_trust.c
 	      utils/net_rpc_conf.c
               registry/reg_parse.c registry/reg_format.c
-              registry/reg_parse_internal.c registry/reg_import.c
-              lib/cbuf.c lib/srprs.c'''
+              registry/reg_import.c
+              '''
 
 NET_SRC2 = 'utils/net_registry_util.c utils/net_help_common.c'
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list