[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Wed Jun 1 12:02:04 UTC 2016


The branch, master has been updated
       via  01043fc repl_meta_data: Do rename before deleted object cleanup
       via  cb32e25f dsdb/subtree_rename: Rename the base before we rename children
       via  2d9383e getncchanges: Fill in ctr6.linked_attributes with a pointer to a zero-length array
       via  b8f3252 getncchanges: Use the talloc_stackframe() for tempory memory
       via  59d6c7c getncchanges: Give the correct error when RID_ALLOC fails on an invalid destination_dsa_guid
       via  dfda458 rpc_server/drsuapi: Return the correct 3 objects for DRSUAPI_EXOP_FSMO_RID_ALLOC
      from  c0b17c3 ctdb:tests: timedout->timed out in 60.nfs.multi.004 test

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


- Log -----------------------------------------------------------------
commit 01043fc5f549b61cf3e203cb660e3235d48184c0
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Mar 22 12:07:27 2016 +1300

    repl_meta_data: Do rename before deleted object cleanup
    
    Following from the lesson of subtree_rename, do the rename first,
    as this is more likely to fail for some reason
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Wed Jun  1 14:01:36 CEST 2016 on sn-devel-144

commit cb32e25fbecb435b840deddf873aea8d89a3c506
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Mar 15 15:35:21 2016 +1300

    dsdb/subtree_rename: Rename the base before we rename children
    
    Otherwise, we might rename children to be under a different, conflicting, DN.
    
    This would normally be picked up in the transaction rollback, but in replication
    the transaction is not aborted for this situation
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>

commit 2d9383e1d4aef758ec2fdaa57203e9a0dbcbca2f
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Mar 14 11:10:04 2016 +1300

    getncchanges: Fill in ctr6.linked_attributes with a pointer to a zero-length array
    
    Our newly run repl_exop tests expect this, matching Windows 2012R2
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>

commit b8f32528c7939ed47a52e99cfeb03009251bb9d7
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Mar 14 11:09:02 2016 +1300

    getncchanges: Use the talloc_stackframe() for tempory memory
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>

commit 59d6c7c6749fba003ca4895cfd7c177ca455d81f
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Mar 14 11:06:39 2016 +1300

    getncchanges: Give the correct error when RID_ALLOC fails on an invalid destination_dsa_guid
    
    This is found by our new tests.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>

commit dfda45802c7d30d00eab757497e598732c062e81
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Mar 4 13:12:12 2016 +1300

    rpc_server/drsuapi: Return the correct 3 objects for DRSUAPI_EXOP_FSMO_RID_ALLOC
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>

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

Summary of changes:
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c |  17 +-
 source4/dsdb/samdb/ldb_modules/subtree_rename.c |  80 +++-----
 source4/rpc_server/drsuapi/getncchanges.c       | 243 ++++++++++++++++++++----
 3 files changed, 246 insertions(+), 94 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index f65cc65..c0c8de5 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -3495,14 +3495,6 @@ static int replmd_delete_internals(struct ldb_module *module, struct ldb_request
 	 *
 	 */
 
-	ret = dsdb_module_modify(module, msg, DSDB_FLAG_OWN_MODULE, req);
-	if (ret != LDB_SUCCESS) {
-		ldb_asprintf_errstring(ldb, "replmd_delete: Failed to modify object %s in delete - %s",
-				       ldb_dn_get_linearized(old_dn), ldb_errstring(ldb));
-		talloc_free(tmp_ctx);
-		return ret;
-	}
-
 	/*
 	 * No matter what has happned with other renames, try again to
 	 * get this to be under the deleted DN.
@@ -3518,6 +3510,15 @@ static int replmd_delete_internals(struct ldb_module *module, struct ldb_request
 			talloc_free(tmp_ctx);
 			return ret;
 		}
+		msg->dn = new_dn;
+	}
+
+	ret = dsdb_module_modify(module, msg, DSDB_FLAG_OWN_MODULE, req);
+	if (ret != LDB_SUCCESS) {
+		ldb_asprintf_errstring(ldb, "replmd_delete: Failed to modify object %s in delete - %s",
+				       ldb_dn_get_linearized(old_dn), ldb_errstring(ldb));
+		talloc_free(tmp_ctx);
+		return ret;
 	}
 
 	talloc_free(tmp_ctx);
diff --git a/source4/dsdb/samdb/ldb_modules/subtree_rename.c b/source4/dsdb/samdb/ldb_modules/subtree_rename.c
index b9ecb3f..57020e1 100644
--- a/source4/dsdb/samdb/ldb_modules/subtree_rename.c
+++ b/source4/dsdb/samdb/ldb_modules/subtree_rename.c
@@ -39,6 +39,7 @@
 struct subtree_rename_context {
 	struct ldb_module *module;
 	struct ldb_request *req;
+	bool base_renamed;
 };
 
 static struct subtree_rename_context *subren_ctx_init(struct ldb_module *module,
@@ -54,48 +55,15 @@ static struct subtree_rename_context *subren_ctx_init(struct ldb_module *module,
 
 	ac->module = module;
 	ac->req = req;
+	ac->base_renamed = false;
 
 	return ac;
 }
 
-static int subtree_rename_callback(struct ldb_request *req,
-				   struct ldb_reply *ares)
-{
-	struct ldb_context *ldb;
-	struct subtree_rename_context *ac;
-
-	ac = talloc_get_type(req->context, struct subtree_rename_context);
-	ldb = ldb_module_get_ctx(ac->module);
-
-	if (!ares) {
-		return ldb_module_done(ac->req, NULL, NULL,
-					LDB_ERR_OPERATIONS_ERROR);
-	}
-
-	if (ares->type == LDB_REPLY_REFERRAL) {
-		return ldb_module_send_referral(ac->req, ares->referral);
-	}
-
-	if (ares->error != LDB_SUCCESS) {
-		return ldb_module_done(ac->req, ares->controls,
-					ares->response, ares->error);
-	}
-
-	if (ares->type != LDB_REPLY_DONE) {
-		ldb_asprintf_errstring(ldb, "Invalid LDB reply type %d", ares->type);
-		return ldb_module_done(ac->req, NULL, NULL,
-					LDB_ERR_OPERATIONS_ERROR);
-	}
-
-	talloc_free(ares);
-	return ldb_module_done(ac->req, NULL, NULL, LDB_SUCCESS);
-}
-
 static int subtree_rename_search_onelevel_callback(struct ldb_request *req,
 						   struct ldb_reply *ares)
 {
 	struct subtree_rename_context *ac;
-	struct ldb_request *rename_req;
 	int ret;
 
 	ac = talloc_get_type(req->context, struct subtree_rename_context);
@@ -109,11 +77,26 @@ static int subtree_rename_search_onelevel_callback(struct ldb_request *req,
 					ares->response, ares->error);
 	}
 
+	if (ac->base_renamed == false) {
+		ac->base_renamed = true;
+
+		ret = dsdb_module_rename(ac->module,
+					 ac->req->op.rename.olddn,
+					 ac->req->op.rename.newdn,
+					 DSDB_FLAG_NEXT_MODULE, req);
+		if (ret != LDB_SUCCESS) {
+			return ldb_module_done(ac->req, NULL, NULL, ret);
+		}
+	}
+
 	switch (ares->type) {
 	case LDB_REPLY_ENTRY:
 	{
-		struct ldb_dn *old_dn = ares->message->dn;
-		struct ldb_dn *new_dn = ldb_dn_copy(ares, old_dn);
+		struct ldb_dn *old_dn = NULL;
+		struct ldb_dn *new_dn = NULL;
+
+		old_dn = ares->message->dn;
+		new_dn = ldb_dn_copy(ares, old_dn);
 		if (!new_dn) {
 			return ldb_module_oom(ac->module);
 		}
@@ -130,7 +113,7 @@ static int subtree_rename_search_onelevel_callback(struct ldb_request *req,
 		}
 		ret = dsdb_module_rename(ac->module, old_dn, new_dn, DSDB_FLAG_OWN_MODULE, req);
 		if (ret != LDB_SUCCESS) {
-			return ret;
+			return ldb_module_done(ac->req, NULL, NULL, ret);
 		}
 
 		talloc_free(ares);
@@ -140,22 +123,17 @@ static int subtree_rename_search_onelevel_callback(struct ldb_request *req,
 	case LDB_REPLY_REFERRAL:
 		/* ignore */
 		break;
-
 	case LDB_REPLY_DONE:
-
-		ret = ldb_build_rename_req(&rename_req, ldb_module_get_ctx(ac->module), ac,
-					   ac->req->op.rename.olddn,
-					   ac->req->op.rename.newdn,
-					   ac->req->controls,
-					   ac, subtree_rename_callback,
-					   ac->req);
-		LDB_REQ_SET_LOCATION(req);
-		if (ret != LDB_SUCCESS) {
-			return ret;
-		}
-
 		talloc_free(ares);
-		return ldb_next_request(ac->module, rename_req);
+		return ldb_module_done(ac->req, NULL, NULL, LDB_SUCCESS);
+	default:
+	{
+		struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
+
+		ldb_asprintf_errstring(ldb, "Invalid LDB reply type %d", ares->type);
+		return ldb_module_done(ac->req, NULL, NULL,
+					LDB_ERR_OPERATIONS_ERROR);
+	}
 	}
 
 	return LDB_SUCCESS;
diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c
index 319ef15..6b961bc 100644
--- a/source4/rpc_server/drsuapi/getncchanges.c
+++ b/source4/rpc_server/drsuapi/getncchanges.c
@@ -4,8 +4,9 @@
    implement the DSGetNCChanges call
 
    Copyright (C) Anatoliy Atanasov 2009
-   Copyright (C) Andrew Tridgell 2009
-   
+   Copyright (C) Andrew Tridgell 2009-2010
+   Copyright (C) Andrew Bartlett 2010-2016
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
@@ -742,9 +743,10 @@ static int site_res_cmp_usn_order(struct drsuapi_changed_objects *m1,
 static WERROR getncchanges_rid_alloc(struct drsuapi_bind_state *b_state,
 				     TALLOC_CTX *mem_ctx,
 				     struct drsuapi_DsGetNCChangesRequest10 *req10,
-				     struct drsuapi_DsGetNCChangesCtr6 *ctr6)
+				     struct drsuapi_DsGetNCChangesCtr6 *ctr6,
+				     struct ldb_dn **rid_manager_dn)
 {
-	struct ldb_dn *rid_manager_dn, *req_dn;
+	struct ldb_dn *req_dn, *ntds_dn = NULL;
 	int ret;
 	struct ldb_context *ldb = b_state->sam_ctx;
 	struct ldb_result *ext_res;
@@ -757,8 +759,8 @@ static WERROR getncchanges_rid_alloc(struct drsuapi_bind_state *b_state,
 	    - verify that we are the RID Manager
 	 */
 
-	/* work out who is the RID Manager */
-	ret = samdb_rid_manager_dn(ldb, mem_ctx, &rid_manager_dn);
+	/* work out who is the RID Manager, also return to caller */
+	ret = samdb_rid_manager_dn(ldb, mem_ctx, rid_manager_dn);
 	if (ret != LDB_SUCCESS) {
 		DEBUG(0, (__location__ ": Failed to find RID Manager object - %s\n", ldb_errstring(ldb)));
 		return WERR_DS_DRA_INTERNAL_ERROR;
@@ -766,7 +768,7 @@ static WERROR getncchanges_rid_alloc(struct drsuapi_bind_state *b_state,
 
 	req_dn = drs_ObjectIdentifier_to_dn(mem_ctx, ldb, req10->naming_context);
 	if (!ldb_dn_validate(req_dn) ||
-	    ldb_dn_compare(req_dn, rid_manager_dn) != 0) {
+	    ldb_dn_compare(req_dn, *rid_manager_dn) != 0) {
 		/* that isn't the RID Manager DN */
 		DEBUG(0,(__location__ ": RID Alloc request for wrong DN %s\n",
 			 drs_ObjectIdentifier_to_string(mem_ctx, req10->naming_context)));
@@ -774,8 +776,17 @@ static WERROR getncchanges_rid_alloc(struct drsuapi_bind_state *b_state,
 		return WERR_OK;
 	}
 
+	/* TODO: make sure ntds_dn is a valid nTDSDSA object */
+	ret = dsdb_find_dn_by_guid(ldb, mem_ctx, &req10->destination_dsa_guid, 0, &ntds_dn);
+	if (ret != LDB_SUCCESS) {
+		DEBUG(0, (__location__ ": Unable to find NTDS object for guid %s - %s\n",
+			  GUID_string(mem_ctx, &req10->destination_dsa_guid), ldb_errstring(ldb)));
+		ctr6->extended_ret = DRSUAPI_EXOP_ERR_UNKNOWN_CALLER;
+		return WERR_OK;
+	}
+
 	/* find the DN of the RID Manager */
-	ret = samdb_reference_dn_is_our_ntdsa(ldb, rid_manager_dn, "fSMORoleOwner", &is_us);
+	ret = samdb_reference_dn_is_our_ntdsa(ldb, *rid_manager_dn, "fSMORoleOwner", &is_us);
 	if (ret != LDB_SUCCESS) {
 		DEBUG(0,("Failed to find fSMORoleOwner in RID Manager object\n"));
 		ctr6->extended_ret = DRSUAPI_EXOP_ERR_FSMO_NOT_OWNER;
@@ -802,15 +813,6 @@ static WERROR getncchanges_rid_alloc(struct drsuapi_bind_state *b_state,
 		return WERR_DS_DRA_INTERNAL_ERROR;
 	}
 
-	/*
-	 * FIXME (kim): this is a temp hack to return just few object,
-	 * but not the whole domain NC.
-	 * We should remove this hack and implement a 'scope'
-	 * building function to return just the set of object
-	 * documented for DRSUAPI_EXOP_FSMO_RID_ALLOC extended_op
-	 */
-	ldb_sequence_number(ldb, LDB_SEQ_HIGHEST_SEQ, &req10->highwatermark.highest_usn);
-
 	ret = ldb_extended(ldb, DSDB_EXTENDED_ALLOCATE_RID_POOL, exop, &ext_res);
 	if (ret != LDB_SUCCESS) {
 		DEBUG(0,(__location__ ": Failed extended allocation RID pool operation - %s\n",
@@ -1382,6 +1384,9 @@ getncchanges_map_req8(TALLOC_CTX *mem_ctx,
 	return req10;
 }
 
+static const char *collect_objects_attrs[] = { "uSNChanged",
+					       "objectGUID" ,
+					       NULL };
 
 /**
  * Collects object for normal replication cycle.
@@ -1398,9 +1403,6 @@ static WERROR getncchanges_collect_objects(struct drsuapi_bind_state *b_state,
 	enum ldb_scope scope = LDB_SCOPE_SUBTREE;
 	//const char *extra_filter;
 	struct drsuapi_getncchanges_state *getnc_state = b_state->getncchanges_state;
-	const char *attrs[] = { "uSNChanged",
-				"objectGUID" ,
-				NULL };
 
 	if (req10->extended_op == DRSUAPI_EXOP_REPL_OBJ ||
 	    req10->extended_op == DRSUAPI_EXOP_REPL_SECRET) {
@@ -1437,7 +1439,8 @@ static WERROR getncchanges_collect_objects(struct drsuapi_bind_state *b_state,
 	DEBUG(2,(__location__ ": getncchanges on %s using filter %s\n",
 		 ldb_dn_get_linearized(getnc_state->ncRoot_dn), search_filter));
 	ret = drsuapi_search_with_extended_dn(b_state->sam_ctx, getnc_state, search_res,
-					      search_dn, scope, attrs,
+					      search_dn, scope,
+					      collect_objects_attrs,
 					      search_filter);
 	if (ret != LDB_SUCCESS) {
 		return WERR_DS_DRA_INTERNAL_ERROR;
@@ -1462,10 +1465,156 @@ static WERROR getncchanges_collect_objects_exop(struct drsuapi_bind_state *b_sta
 		return WERR_OK;
 	}
 
-	/* TODO: implement extended op specific collection
-	 * of objects. Right now we just normal procedure
-	 * for collecting objects */
-	return getncchanges_collect_objects(b_state, mem_ctx, req10, search_dn, extra_filter, search_res);
+	switch (req10->extended_op) {
+	case DRSUAPI_EXOP_FSMO_RID_ALLOC:
+	{
+		int ret;
+		struct ldb_dn *ntds_dn = NULL;
+		struct ldb_dn *server_dn = NULL;
+		struct ldb_dn *machine_dn = NULL;
+		struct ldb_dn *rid_set_dn = NULL;
+		struct ldb_result *search_res2 = NULL;
+		struct ldb_result *search_res3 = NULL;
+		TALLOC_CTX *frame = talloc_stackframe();
+		/* get RID manager, RID set and server DN (in that order) */
+
+		/* This first search will get the RID Manager */
+		ret = drsuapi_search_with_extended_dn(b_state->sam_ctx, frame,
+						      search_res,
+						      search_dn, LDB_SCOPE_BASE,
+						      collect_objects_attrs,
+						      NULL);
+		if (ret != LDB_SUCCESS) {
+			DEBUG(1, ("DRSUAPI_EXOP_FSMO_RID_ALLOC: Failed to get RID Manager object %s - %s",
+				  ldb_dn_get_linearized(search_dn),
+				  ldb_errstring(b_state->sam_ctx)));
+			TALLOC_FREE(frame);
+			return WERR_DS_DRA_INTERNAL_ERROR;
+		}
+
+		if ((*search_res)->count != 1) {
+			DEBUG(1, ("DRSUAPI_EXOP_FSMO_RID_ALLOC: Failed to get RID Manager object %s - %u objects returned",
+				  ldb_dn_get_linearized(search_dn),
+				  (*search_res)->count));
+			TALLOC_FREE(frame);
+			return WERR_DS_DRA_INTERNAL_ERROR;
+		}
+
+		/* Now extend it to the RID set */
+
+		/* Find the computer account DN for the destination
+		 * dsa GUID specified */
+
+		ret = dsdb_find_dn_by_guid(b_state->sam_ctx, frame,
+					   &req10->destination_dsa_guid, 0,
+					   &ntds_dn);
+		if (ret != LDB_SUCCESS) {
+			DEBUG(1, ("DRSUAPI_EXOP_FSMO_RID_ALLOC: Unable to find NTDS object for guid %s - %s\n",
+				  GUID_string(frame,
+					      &req10->destination_dsa_guid),
+				  ldb_errstring(b_state->sam_ctx)));
+			TALLOC_FREE(frame);
+			return WERR_DS_DRA_INTERNAL_ERROR;
+		}
+
+		server_dn = ldb_dn_get_parent(frame, ntds_dn);
+		if (!server_dn) {
+			TALLOC_FREE(frame);
+			return WERR_DS_DRA_INTERNAL_ERROR;
+		}
+
+		ret = samdb_reference_dn(b_state->sam_ctx, frame, server_dn,
+					 "serverReference", &machine_dn);
+		if (ret != LDB_SUCCESS) {
+			DEBUG(1, ("DRSUAPI_EXOP_FSMO_RID_ALLOC: Failed to find serverReference in %s - %s",
+				  ldb_dn_get_linearized(server_dn),
+				  ldb_errstring(b_state->sam_ctx)));
+			TALLOC_FREE(frame);
+			return WERR_DS_DRA_INTERNAL_ERROR;
+		}
+
+		ret = samdb_reference_dn(b_state->sam_ctx, frame, machine_dn,
+					 "rIDSetReferences", &rid_set_dn);
+		if (ret != LDB_SUCCESS) {
+			DEBUG(1, ("DRSUAPI_EXOP_FSMO_RID_ALLOC: Failed to find rIDSetReferences in %s - %s",
+				  ldb_dn_get_linearized(server_dn),
+				  ldb_errstring(b_state->sam_ctx)));
+			TALLOC_FREE(frame);
+			return WERR_DS_DRA_INTERNAL_ERROR;
+		}
+
+
+		/* This first search will get the RID Manager, now get the RID set */
+		ret = drsuapi_search_with_extended_dn(b_state->sam_ctx, frame,
+						      &search_res2,
+						      rid_set_dn, LDB_SCOPE_BASE,
+						      collect_objects_attrs,
+						      NULL);
+		if (ret != LDB_SUCCESS) {
+			DEBUG(1, ("DRSUAPI_EXOP_FSMO_RID_ALLOC: Failed to get RID Set object %s - %s",
+				  ldb_dn_get_linearized(rid_set_dn),
+				  ldb_errstring(b_state->sam_ctx)));
+			TALLOC_FREE(frame);
+			return WERR_DS_DRA_INTERNAL_ERROR;
+		}
+
+		if (search_res2->count != 1) {
+			DEBUG(1, ("DRSUAPI_EXOP_FSMO_RID_ALLOC: Failed to get RID Set object %s - %u objects returned",
+				  ldb_dn_get_linearized(rid_set_dn),
+				  search_res2->count));
+			TALLOC_FREE(frame);
+			return WERR_DS_DRA_INTERNAL_ERROR;
+		}
+
+		/* Finally get the server DN */
+		ret = drsuapi_search_with_extended_dn(b_state->sam_ctx, frame,
+						      &search_res3,
+						      machine_dn, LDB_SCOPE_BASE,
+						      collect_objects_attrs,
+						      NULL);
+		if (ret != LDB_SUCCESS) {
+			DEBUG(1, ("DRSUAPI_EXOP_FSMO_RID_ALLOC: Failed to get server object %s - %s",
+				  ldb_dn_get_linearized(server_dn),
+				  ldb_errstring(b_state->sam_ctx)));
+			TALLOC_FREE(frame);
+			return WERR_DS_DRA_INTERNAL_ERROR;
+		}
+
+		if (search_res3->count != 1) {
+			DEBUG(1, ("DRSUAPI_EXOP_FSMO_RID_ALLOC: Failed to get server object %s - %u objects returned",
+				  ldb_dn_get_linearized(server_dn),
+				  search_res3->count));
+			TALLOC_FREE(frame);
+			return WERR_DS_DRA_INTERNAL_ERROR;
+		}
+
+		/* Now extend the original search_res with these answers */
+		(*search_res)->count = 3;
+
+		(*search_res)->msgs = talloc_realloc(frame, (*search_res)->msgs,
+						     struct ldb_message *,
+						     (*search_res)->count);
+		if ((*search_res)->msgs == NULL) {
+			TALLOC_FREE(frame);
+			return WERR_NOMEM;
+		}
+
+
+		talloc_steal(mem_ctx, *search_res);
+		(*search_res)->msgs[1] =
+			talloc_steal((*search_res)->msgs, search_res2->msgs[0]);
+		(*search_res)->msgs[2] =
+			talloc_steal((*search_res)->msgs, search_res3->msgs[0]);
+
+		TALLOC_FREE(frame);
+		return WERR_OK;
+	}
+	default:
+		/* TODO: implement extended op specific collection
+		 * of objects. Right now we just normal procedure
+		 * for collecting objects */
+		return getncchanges_collect_objects(b_state, mem_ctx, req10, search_dn, extra_filter, search_res);
+	}
 }
 
 /* 
@@ -1508,6 +1657,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
 	bool max_wait_reached = false;
 	bool has_get_all_changes = false;
 	struct GUID invocation_id;
+	static const struct drsuapi_DsReplicaLinkedAttribute no_linked_attr;
 
 	DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
 	b_state = h->data;
@@ -1519,12 +1669,15 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
 	*r->out.level_out = 6;
 	/* TODO: linked attributes*/
 	r->out.ctr->ctr6.linked_attributes_count = 0;
-	r->out.ctr->ctr6.linked_attributes = NULL;
+	r->out.ctr->ctr6.linked_attributes = discard_const_p(struct drsuapi_DsReplicaLinkedAttribute, &no_linked_attr);
 
 	r->out.ctr->ctr6.object_count = 0;
 	r->out.ctr->ctr6.nc_object_count = 0;
 	r->out.ctr->ctr6.more_data = false;
 	r->out.ctr->ctr6.uptodateness_vector = NULL;
+	r->out.ctr->ctr6.source_dsa_guid = *(samdb_ntds_objectGUID(sam_ctx));
+	r->out.ctr->ctr6.source_dsa_invocation_id = *(samdb_ntds_invocation_id(sam_ctx));
+	r->out.ctr->ctr6.first_object = NULL;
 
 	/* a RODC doesn't allow for any replication */
 	ret = samdb_rodc(sam_ctx, &am_rodc);
@@ -1701,9 +1854,11 @@ allowed:
 		case DRSUAPI_EXOP_NONE:
 			break;
 		case DRSUAPI_EXOP_FSMO_RID_ALLOC:
-			werr = getncchanges_rid_alloc(b_state, mem_ctx, req10, &r->out.ctr->ctr6);
+			werr = getncchanges_rid_alloc(b_state, mem_ctx, req10, &r->out.ctr->ctr6, &search_dn);
 			W_ERROR_NOT_OK_RETURN(werr);
-			search_dn = ldb_get_default_basedn(sam_ctx);
+			if (r->out.ctr->ctr6.extended_ret != DRSUAPI_EXOP_ERR_SUCCESS) {
+				return WERR_OK;
+			}
 			break;
 		case DRSUAPI_EXOP_REPL_SECRET:
 			werr = getncchanges_repl_secret(b_state, mem_ctx, req10,
@@ -1716,14 +1871,23 @@ allowed:
 		case DRSUAPI_EXOP_FSMO_REQ_ROLE:
 			werr = getncchanges_change_master(b_state, mem_ctx, req10, &r->out.ctr->ctr6);
 			W_ERROR_NOT_OK_RETURN(werr);
+			if (r->out.ctr->ctr6.extended_ret != DRSUAPI_EXOP_ERR_SUCCESS) {
+				return WERR_OK;
+			}
 			break;
 		case DRSUAPI_EXOP_FSMO_RID_REQ_ROLE:
 			werr = getncchanges_change_master(b_state, mem_ctx, req10, &r->out.ctr->ctr6);
 			W_ERROR_NOT_OK_RETURN(werr);
+			if (r->out.ctr->ctr6.extended_ret != DRSUAPI_EXOP_ERR_SUCCESS) {
+				return WERR_OK;
+			}
 			break;
 		case DRSUAPI_EXOP_FSMO_REQ_PDC:
 			werr = getncchanges_change_master(b_state, mem_ctx, req10, &r->out.ctr->ctr6);
 			W_ERROR_NOT_OK_RETURN(werr);
+			if (r->out.ctr->ctr6.extended_ret != DRSUAPI_EXOP_ERR_SUCCESS) {


-- 
Samba Shared Repository



More information about the samba-cvs mailing list