[SCM] Samba Shared Repository - branch master updated

Andrew Tridgell tridge at samba.org
Wed Sep 21 19:40:03 MDT 2011


The branch, master has been updated
       via  0921e75 s4-dbcheck: fixed transaction nesting in dbcheck
       via  4dbc604 samba-tool: use show_recycled in dbchecker
       via  b92e0a2 s4-kdc: set NO_GLOBAL_CATALOG control in kdc
       via  3e685f5 s4-rpc: show binding string in failed rpc binds
       via  0287221 s4-ldap-server: set the NO_GLOBAL_CATALOG control on non-GC operations
       via  516f326 s4-repl: remove unused principal_name element
       via  aba856c s4-dsdb: load the partialReplica attribute in the @PARTITION object
       via  8c3d77d s4-repl: fill in GUID and SID from partition information
       via  783ff68 s4-kcc: return partial replica NCs in drs showrepl
       via  00ef18f s4-dsdb: added NO_GLOBAL_CATALOG control
       via  73f2df6 s4-dns: started adding support for auto-creation of NS glue record
       via  7da636f s4-dsdb: get GUID and SID for DSA from extended DN
       via  2b929b0 s4-dsdb: enable initial replication of partitions via DsReplicaSync
       via  86f5ecd s4-repl: get NCs to replicate from our NTDS object
       via  4efb4eb s4-dsdb: added support for replicating with GC partial attribute set
       via  677600f s4-dsdb: failing to find the object is not an error in dsdb_loadreps()
      from  585294e s3: Fix Coverity ID 2619: UNINIT

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


- Log -----------------------------------------------------------------
commit 0921e750018a53c02e9984006a48cb08cd370b92
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 22 09:58:39 2011 +1000

    s4-dbcheck: fixed transaction nesting in dbcheck
    
    ensure we don't cancel a transaction we didn't start
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User: Andrew Tridgell <tridge at samba.org>
    Autobuild-Date: Thu Sep 22 03:39:59 CEST 2011 on sn-devel-104

commit 4dbc604d9c055530f4f4440aae704ed9f9b81c6d
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 22 09:58:09 2011 +1000

    samba-tool: use show_recycled in dbchecker
    
    we need to use show_recycled instead of show_deleted in dbchecker to
    allow us to see recycled objects

commit b92e0a232eabc8e759ae18909d6f0d59d4e05736
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 22 09:57:26 2011 +1000

    s4-kdc: set NO_GLOBAL_CATALOG control in kdc
    
    the kdc doesn't want to find users who are in partialReplica
    partitions, as they won't have the needed secret info for the kdc to
    operate. We need to generate referrals instead
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 3e685f599580d5fe006a07511fa78c23f30dd5fb
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 22 09:56:27 2011 +1000

    s4-rpc: show binding string in failed rpc binds
    
    this makes debugging some RPC auth issues easier

commit 02872212ebd18f150d3e7cff5722698b770c9f90
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 22 09:55:55 2011 +1000

    s4-ldap-server: set the NO_GLOBAL_CATALOG control on non-GC operations
    
    this makes us honor GC semantics on the two ldap ports

commit 516f32654ae2897acd1d7095f18ac6eb0db09230
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 22 09:54:56 2011 +1000

    s4-repl: remove unused principal_name element

commit aba856c6668bbe56e2d84057bead31de1e08e2bd
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 22 09:52:29 2011 +1000

    s4-dsdb: load the partialReplica attribute in the @PARTITION object
    
    this modifies the partition module to honor a partialReplica attribute
    on the @PARTITION module, marking partiations as partial replicas so
    the NO_GLOBAL_CATALOG control can be honoured

commit 8c3d77d84c9627c9ed4e1164d4844f83345fdbd6
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 22 09:50:57 2011 +1000

    s4-repl: fill in GUID and SID from partition information
    
    when we find a NC via a DN string, fill in the GUID and SID so the
    caller can properly report them

commit 783ff68628fee6d5681b3a9abd80b74a78588926
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 22 09:49:54 2011 +1000

    s4-kcc: return partial replica NCs in drs showrepl
    
    the showrepl operation should return all our replicated NCs, including
    partial replicas

commit 00ef18f19c39bf5083939ac79854bcd1ccc7cef7
Author: Andrew Tridgell <tridge at samba.org>
Date:   Thu Sep 22 09:48:17 2011 +1000

    s4-dsdb: added NO_GLOBAL_CATALOG control
    
    this control is used to ask samdb to not return searches with a basedn
    in partial repica partitions, which is needed to support the
    difference between a search on the 3268 GC ldap port and the non-GC
    389 port

commit 73f2df6a378034455f44bb5ed94a7eba97e04448
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 21 08:59:30 2011 +1000

    s4-dns: started adding support for auto-creation of NS glue record
    
    when we create a new subdomain we need to create a NS glue record in
    the parent domain pointing at our subdomain

commit 7da636f33aa3e4e68f7462a33f9b7aa5663619d3
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 21 08:58:13 2011 +1000

    s4-dsdb: get GUID and SID for DSA from extended DN
    
    this allows us to use the DN from a hasPartialReplicaNCs attribute to
    create a reps1 object

commit 2b929b0b515ae6c3f000d1f522dbac542fff9546
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 21 08:56:32 2011 +1000

    s4-dsdb: enable initial replication of partitions via DsReplicaSync
    
    we need to create a temporary dsa object to allow the replication task
    to replicate a NC that is not listed in a repsFrom attribute

commit 86f5ecdc0c97b21be6d9d2f7be4e15b8d95af219
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 21 08:53:15 2011 +1000

    s4-repl: get NCs to replicate from our NTDS object
    
    we need to use the hasMasterNCs and hasPartialReplicaNCs attributes on
    our NTDS object to get the list of NCs to replicate, instead of using
    the rootDSE. This is needed to support replicating of GC partial
    replicas, which are not listed in the rootDSE

commit 4efb4ebe633350e8d260d1b063d6997001bedd06
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 21 08:52:14 2011 +1000

    s4-dsdb: added support for replicating with GC partial attribute set
    
    if we are replicating a partial replica, then we need to supply the
    partial attribute set we want to replicate to the server

commit 677600fb7f979b1ad486aadecf4d5a03a9508de3
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 21 08:51:20 2011 +1000

    s4-dsdb: failing to find the object is not an error in dsdb_loadreps()
    
    we may not have replicated the partition yet, so this should be
    considered the same as having no repsFrom/repsTo

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

Summary of changes:
 source4/dsdb/common/util.c                       |   22 ++-
 source4/dsdb/common/util.h                       |    1 +
 source4/dsdb/kcc/kcc_drs_replica_info.c          |   44 +++---
 source4/dsdb/repl/drepl_out_helpers.c            |   53 ++++++-
 source4/dsdb/repl/drepl_partitions.c             |  193 ++++++++++++++++------
 source4/dsdb/repl/drepl_service.c                |   10 +
 source4/dsdb/repl/drepl_service.h                |    4 +-
 source4/dsdb/samdb/ldb_modules/partition.c       |   12 ++
 source4/dsdb/samdb/ldb_modules/partition.h       |    1 +
 source4/dsdb/samdb/ldb_modules/partition_init.c  |   16 ++-
 source4/dsdb/samdb/samdb.h                       |    3 +
 source4/kdc/db-glue.c                            |    8 +-
 source4/ldap_server/ldap_backend.c               |    2 +
 source4/librpc/rpc/dcerpc_util.c                 |    3 +-
 source4/scripting/bin/samba_dnsupdate            |   38 ++++-
 source4/scripting/python/samba/dbchecker.py      |   29 ++--
 source4/scripting/python/samba/netcmd/dbcheck.py |    8 +-
 source4/setup/schema_samba4.ldif                 |    1 +
 18 files changed, 341 insertions(+), 107 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 3276ec8..cf28f1d 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -2667,13 +2667,18 @@ WERROR dsdb_loadreps(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, struct ld
 	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
 	unsigned int i;
 	struct ldb_message_element *el;
+	int ret;
 
 	*r = NULL;
 	*count = 0;
 
-	if (ldb_search(sam_ctx, tmp_ctx, &res, dn, LDB_SCOPE_BASE, attrs, NULL) != LDB_SUCCESS ||
-	    res->count < 1) {
-		DEBUG(0,("dsdb_loadreps: failed to read partition object\n"));
+	ret = dsdb_search_dn(sam_ctx, tmp_ctx, &res, dn, attrs, 0);
+	if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+		/* partition hasn't been replicated yet */
+		return WERR_OK;
+	}
+	if (ret != LDB_SUCCESS) {
+		DEBUG(0,("dsdb_loadreps: failed to read partition object: %s\n", ldb_errstring(sam_ctx)));
 		talloc_free(tmp_ctx);
 		return WERR_DS_DRA_INTERNAL_ERROR;
 	}
@@ -2747,7 +2752,7 @@ WERROR dsdb_savereps(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, struct ld
 		el->values[i] = v;
 	}
 
-	if (ldb_modify(sam_ctx, msg) != LDB_SUCCESS) {
+	if (dsdb_modify(sam_ctx, msg, 0) != LDB_SUCCESS) {
 		DEBUG(0,("Failed to store %s - %s\n", attr, ldb_errstring(sam_ctx)));
 		goto failed;
 	}
@@ -3653,6 +3658,15 @@ int dsdb_request_add_controls(struct ldb_request *req, uint32_t dsdb_flags)
 		}
 	}
 
+	if (dsdb_flags & DSDB_SEARCH_NO_GLOBAL_CATALOG) {
+		ret = ldb_request_add_control(req,
+					      DSDB_CONTROL_NO_GLOBAL_CATALOG,
+					      false, NULL);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
+	}
+
 	if (dsdb_flags & DSDB_SEARCH_SHOW_DELETED) {
 		ret = ldb_request_add_control(req, LDB_CONTROL_SHOW_DELETED_OID, true, NULL);
 		if (ret != LDB_SUCCESS) {
diff --git a/source4/dsdb/common/util.h b/source4/dsdb/common/util.h
index 0140f29..75ef49e 100644
--- a/source4/dsdb/common/util.h
+++ b/source4/dsdb/common/util.h
@@ -36,6 +36,7 @@
 #define DSDB_SEARCH_SHOW_RECYCLED	      0x0400
 #define DSDB_PROVISION			      0x0800
 #define DSDB_BYPASS_PASSWORD_HASH	      0x1000
+#define DSDB_SEARCH_NO_GLOBAL_CATALOG	      0x2000
 
 bool is_attr_in_list(const char * const * attrs, const char *attr);
 
diff --git a/source4/dsdb/kcc/kcc_drs_replica_info.c b/source4/dsdb/kcc/kcc_drs_replica_info.c
index ab77fa0..8eb7266 100644
--- a/source4/dsdb/kcc/kcc_drs_replica_info.c
+++ b/source4/dsdb/kcc/kcc_drs_replica_info.c
@@ -386,8 +386,9 @@ struct ncList {
 static WERROR get_master_ncs(TALLOC_CTX *mem_ctx, struct ldb_context *samdb,
 			     const char *ntds_guid_str, struct ncList **master_nc_list)
 {
-	const char *post_2003_attrs[] = { "msDs-hasMasterNCs", NULL };
-	const char *pre_2003_attrs[] = { "hasMasterNCs", NULL };
+	const char *post_2003_attrs[] = { "msDs-hasMasterNCs", "hasPartialReplicaNCs", NULL };
+	const char *pre_2003_attrs[] = { "hasMasterNCs", "hasPartialReplicaNCs", NULL };
+	const char **attrs = post_2003_attrs;
 	struct ldb_result *res;
 	struct ncList *nc_list = NULL;
 	struct ncList *nc_list_elem;
@@ -405,6 +406,7 @@ static WERROR get_master_ncs(TALLOC_CTX *mem_ctx, struct ldb_context *samdb,
 		DEBUG(0,(__location__ ": Failed objectguid search - %s\n", ldb_errstring(samdb)));
 
 		is_level_post_2003 = 0;
+		attrs = post_2003_attrs;
 		ret = ldb_search(samdb, mem_ctx, &res, ldb_get_config_basedn(samdb),
 			LDB_SCOPE_DEFAULT, pre_2003_attrs, "(objectguid=%s)", ntds_guid_str);
 	}
@@ -421,32 +423,26 @@ static WERROR get_master_ncs(TALLOC_CTX *mem_ctx, struct ldb_context *samdb,
 
 	for (i = 0; i < res->count; i++) {
 		struct ldb_message_element *msg_elem;
-		unsigned int k;
+		unsigned int k, a;
 
-		if (is_level_post_2003) {
-			msg_elem = ldb_msg_find_element(res->msgs[i], "msDs-hasMasterNCs");
-		} else {
-			msg_elem = ldb_msg_find_element(res->msgs[i], "hasMasterNCs");
-		}
-
-		if (!msg_elem || msg_elem->num_values == 0) {
-			DEBUG(0,(__location__ ": Failed: Attribute hasMasterNCs not found - %s\n",
-			      ldb_errstring(samdb)));
-			return WERR_INTERNAL_ERROR;
-		}
+		for (a=0; attrs[a]; a++) {
+			msg_elem = ldb_msg_find_element(res->msgs[i], attrs[a]);
+			if (!msg_elem || msg_elem->num_values == 0) {
+				continue;
+			}
 
-		for (k = 0; k < msg_elem->num_values; k++) {
-			/* copy the string on msg_elem->values[k]->data to nc_str */
-			nc_str = talloc_strndup(mem_ctx, (char *)msg_elem->values[k].data, msg_elem->values[k].length);
-			W_ERROR_HAVE_NO_MEMORY(nc_str);
+			for (k = 0; k < msg_elem->num_values; k++) {
+				/* copy the string on msg_elem->values[k]->data to nc_str */
+				nc_str = talloc_strndup(mem_ctx, (char *)msg_elem->values[k].data, msg_elem->values[k].length);
+				W_ERROR_HAVE_NO_MEMORY(nc_str);
 
-			nc_list_elem = talloc_zero(mem_ctx, struct ncList);
-			W_ERROR_HAVE_NO_MEMORY(nc_list_elem);
-			nc_list_elem->dn = ldb_dn_new(mem_ctx, samdb, nc_str);
-			W_ERROR_HAVE_NO_MEMORY(nc_list_elem);
-			DLIST_ADD(nc_list, nc_list_elem);
+				nc_list_elem = talloc_zero(mem_ctx, struct ncList);
+				W_ERROR_HAVE_NO_MEMORY(nc_list_elem);
+				nc_list_elem->dn = ldb_dn_new(mem_ctx, samdb, nc_str);
+				W_ERROR_HAVE_NO_MEMORY(nc_list_elem);
+				DLIST_ADD(nc_list, nc_list_elem);
+			}
 		}
-
 	}
 
 	*master_nc_list = nc_list;
diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c
index 19d0957..0ecea17 100644
--- a/source4/dsdb/repl/drepl_out_helpers.c
+++ b/source4/dsdb/repl/drepl_out_helpers.c
@@ -262,7 +262,7 @@ static void dreplsrv_op_pull_source_connect_done(struct tevent_req *subreq)
 static void dreplsrv_op_pull_source_get_changes_done(struct tevent_req *subreq);
 
 /*
-  get a partial attribute set for a replication call
+  get a RODC partial attribute set for a replication call
  */
 static NTSTATUS dreplsrv_get_rodc_partial_attribute_set(struct dreplsrv_service *service,
 							TALLOC_CTX *mem_ctx,
@@ -294,6 +294,47 @@ static NTSTATUS dreplsrv_get_rodc_partial_attribute_set(struct dreplsrv_service
 		pas->attids[pas->num_attids] = dsdb_attribute_get_attid(a, for_schema);
 		pas->num_attids++;
 	}
+
+	pas->attids = talloc_realloc(pas, pas->attids, enum drsuapi_DsAttributeId, pas->num_attids);
+	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(pas->attids, pas);
+
+	*_pas = pas;
+	return NT_STATUS_OK;
+}
+
+
+/*
+  get a GC partial attribute set for a replication call
+ */
+static NTSTATUS dreplsrv_get_gc_partial_attribute_set(struct dreplsrv_service *service,
+						      TALLOC_CTX *mem_ctx,
+						      struct drsuapi_DsPartialAttributeSet **_pas)
+{
+	struct drsuapi_DsPartialAttributeSet *pas;
+	struct dsdb_schema *schema;
+	uint32_t i;
+
+	pas = talloc_zero(mem_ctx, struct drsuapi_DsPartialAttributeSet);
+	NT_STATUS_HAVE_NO_MEMORY(pas);
+
+	schema = dsdb_get_schema(service->samdb, NULL);
+
+	pas->version = 1;
+	pas->attids = talloc_array(pas, enum drsuapi_DsAttributeId, schema->num_attributes);
+	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(pas->attids, pas);
+
+	for (i=0; i<schema->num_attributes; i++) {
+		struct dsdb_attribute *a;
+		a = schema->attributes_by_attributeID_id[i];
+                if (a->isMemberOfPartialAttributeSet) {
+			pas->attids[pas->num_attids] = dsdb_attribute_get_attid(a, false);
+			pas->num_attids++;
+		}
+	}
+
+	pas->attids = talloc_realloc(pas, pas->attids, enum drsuapi_DsAttributeId, pas->num_attids);
+	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(pas->attids, pas);
+
 	*_pas = pas;
 	return NT_STATUS_OK;
 }
@@ -374,7 +415,13 @@ static void dreplsrv_op_pull_source_get_changes_trigger(struct tevent_req *req)
 
 	replica_flags = rf1->replica_flags;
 
-	if (service->am_rodc) {
+	if (partition->partial_replica) {
+		status = dreplsrv_get_gc_partial_attribute_set(service, r, &pas);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(0,(__location__ ": Failed to construct GC partial attribute set : %s\n", nt_errstr(status)));
+			return;
+		}
+	} else if (service->am_rodc) {
 		bool for_schema = false;
 		if (ldb_dn_compare_base(ldb_get_schema_basedn(service->samdb), partition->dn) == 0) {
 			for_schema = true;
@@ -382,7 +429,7 @@ static void dreplsrv_op_pull_source_get_changes_trigger(struct tevent_req *req)
 
 		status = dreplsrv_get_rodc_partial_attribute_set(service, r, &pas, for_schema);
 		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(0,(__location__ ": Failed to construct partial attribute set : %s\n", nt_errstr(status)));
+			DEBUG(0,(__location__ ": Failed to construct RODC partial attribute set : %s\n", nt_errstr(status)));
 			return;
 		}
 		if (state->op->extended_op == DRSUAPI_EXOP_REPL_SECRET) {
diff --git a/source4/dsdb/repl/drepl_partitions.c b/source4/dsdb/repl/drepl_partitions.c
index e0f4045..f9bb3f0 100644
--- a/source4/dsdb/repl/drepl_partitions.c
+++ b/source4/dsdb/repl/drepl_partitions.c
@@ -32,57 +32,93 @@
 #include "librpc/gen_ndr/ndr_drsblobs.h"
 #include "libcli/security/security.h"
 #include "param/param.h"
+#include "dsdb/common/util.h"
 
 WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
 {
 	WERROR status;
-	static const char *attrs[] = { "namingContexts", NULL };
+	static const char *attrs[] = { "hasMasterNCs", "hasPartialReplicaNCs", NULL };
 	unsigned int i;
 	int ret;
 	TALLOC_CTX *tmp_ctx;
 	struct ldb_result *res;
 	struct ldb_message_element *el;
+	struct ldb_dn *ntds_dn;
 
 	tmp_ctx = talloc_new(s);
 	W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
 
-	ret = ldb_search(s->samdb, tmp_ctx, &res,
-			 ldb_dn_new(tmp_ctx, s->samdb, ""), LDB_SCOPE_BASE, attrs, NULL);
+	ntds_dn = samdb_ntds_settings_dn(s->samdb);
+	if (!ntds_dn) {
+		DEBUG(1,(__location__ ": Unable to find ntds_dn: %s\n", ldb_errstring(s->samdb)));
+		talloc_free(tmp_ctx);
+		return WERR_DS_DRA_INTERNAL_ERROR;
+	}
+
+	ret = dsdb_search_dn(s->samdb, tmp_ctx, &res, ntds_dn, attrs, DSDB_SEARCH_SHOW_EXTENDED_DN);
 	if (ret != LDB_SUCCESS) {
-		DEBUG(1,("Searching for namingContexts in rootDSE failed: %s\n", ldb_errstring(s->samdb)));
+		DEBUG(1,("Searching for hasMasterNCs in NTDS DN failed: %s\n", ldb_errstring(s->samdb)));
 		talloc_free(tmp_ctx);
 		return WERR_DS_DRA_INTERNAL_ERROR;
-       }
+	}
+
+	el = ldb_msg_find_element(res->msgs[0], "hasMasterNCs");
+	if (!el) {
+		DEBUG(1,("Finding hasMasterNCs element in root_res failed: %s\n",
+			 ldb_errstring(s->samdb)));
+		talloc_free(tmp_ctx);
+		return WERR_DS_DRA_INTERNAL_ERROR;
+	}
+
+	for (i=0; i<el->num_values; i++) {
+		struct ldb_dn *pdn;
+		struct dreplsrv_partition *p;
+
+		pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]);
+		if (pdn == NULL) {
+			talloc_free(tmp_ctx);
+			return WERR_DS_DRA_INTERNAL_ERROR;
+		}
+		if (!ldb_dn_validate(pdn)) {
+			return WERR_DS_DRA_INTERNAL_ERROR;
+		}
+
+		p = talloc_zero(s, struct dreplsrv_partition);
+		W_ERROR_HAVE_NO_MEMORY(p);
 
-       el = ldb_msg_find_element(res->msgs[0], "namingContexts");
-       if (!el) {
-               DEBUG(1,("Finding namingContexts element in root_res failed: %s\n",
-			ldb_errstring(s->samdb)));
-	       talloc_free(tmp_ctx);
-	       return WERR_DS_DRA_INTERNAL_ERROR;
-       }
+		p->dn = talloc_steal(p, pdn);
+		p->service = s;
 
-       for (i=0; i<el->num_values; i++) {
-	       struct ldb_dn *pdn;
-	       struct dreplsrv_partition *p;
+		DLIST_ADD(s->partitions, p);
 
-	       pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]);
-	       if (pdn == NULL) {
-		       talloc_free(tmp_ctx);
-		       return WERR_DS_DRA_INTERNAL_ERROR;
-	       }
-	       if (!ldb_dn_validate(pdn)) {
-		       return WERR_DS_DRA_INTERNAL_ERROR;
-	       }
+		DEBUG(2, ("dreplsrv_partition[%s] loaded\n", ldb_dn_get_linearized(p->dn)));
+	}
 
-	       p = talloc_zero(s, struct dreplsrv_partition);
-	       W_ERROR_HAVE_NO_MEMORY(p);
+	el = ldb_msg_find_element(res->msgs[0], "hasPartialReplicaNCs");
 
-	       p->dn = talloc_steal(p, pdn);
+	for (i=0; el && i<el->num_values; i++) {
+		struct ldb_dn *pdn;
+		struct dreplsrv_partition *p;
 
-	       DLIST_ADD(s->partitions, p);
+		pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]);
+		if (pdn == NULL) {
+			talloc_free(tmp_ctx);
+			return WERR_DS_DRA_INTERNAL_ERROR;
+		}
+		if (!ldb_dn_validate(pdn)) {
+			return WERR_DS_DRA_INTERNAL_ERROR;
+		}
 
-	       DEBUG(2, ("dreplsrv_partition[%s] loaded\n", ldb_dn_get_linearized(p->dn)));
+		p = talloc_zero(s, struct dreplsrv_partition);
+		W_ERROR_HAVE_NO_MEMORY(p);
+
+		p->dn = talloc_steal(p, pdn);
+		p->partial_replica = true;
+		p->service = s;
+
+		DLIST_ADD(s->partitions, p);
+
+		DEBUG(2, ("dreplsrv_partition[%s] loaded (partial replica)\n", ldb_dn_get_linearized(p->dn)));
 	}
 
 	talloc_free(tmp_ctx);
@@ -297,8 +333,8 @@ static WERROR dreplsrv_partition_add_source_dsa(struct dreplsrv_service *s,
 }
 
 WERROR dreplsrv_partition_find_for_nc(struct dreplsrv_service *s,
-				      const struct GUID *nc_guid,
-				      const struct dom_sid *nc_sid,
+				      struct GUID *nc_guid,
+				      struct dom_sid *nc_sid,
 				      const char *nc_dn_str,
 				      struct dreplsrv_partition **_p)
 {
@@ -321,6 +357,13 @@ WERROR dreplsrv_partition_find_for_nc(struct dreplsrv_service *s,
 		    || strequal(p->nc.dn, nc_dn_str)
 		    || (valid_sid && dom_sid_equal(&p->nc.sid, nc_sid)))
 		{
+			/* fill in he right guid and sid if possible */
+			if (nc_guid && !valid_guid) {
+				dsdb_get_extended_dn_guid(p->dn, nc_guid, "GUID");
+			}
+			if (nc_sid && !valid_sid) {
+				dsdb_get_extended_dn_sid(p->dn, nc_sid, "SID");
+			}
 			*_p = p;
 			return WERR_OK;
 		}
@@ -369,44 +412,92 @@ WERROR dreplsrv_partition_source_dsa_by_dns(const struct dreplsrv_partition *p,
 }
 
 
+/*
+  create a temporary dsa structure for a replication. This is needed
+  for the initial replication of a new partition, such as when a new
+  domain NC is created and we are a global catalog server
+ */
+WERROR dreplsrv_partition_source_dsa_temporary(struct dreplsrv_partition *p,
+					       TALLOC_CTX *mem_ctx,
+					       const struct GUID *dsa_guid,
+					       struct dreplsrv_partition_source_dsa **_dsa)
+{
+	struct dreplsrv_partition_source_dsa *dsa;
+	WERROR werr;
+
+	dsa = talloc_zero(mem_ctx, struct dreplsrv_partition_source_dsa);
+	W_ERROR_HAVE_NO_MEMORY(dsa);
+
+	dsa->partition = p;
+	dsa->repsFrom1 = &dsa->_repsFromBlob.ctr.ctr1;
+	dsa->repsFrom1->replica_flags = 0;
+	dsa->repsFrom1->source_dsa_obj_guid = *dsa_guid;
+
+	dsa->repsFrom1->other_info = talloc_zero(dsa, struct repsFromTo1OtherInfo);
+	W_ERROR_HAVE_NO_MEMORY(dsa->repsFrom1->other_info);
+
+	dsa->repsFrom1->other_info->dns_name = samdb_ntds_msdcs_dns_name(p->service->samdb,
+									 dsa->repsFrom1->other_info, dsa_guid);
+	W_ERROR_HAVE_NO_MEMORY(dsa->repsFrom1->other_info->dns_name);
+
+	werr = dreplsrv_out_connection_attach(p->service, dsa->repsFrom1, &dsa->conn);
+	if (!W_ERROR_IS_OK(werr)) {
+		DEBUG(0,(__location__ ": Failed to attach connection to %s\n",
+			 ldb_dn_get_linearized(p->dn)));
+		talloc_free(dsa);
+		return werr;
+	}
+
+	*_dsa = dsa;
+
+	return WERR_OK;
+}
+
+
 static WERROR dreplsrv_refresh_partition(struct dreplsrv_service *s,
 					 struct dreplsrv_partition *p)
 {
 	WERROR status;
-	struct dom_sid *nc_sid;
+	NTSTATUS ntstatus;
 	struct ldb_message_element *orf_el = NULL;
-	struct ldb_result *r;
+	struct ldb_result *r = NULL;
 	unsigned int i;
 	int ret;
 	TALLOC_CTX *mem_ctx = talloc_new(p);
 	static const char *attrs[] = {
-		"objectSid",
-		"objectGUID",
 		"repsFrom",
 		"repsTo",
 		NULL
 	};
+	struct ldb_dn *dn;
 
 	DEBUG(4, ("dreplsrv_refresh_partition(%s)\n",
 		ldb_dn_get_linearized(p->dn)));
 
-	ret = ldb_search(s->samdb, mem_ctx, &r, p->dn, LDB_SCOPE_BASE, attrs,
-			 "(objectClass=*)");
-	if (ret != LDB_SUCCESS) {
+	ret = dsdb_search_dn(s->samdb, mem_ctx, &r, p->dn, attrs, DSDB_SEARCH_SHOW_EXTENDED_DN);
+	if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+		/* we haven't replicated the partition yet, but we
+		 * can fill in the guid, sid etc from the partition DN */
+		dn = p->dn;
+	} else if (ret != LDB_SUCCESS) {
 		talloc_free(mem_ctx);
 		return WERR_FOOBAR;
+	} else {
+		dn = r->msgs[0]->dn;
 	}
 	
 	talloc_free(discard_const(p->nc.dn));
 	ZERO_STRUCT(p->nc);
-	p->nc.dn	= ldb_dn_alloc_linearized(p, p->dn);
+	p->nc.dn	= ldb_dn_alloc_linearized(p, dn);
 	W_ERROR_HAVE_NO_MEMORY(p->nc.dn);
-	p->nc.guid	= samdb_result_guid(r->msgs[0], "objectGUID");
-	nc_sid		= samdb_result_dom_sid(p, r->msgs[0], "objectSid");
-	if (nc_sid) {
-		p->nc.sid	= *nc_sid;
-		talloc_free(nc_sid);
+	ntstatus = dsdb_get_extended_dn_guid(dn, &p->nc.guid, "GUID");
+	if (!NT_STATUS_IS_OK(ntstatus)) {
+		DEBUG(0,(__location__ ": unable to get GUID for %s: %s\n",
+			 p->nc.dn, nt_errstr(ntstatus)));
+		talloc_free(mem_ctx);
+		return WERR_DS_DRA_INTERNAL_ERROR;
 	}
+	dsdb_get_extended_dn_sid(dn, &p->nc.sid, "SID");
 
 	talloc_free(p->uptodatevector.cursors);
 	talloc_free(p->uptodatevector_ex.cursors);
@@ -418,27 +509,27 @@ static WERROR dreplsrv_refresh_partition(struct dreplsrv_service *s,
 		DEBUG(4,(__location__ ": no UDV available for %s\n", ldb_dn_get_linearized(p->dn)));
 	}
 
-	orf_el = ldb_msg_find_element(r->msgs[0], "repsFrom");
-	if (orf_el) {
+	status = WERR_OK;
+
+	if (r != NULL && (orf_el = ldb_msg_find_element(r->msgs[0], "repsFrom"))) {
 		for (i=0; i < orf_el->num_values; i++) {
 			status = dreplsrv_partition_add_source_dsa(s, p, &p->sources, 
 								   NULL, &orf_el->values[i]);
-			W_ERROR_NOT_OK_RETURN(status);	
+			W_ERROR_NOT_OK_GOTO_DONE(status);
 		}
 	}
 
-	orf_el = ldb_msg_find_element(r->msgs[0], "repsTo");
-	if (orf_el) {
+	if (r != NULL && (orf_el = ldb_msg_find_element(r->msgs[0], "repsTo"))) {
 		for (i=0; i < orf_el->num_values; i++) {
 			status = dreplsrv_partition_add_source_dsa(s, p, &p->notifies, 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list