[SCM] Samba Shared Repository - branch master updated

Andrew Tridgell tridge at samba.org
Thu Mar 11 22:33:17 MST 2010


The branch, master has been updated
       via  a0527dd... use unsigned instead of uint32_t for LDB counters.
       via  208e280... nTDSConnection creation
       via  6e20906... spanning tree computation
       via  b70df94... new function kcctpl_color_vertices
       via  7b20ad9... s4-drs: check if an optional feature is enabled
      from  ca67768... s4:selftest Add file based DNS resolver to selftest environment

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


- Log -----------------------------------------------------------------
commit a0527dd790c12d9f3d7e579103a48dd420946e40
Author: Crístian Deives <cristiandeives at gmail.com>
Date:   Mon Mar 8 23:45:44 2010 -0300

    use unsigned instead of uint32_t for LDB counters.
    
    the attribute num_values of the struct ldb_message_element is defined as
    an unsigned int, so the counters of that variable should be of the same
    type.

commit 208e2801b4715626a46292ca9d576d34d7fbfef2
Author: Crístian Deives <cristiandeives at gmail.com>
Date:   Sun Mar 7 02:09:24 2010 -0300

    nTDSConnection creation
    
    create nTDSConnection objects to "imply" the minimum-cost spanning tree edges
    for which no nTDSConnection objects yet exist. it also adds a test function in
    kcc_connection so the kcctpl functions can be called. this patch is in accord
    with the sections [MS-ADTS] 7.2.2.3.4.2 and 7.2.2.3.4.5.

commit 6e20906f420be591894925a38504735d4e220c52
Author: Crístian Deives <cristiandeives at gmail.com>
Date:   Sun Mar 7 01:55:12 2010 -0300

    spanning tree computation
    
    calculate the spanning tree for the intersite connection. this patch is in
    accord with the section [MS-ADTS] 7.2.2.3.4.4.

commit b70df94f620eb6c30ddfc98212012df270750412
Author: Crístian Deives <cristiandeives at gmail.com>
Date:   Sun Mar 7 01:34:41 2010 -0300

    new function kcctpl_color_vertices
    
    besides the new function implemented, some minor bugs were also fixed.  this
    patch is in accord with the section [MS-ADTS] 7.2.2.3.4.3.

commit 7b20ad99d679de92a13652224fb33b4a0a0a7b35
Author: Eduardo Lima <eduardoll at gmail.com>
Date:   Wed Mar 10 16:21:29 2010 -0300

    s4-drs: check if an optional feature is enabled

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

Summary of changes:
 source4/dsdb/kcc/kcc_connection.c     |    2 +
 source4/dsdb/kcc/kcc_topology.c       | 3292 ++++++++++++++++++++++++++++++---
 source4/dsdb/samdb/ldb_modules/util.c |   59 +
 3 files changed, 3143 insertions(+), 210 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/kcc/kcc_connection.c b/source4/dsdb/kcc/kcc_connection.c
index d0d549d..e78a615 100644
--- a/source4/dsdb/kcc/kcc_connection.c
+++ b/source4/dsdb/kcc/kcc_connection.c
@@ -175,6 +175,8 @@ struct kcc_connection_list *kccsrv_find_connections(struct kccsrv_service *s,
 	const char *attrs[] = { "objectGUID", "fromServer", NULL };
 	struct kcc_connection_list *list;
 
+	kcctpl_test(s->samdb);
+
 	base_dn = samdb_ntds_settings_dn(s->samdb);
 	if (!base_dn) {
 		DEBUG(0, ("failed to find our own NTDS settings DN\n"));
diff --git a/source4/dsdb/kcc/kcc_topology.c b/source4/dsdb/kcc/kcc_topology.c
index 571bd84..a2dd4dd 100644
--- a/source4/dsdb/kcc/kcc_topology.c
+++ b/source4/dsdb/kcc/kcc_topology.c
@@ -25,14 +25,36 @@
 #include "lib/messaging/irpc.h"
 #include "librpc/gen_ndr/ndr_misc.h"
 
-#define NTDSTRANSPORT_OPT_IGNORE_SCHEDULES 0x00000001
+#define FLAG_CR_NTDS_NC 0x00000001
+#define FLAG_CR_NTDS_DOMAIN 0x00000002
+
+#define NTDSCONN_OPT_IS_GENERATED 0x00000001
+#define NTDSCONN_OPT_TWOWAY_SYNC 0x00000002
+#define NTDSCONN_OPT_OVERRIDE_NOTIFY_DEFAULT 0x00000004
+#define NTDSCONN_OPT_USE_NOTIFY 0x00000008
+#define NTDSCONN_OPT_DISABLE_INTERSITE_COMPRESSION 0x00000010
+#define NTDSCONN_OPT_USER_OWNED_SCHEDULE 0x00000020
+#define NTDSCONN_OPT_RODC_TOPOLOGY 0x00000040
+
+#define NTDSDSA_OPT_IS_GC 0x00000001
+
+#define NTDSSETTINGS_OPT_IS_TOPL_DETECT_STALE_DISABLED 0x00000008
+#define NTDSSETTINGS_OPT_IS_RAND_BH_SELECTION_DISABLED 0x00000100
+#define NTDSSETTINGS_OPT_W2K3_BRIDGES_REQUIRED 0x00001000
+
+#define NTDSSITELINK_OPT_USE_NOTIFY 0x00000001
+#define NTDSSITELINK_OPT_TWOWAY_SYNC 0x00000002
+#define NTDSSITELINK_OPT_DISABLE_COMPRESSION 0x00000004
+
 #define NTDSTRANSPORT_OPT_BRIDGES_REQUIRED 0x00000002
 
+#define DS_BEHAVIOR_WIN2008 3
+
 /** replication parameters of a graph edge */
 struct kcctpl_repl_info {
-	int cost;
-	int interval;
-	int options;
+	uint32_t cost;
+	uint32_t interval;
+	uint32_t options;
 	uint8_t schedule[84];
 };
 
@@ -42,7 +64,7 @@ enum kcctpl_color { RED, BLACK, WHITE };
 /** a GUID array list */
 struct GUID_list {
 	struct GUID *data;
-	unsigned int count;
+	uint32_t count;
 };
 
 /** a vertex in the site graph */
@@ -53,7 +75,7 @@ struct kcctpl_vertex {
 	struct GUID_list accept_red_red;
 	struct GUID_list accept_black;
 	struct kcctpl_repl_info repl_info;
-	int dist_to_red;
+	uint32_t dist_to_red;
 
 	/* Dijkstra data */
 	struct GUID root_id;
@@ -61,7 +83,7 @@ struct kcctpl_vertex {
 
 	/* Kruskal data */
 	struct GUID component_id;
-	int component_index;
+	uint32_t component_index;
 };
 
 /** fully connected subgraph of vertices */
@@ -83,19 +105,19 @@ struct kcctpl_multi_edge_set {
 /** a vertices array list */
 struct kcctpl_vertex_list {
 	struct kcctpl_vertex *data;
-	unsigned int count;
+	uint32_t count;
 };
 
-/** an edges linked list */
+/** an edges array list */
 struct kcctpl_multi_edge_list {
 	struct kcctpl_multi_edge *data;
-	unsigned int count;
+	uint32_t count;
 };
 
-/** an edge sets linked list */
+/** an edge sets array list */
 struct kcctpl_multi_edge_set_list {
 	struct kcctpl_multi_edge_set *data;
-	unsigned int count;
+	uint32_t count;
 };
 
 /** a site graph */
@@ -107,49 +129,394 @@ struct kcctpl_graph {
 
 /** path found in the graph between two non-white vertices */
 struct kcctpl_internal_edge {
-	struct GUID v1id, v2id;
+	struct GUID v1id;
+	struct GUID v2id;
 	bool red_red;
 	struct kcctpl_repl_info repl_info;
 	struct GUID type;
 };
 
+/** an internal edges array list */
+struct kcctpl_internal_edge_list {
+	struct kcctpl_internal_edge *data;
+	uint32_t count;
+};
+
+/** an LDB messages array list */
+struct message_list {
+	struct ldb_message *data;
+	uint32_t count;
+};
+
+/**
+ * sort internal edges based on:
+ * - descending red_red,
+ * - ascending repl_info.cost,
+ * - descending available time in repl_info.schedule,
+ * - ascending v1id,
+ * - ascending v2id,
+ * - ascending type.
+ *
+ * this function is used in 'kcctpl_kruskal'.
+ */
+static int kcctpl_sort_internal_edges(const void *internal_edge1,
+				      const void *internal_edge2)
+{
+	const struct kcctpl_internal_edge *ie1, *ie2;
+	int cmp_red_red;
+
+	ie1 = (const struct kcctpl_internal_edge *) internal_edge1;
+	ie2 = (const struct kcctpl_internal_edge *) internal_edge2;
+
+	cmp_red_red = ie2->red_red - ie1->red_red;
+	if (cmp_red_red == 0) {
+		int cmp_cost = ie1->repl_info.cost - ie2->repl_info.cost;
+
+		if (cmp_cost == 0) {
+			uint32_t available1, available2, i;
+			int cmp_schedule;
+
+			available1 = available2 = 0;
+			for (i = 0; i < 84; i++) {
+				if (ie1->repl_info.schedule[i] == 0) {
+					available1++;
+				}
+
+				if (ie2->repl_info.schedule[i] == 0) {
+					available2++;
+				}
+			}
+			cmp_schedule = available2 - available1;
+
+			if (cmp_schedule == 0) {
+				int cmp_v1id = GUID_compare(&ie1->v1id,
+							    &ie2->v1id);
+
+				if (cmp_v1id == 0) {
+					int cmp_v2id = GUID_compare(&ie1->v2id,
+								    &ie2->v2id);
+
+					if (cmp_v2id == 0) {
+						return GUID_compare(&ie1->type,
+								    &ie2->type);
+					} else {
+						return cmp_v2id;
+					}
+				} else {
+					return cmp_v1id;
+				}
+			} else {
+				return cmp_schedule;
+			}
+		} else {
+			return cmp_cost;
+		}
+	} else {
+		return cmp_red_red;
+	}
+}
+
+/**
+ * sort vertices based on the following criteria:
+ * - ascending color (RED < BLACK),
+ * - ascending repl_info.cost,
+ * - ascending id.
+ *
+ * this function is used in 'kcctpl_process_edge'.
+ */
+static int kcctpl_sort_vertices(const void *vertex1, const void *vertex2)
+{
+	const struct kcctpl_vertex *v1, *v2;
+	int cmp_color;
+
+	v1 = (const struct kcctpl_vertex *) vertex1;
+	v2 = (const struct kcctpl_vertex *) vertex2;
+
+	cmp_color = v1->color - v2->color;
+	if (cmp_color == 0) {
+		int cmp_cost = v1->repl_info.cost - v2->repl_info.cost;
+		if (cmp_cost == 0) {
+			return GUID_compare(&v1->id, &v2->id);
+		} else {
+			return cmp_cost;
+		}
+	} else {
+		return cmp_color;
+	}
+}
+
+/**
+ * sort bridgehead elements (nTDSDSA) based on the following criteria:
+ * - GC servers precede non-GC servers
+ * - ascending objectGUID
+ *
+ * this function is used in 'kcctpl_get_all_bridgehead_dcs'.
+ */
+static int kcctpl_sort_bridgeheads(const void *bridgehead1,
+				   const void *bridgehead2)
+{
+	const struct ldb_message *bh1, *bh2;
+	uint64_t bh1_opts, bh2_opts, cmp_gc;
+
+	bh1 = (const struct ldb_message *) bridgehead1;
+	bh2 = (const struct ldb_message *) bridgehead2;
+
+	bh1_opts = samdb_result_int64(bh1, "options", 0);
+	bh2_opts = samdb_result_int64(bh2, "options", 0);
+
+	cmp_gc = (bh1_opts & NTDSDSA_OPT_IS_GC) -
+		 (bh2_opts & NTDSDSA_OPT_IS_GC);
+
+	if (cmp_gc == 0) {
+		struct GUID bh1_id, bh2_id;
+
+		bh1_id = samdb_result_guid(bh1, "objectGUID");
+		bh2_id = samdb_result_guid(bh2, "objectGUID");
+
+		return GUID_compare(&bh1_id, &bh2_id);
+	} else {
+		return cmp_gc;
+	}
+}
+
+/**
+ * sort bridgehead elements (nTDSDSA) in a random order.
+ *
+ * this function is used in 'kcctpl_get_all_bridgehead_dcs'.
+ */
+static void kcctpl_shuffle_bridgeheads(struct message_list bridgeheads)
+{
+	uint32_t i;
+
+	srandom(time(NULL));
+
+	for (i = bridgeheads.count; i > 1; i--) {
+		uint32_t r;
+		struct ldb_message tmp;
+
+		r = random() % i;
+
+		tmp = bridgeheads.data[i - 1];
+		bridgeheads.data[i - 1] = bridgeheads.data[r];
+		bridgeheads.data[r] = tmp;
+	}
+}
+
+/**
+ * find a graph vertex based on its GUID.
+ */
+static struct kcctpl_vertex *kcctpl_find_vertex_by_guid(struct kcctpl_graph *graph,
+							struct GUID guid)
+{
+	uint32_t i;
+
+	for (i = 0; i < graph->vertices.count; i++) {
+		if (GUID_equal(&graph->vertices.data[i].id, &guid)) {
+			return &graph->vertices.data[i];
+		}
+	}
+
+	return NULL;
+}
+
 /**
  * find a graph edge based on its GUID.
  */
 static struct kcctpl_multi_edge *kcctpl_find_edge_by_guid(struct kcctpl_graph *graph,
 							  struct GUID guid)
 {
-	unsigned int i;
+	uint32_t i;
 
 	for (i = 0; i < graph->edges.count; i++) {
-		if (GUID_compare(&graph->edges.data[i].id, &guid) == 0) {
+		if (GUID_equal(&graph->edges.data[i].id, &guid)) {
 			return &graph->edges.data[i];
 		}
 	}
+
 	return NULL;
 }
+
+/**
+ * find a graph edge that contains a vertex with the specified GUID. the first
+ * occurrence will be returned.
+ */
+static struct kcctpl_multi_edge *kcctpl_find_edge_by_vertex_guid(struct kcctpl_graph *graph,
+								 struct GUID guid)
+{
+	uint32_t i;
+
+	for (i = 0; i < graph->edges.count; i++) {
+		struct kcctpl_multi_edge *edge;
+		uint32_t j;
+
+		edge = &graph->edges.data[i];
+
+		for (j = 0; j < edge->vertex_ids.count; j++) {
+			struct GUID vertex_guid = edge->vertex_ids.data[j];
+
+			struct GUID *p = &guid;
+
+			if (GUID_equal(&vertex_guid, p)) {
+				return edge;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+/**
+ * search for an occurrence of a GUID inside a list of GUIDs.
+ */
+static bool kcctpl_guid_list_contains(struct GUID_list list, struct GUID guid)
+{
+	uint32_t i;
+
+	for (i = 0; i < list.count; i++) {
+		if (GUID_equal(&list.data[i], &guid)) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+/**
+ * search for an occurrence of an ldb_message inside a list of ldb_messages,
+ * based on the ldb_message's DN.
+ */
+static bool kcctpl_message_list_contains_dn(struct message_list list,
+					    struct ldb_dn *dn)
+{
+	uint32_t i;
+
+	for (i = 0; i < list.count; i++) {
+		struct ldb_message *message = &list.data[i];
+
+		if (ldb_dn_compare(message->dn, dn) == 0) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+/**
+ * get the Transports DN
+ * (CN=Inter-Site Transports,CN=Sites,CN=Configuration,DC=<domain>).
+ */
+static struct ldb_dn *kcctpl_transports_dn(struct ldb_context *ldb,
+					   TALLOC_CTX *mem_ctx)
+{
+	struct ldb_dn *sites_dn;
+	bool ok;
+
+	sites_dn = samdb_sites_dn(ldb, mem_ctx);
+	if (!sites_dn) {
+		return NULL;
+	}
+
+	ok = ldb_dn_add_child_fmt(sites_dn, "CN=Inter-Site Transports");
+	if (!ok) {
+		talloc_free(sites_dn);
+		return NULL;
+	}
+
+	return sites_dn;
+}
+/**
+ * get the domain local site object.
+ */
+static struct ldb_message *kcctpl_local_site(struct ldb_context *ldb,
+					     TALLOC_CTX *mem_ctx)
+{
+	int ret;
+	TALLOC_CTX *tmp_ctx;
+	struct ldb_dn *sites_dn;
+	struct ldb_result *res;
+	const char * const attrs[] = { "objectGUID", "options", NULL };
+
+	tmp_ctx = talloc_new(ldb);
+
+	sites_dn = samdb_sites_dn(ldb, tmp_ctx);
+	if (!sites_dn) {
+		talloc_free(tmp_ctx);
+		return NULL;
+	}
+
+	ret = ldb_search(ldb, tmp_ctx, &res, sites_dn, LDB_SCOPE_SUBTREE, attrs,
+			 "objectClass=site");
+
+	if (ret != LDB_SUCCESS || res->count == 0) {
+		talloc_free(tmp_ctx);
+		return NULL;
+	}
+
+	talloc_steal(mem_ctx, res);
+	talloc_free(tmp_ctx);
+	return res->msgs[0];
+}
+
+/*
+ * compare two internal edges for equality. every field of the structure will be
+ * compared.
+ */
+static bool kcctpl_internal_edge_equal(struct kcctpl_internal_edge *edge1,
+				       struct kcctpl_internal_edge *edge2)
+{
+	if (!edge1 || !edge2) {
+		return false;
+	}
+
+	if (!GUID_equal(&edge1->v1id, &edge2->v1id)) {
+		return false;
+	}
+
+	if (!GUID_equal(&edge1->v2id, &edge2->v2id)) {
+		return false;
+	}
+
+	if (edge1->red_red != edge2->red_red) {
+		return false;
+	}
+
+	if (edge1->repl_info.cost != edge2->repl_info.cost ||
+	    edge1->repl_info.interval != edge2->repl_info.interval ||
+	    edge1->repl_info.options != edge2->repl_info.options ||
+	    memcmp(&edge1->repl_info.schedule,
+		   &edge2->repl_info.schedule, 84) != 0) {
+		return false;
+	}
+
+	if (!GUID_equal(&edge1->type, &edge2->type)) {
+		return false;
+	}
+
+	return true;
+}
+
 /**
  * create a kcctpl_graph instance.
  */
 static NTSTATUS kcctpl_create_graph(TALLOC_CTX *mem_ctx,
-				    struct GUID_list *guids,
+				    struct GUID_list guids,
 				    struct kcctpl_graph **_graph)
 {
 	struct kcctpl_graph *graph;
-	unsigned int i;
+	uint32_t i;
 
 	graph = talloc_zero(mem_ctx, struct kcctpl_graph);
 	NT_STATUS_HAVE_NO_MEMORY(graph);
 
-	graph->vertices.count = guids->count;
+	graph->vertices.count = guids.count;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list