[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