[SCM] Samba Shared Repository - branch master updated

Andrew Tridgell tridge at samba.org
Mon Feb 15 14:35:38 MST 2010


The branch, master has been updated
       via  23d1dd5... s4-drs: DsGetReplInfo() refactoring
       via  3e2a867... s4-drs: DsReplGetInfo() for DS_REPL_INFO_REPSTO infoType
      from  bb05595... s4-smbtorture: more work on SD tests for RPC-SPOOLSS.

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


- Log -----------------------------------------------------------------
commit 23d1dd5189e0662efb532c31b26c71434a00cff4
Author: Erick Nogueira do Nascimento <erick.nogueira.nascimento at gmail.com>
Date:   Thu Feb 11 19:04:00 2010 -0200

    s4-drs: DsGetReplInfo() refactoring

commit 3e2a8676c3beff03c9eb3507b0d3bacbd97c147e
Author: Erick Nogueira do Nascimento <erick.nogueira.nascimento at gmail.com>
Date:   Fri Jan 29 20:07:47 2010 -0200

    s4-drs: DsReplGetInfo() for DS_REPL_INFO_REPSTO infoType
    
    Implements the DS_REPL_INFO_REPSTO infoType of DsReplGetInfo().

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

Summary of changes:
 source4/dsdb/kcc/kcc_drs_replica_info.c |  431 ++++++++++++++++++-------------
 source4/torture/rpc/dsgetinfo.c         |   19 +-
 2 files changed, 263 insertions(+), 187 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/kcc/kcc_drs_replica_info.c b/source4/dsdb/kcc/kcc_drs_replica_info.c
index 8c18293..da89a47 100644
--- a/source4/dsdb/kcc/kcc_drs_replica_info.c
+++ b/source4/dsdb/kcc/kcc_drs_replica_info.c
@@ -112,17 +112,112 @@ static WERROR kccdrs_replica_get_info_pending_ops(TALLOC_CTX *mem_ctx,
 	return WERR_OK;
 }
 
-
 struct ncList {
 	struct ldb_dn *dn;
 	struct ncList *prev, *next;
 };
 
-struct neighList {
-	struct drsuapi_DsReplicaNeighbour *neigh;
-	struct neighList *prev, *next;
-};
+/*
+  Fill 'master_nc_list' with the master ncs hosted by this server
+*/
+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 *attrs[] = { "hasMasterNCs", NULL };
+	struct ldb_result *res;
+	struct ncList *nc_list = NULL;
+	struct ncList *nc_list_elem;
+	int ret;
+	int i;
+	char *nc_str;
+
+	ret = ldb_search(samdb, mem_ctx, &res, ldb_get_config_basedn(samdb),
+			LDB_SCOPE_DEFAULT, attrs, "(objectguid=%s)", ntds_guid_str);
+
+	if (ret != LDB_SUCCESS) {
+		DEBUG(0,(__location__ ": Failed objectguid search - %s\n", ldb_errstring(samdb)));
+		return WERR_INTERNAL_ERROR;
+	}
+
+	if (res->count == 0) {
+		DEBUG(0,(__location__ ": Failed: objectguid=%s not found\n", ntds_guid_str));
+		return WERR_INTERNAL_ERROR;
+	}
+
+	for (i = 0; i < res->count; i++) {
+		struct ldb_message_element *msg_elem = ldb_msg_find_element(res->msgs[i], "hasMasterNCs");
+		int k;
+
+		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 (k = 0; k < msg_elem->num_values; k++) {
+			int len = msg_elem->values[k].length;
+
+			/* copy the string on msg_elem->values[k]->data to nc_str */
+			nc_str = talloc_array(mem_ctx, char, len);
+			W_ERROR_HAVE_NO_MEMORY(nc_str);
+			memcpy(nc_str, msg_elem->values[k].data, len);
+			nc_str[len] = '\0';
+
+			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;
+	return WERR_OK;
+}
+
+/*
+  Fill 'nc_list' with the ncs list. (MS-DRSR 4.1.13.3)
+  if the object dn is specified, fill 'nc_list' only with this dn
+  otherwise, fill 'nc_list' with all master ncs hosted by this server
+*/
+static WERROR get_ncs_list(TALLOC_CTX *mem_ctx,
+		struct ldb_context *samdb,
+		struct kccsrv_service *service,
+		const char *object_dn_str,
+		struct ncList **nc_list)
+{
+	WERROR status;
+	struct ncList *nc_list_elem;
+	struct ldb_dn *nc_dn;
+
+	if (object_dn_str != NULL) {
+		/* ncs := { object_dn } */
+		*nc_list = NULL;
+		nc_dn = ldb_dn_new(mem_ctx, samdb, object_dn_str);
+		nc_list_elem = talloc_zero(mem_ctx, struct ncList);
+		W_ERROR_HAVE_NO_MEMORY(nc_list_elem);
+		nc_list_elem->dn = nc_dn;
+		DLIST_ADD_END(*nc_list, nc_list_elem, struct ncList*);
+	} else {
+		/* ncs := getNCs() from ldb database.
+		 * getNCs() must return an array containing
+		 * the DSNames of all NCs hosted by this
+		 * server.
+		 */
+		char *ntds_guid_str = GUID_string(mem_ctx, &service->ntds_guid);
+		W_ERROR_HAVE_NO_MEMORY(ntds_guid_str);
+		status = get_master_ncs(mem_ctx, samdb, ntds_guid_str, nc_list);
+		W_ERROR_NOT_OK_RETURN(status);
+	}
+
+	return WERR_OK;
+}
+
+/*
+  Copy the fields from 'reps1' to 'reps2', leaving zeroed the fields on
+  'reps2' that aren't available on 'reps1'.
+*/
 static WERROR copy_repsfrom_1_to_2(TALLOC_CTX *mem_ctx,
 				 struct repsFromTo2 **reps2,
 				 struct repsFromTo1 *reps1)
@@ -157,7 +252,6 @@ static WERROR fill_neighbor_from_repsFrom(TALLOC_CTX *mem_ctx,
 					  struct drsuapi_DsReplicaNeighbour *neigh,
 					  struct repsFromTo2 *reps_from)
 {
-	WERROR status;
 	struct ldb_dn *source_dsa_dn;
 	int ret;
 	char *dsa_guid_str;
@@ -175,8 +269,7 @@ static WERROR fill_neighbor_from_repsFrom(TALLOC_CTX *mem_ctx,
 	if (ret != LDB_SUCCESS) {
 		DEBUG(0,(__location__ ": Failed to find DN for neighbor GUID %s\n",
 		      dsa_guid_str));
-		status = WERR_DS_DRA_INTERNAL_ERROR;
-		goto DONE;
+		return WERR_DS_DRA_INTERNAL_ERROR;
 	}
 
 	neigh->source_dsa_obj_dn = ldb_dn_get_linearized(source_dsa_dn);
@@ -184,8 +277,7 @@ static WERROR fill_neighbor_from_repsFrom(TALLOC_CTX *mem_ctx,
 
 	if (dsdb_find_guid_by_dn(samdb, nc_dn, &neigh->naming_context_obj_guid)
 			!= LDB_SUCCESS) {
-		status = WERR_DS_DRA_INTERNAL_ERROR;
-		goto DONE;
+		return WERR_DS_DRA_INTERNAL_ERROR;
 	}
 
 	if (!GUID_all_zero(&reps_from->transport_guid)) {
@@ -194,8 +286,7 @@ static WERROR fill_neighbor_from_repsFrom(TALLOC_CTX *mem_ctx,
 		if (dsdb_find_dn_by_guid(samdb, mem_ctx, transp_guid_str,
 					 &transport_obj_dn) != LDB_SUCCESS)
 		{
-			status = WERR_DS_DRA_INTERNAL_ERROR;
-			goto DONE;
+			return WERR_DS_DRA_INTERNAL_ERROR;
 		}
 	}
 
@@ -209,42 +300,42 @@ static WERROR fill_neighbor_from_repsFrom(TALLOC_CTX *mem_ctx,
 	neigh->consecutive_sync_failures = reps_from->consecutive_sync_failures;
 	neigh->reserved = 0; /* Unused. MUST be 0. */
 
-	/* If everything went fine so far, set the status to OK */
-	status = WERR_OK;
-DONE:
-	return status;
+	return WERR_OK;
 }
 
 /*
- * See details on MS-DRSR 4.1.13.3, for infoType DS_REPL_INFO_NEIGHBORS
- * */
+  Get the inbound neighbours of this DC
+  See details on MS-DRSR 4.1.13.3, for infoType DS_REPL_INFO_NEIGHBORS
+*/
 static WERROR kccdrs_replica_get_info_neighbours(TALLOC_CTX *mem_ctx,
+						 struct kccsrv_service *service,
 						 struct ldb_context *samdb,
 						 struct drsuapi_DsReplicaGetInfo *r,
 						 union drsuapi_DsReplicaInfo *reply,
 						 int base_index,
 						 struct GUID req_src_dsa_guid,
-						 struct ncList *nc_list)
+						 const char *object_dn_str)
 {
 	WERROR status;
-
-	int i, j, k;
+	int i, j;
 	struct ldb_dn *nc_dn = NULL;
 	struct ncList *p_nc_list = NULL;
-
 	struct repsFromToBlob *reps_from_blob = NULL;
 	struct repsFromTo2 *reps_from = NULL;
 	uint32_t c_reps_from;
-
 	int i_rep;
+	struct drsuapi_DsReplicaNeighbour neigh;
+	struct ncList *nc_list = NULL;
 
-	struct neighList *neigh_list = NULL;
-	struct neighList *neigh_elem = NULL;
-
-	struct drsuapi_DsReplicaNeighbour *neigh = NULL;
+	status = get_ncs_list(mem_ctx, samdb, service, object_dn_str, &nc_list);
+	W_ERROR_NOT_OK_RETURN(status);
 
 	i = j = 0;
-	neigh_list = NULL;
+
+	reply->neighbours = talloc_zero(mem_ctx, struct drsuapi_DsReplicaNeighbourCtr);
+	W_ERROR_HAVE_NO_MEMORY(reply->neighbours);
+	reply->neighbours->reserved = 0;
+	reply->neighbours->count = 0;
 
 	/* foreach nc in ncs */
 	for (p_nc_list = nc_list; p_nc_list != NULL; p_nc_list = p_nc_list->next) {
@@ -254,10 +345,7 @@ static WERROR kccdrs_replica_get_info_neighbours(TALLOC_CTX *mem_ctx,
 		/* load the nc's repsFromTo blob */
 		status = dsdb_loadreps(samdb, mem_ctx, nc_dn, "repsFrom",
 				&reps_from_blob, &c_reps_from);
-		if (!W_ERROR_IS_OK(status)) {
-			status = WERR_DS_DRA_INTERNAL_ERROR;
-			goto DONE;
-		}
+		W_ERROR_NOT_OK_RETURN(status);
 
 		/* foreach r in nc!repsFrom */
 		for (i_rep = 0; i_rep < c_reps_from; i_rep++) {
@@ -266,9 +354,7 @@ static WERROR kccdrs_replica_get_info_neighbours(TALLOC_CTX *mem_ctx,
 			if (reps_from_blob[i_rep].version == 1) {
 				status = copy_repsfrom_1_to_2(mem_ctx, &reps_from,
 							      &reps_from_blob[i_rep].ctr.ctr1);
-				if (!W_ERROR_IS_OK(status)) {
-					goto DONE;
-				}
+				W_ERROR_NOT_OK_RETURN(status);
 			} else { /* reps_from->version == 2 */
 				reps_from = &reps_from_blob[i_rep].ctr.ctr2;
 			}
@@ -278,22 +364,17 @@ static WERROR kccdrs_replica_get_info_neighbours(TALLOC_CTX *mem_ctx,
 			{
 
 				if (i >= base_index) {
-					neigh = talloc_zero(mem_ctx, struct drsuapi_DsReplicaNeighbour);
-					W_ERROR_HAVE_NO_MEMORY(neigh);
-
 					status = fill_neighbor_from_repsFrom(mem_ctx, samdb,
-									     nc_dn, neigh,
+									     nc_dn, &neigh,
 									     reps_from);
-					if (!W_ERROR_IS_OK(status)) {
-						goto DONE;
-					}
-
-					/* append the neighbor to neigh_list */
-					neigh_elem = talloc_zero(mem_ctx, struct neighList);
-					W_ERROR_HAVE_NO_MEMORY(neigh_elem);
-					neigh_elem->neigh = neigh;
-					DLIST_ADD_END(neigh_list, neigh_elem, struct neighList*);
-
+					W_ERROR_NOT_OK_RETURN(status);
+
+					/* append the neighbour to the neighbours array */
+					reply->neighbours->array = talloc_realloc(mem_ctx,
+										    reply->neighbours->array,
+										    struct drsuapi_DsReplicaNeighbour,
+										    reply->neighbours->count + 1);
+					reply->neighbours->array[reply->neighbours->count++] = neigh;
 					j++;
 				}
 
@@ -302,110 +383,138 @@ static WERROR kccdrs_replica_get_info_neighbours(TALLOC_CTX *mem_ctx,
 		}
 	}
 
-	/* put all neighbours on neigh_list on reply->neighbours->array */
-	reply->neighbours = talloc_zero(mem_ctx, struct drsuapi_DsReplicaNeighbourCtr);
-	W_ERROR_HAVE_NO_MEMORY(reply->neighbours);
-
-	reply->neighbours->count = j;
-	reply->neighbours->reserved = 0;
-	reply->neighbours->array = talloc_array(mem_ctx, struct drsuapi_DsReplicaNeighbour, j);
-	W_ERROR_HAVE_NO_MEMORY(reply->neighbours->array);
-
-	for (k = 0; neigh_list != NULL; neigh_list = neigh_list->next, k++) {
-		reply->neighbours->array[k] = *neigh_list->neigh;
-	}
-
-	/* If everything went fine so far, set the status to OK */
-	status = WERR_OK;
-DONE:
-	return status;
+	return WERR_OK;
 }
 
-static WERROR get_master_ncs(TALLOC_CTX *mem_ctx, struct ldb_context *samdb,
-			     const char *ntds_guid_str, struct ncList **master_nc_list)
+static WERROR fill_neighbor_from_repsTo(TALLOC_CTX *mem_ctx,
+					struct ldb_context *samdb, struct ldb_dn *nc_dn,
+					struct drsuapi_DsReplicaNeighbour *neigh,
+					struct repsFromTo2 *reps_to)
 {
-	WERROR status;
-	const char *attrs[] = { "hasMasterNCs", NULL };
-	struct ldb_result *res;
-	struct ncList *nc_list = NULL;
-	struct ncList *nc_list_elem;
+	char *dsa_guid_str;
 	int ret;
-	int i;
-	char *nc_str;
+	struct ldb_dn *source_dsa_dn;
 
-	ret = ldb_search(samdb, mem_ctx, &res, ldb_get_config_basedn(samdb),
-			LDB_SCOPE_DEFAULT, attrs, "(objectguid=%s)", ntds_guid_str);
+	neigh->source_dsa_address = reps_to->other_info->dns_name1;
+	neigh->replica_flags = reps_to->replica_flags;
+	neigh->last_attempt = reps_to->last_attempt;
+	neigh->source_dsa_obj_guid = reps_to->source_dsa_obj_guid;
+
+	dsa_guid_str = GUID_string(mem_ctx, &reps_to->source_dsa_obj_guid);
+	W_ERROR_HAVE_NO_MEMORY(dsa_guid_str);
 
+	ret = dsdb_find_dn_by_guid(samdb, mem_ctx, dsa_guid_str, &source_dsa_dn);
 	if (ret != LDB_SUCCESS) {
-		DEBUG(0,(__location__ ": Failed objectguid search - %s\n", ldb_errstring(samdb)));
-		status = WERR_INTERNAL_ERROR;
-		goto DONE;
+		DEBUG(0,(__location__ ": Failed to find DN for neighbor GUID %s\n",
+			 dsa_guid_str));
+		return WERR_DS_DRA_INTERNAL_ERROR;
 	}
 
-	if (res->count == 0) {
-		DEBUG(0,(__location__ ": Failed: objectguid=%s not found\n", ntds_guid_str));
-		status = WERR_INTERNAL_ERROR;
-		goto DONE;
+	neigh->source_dsa_obj_dn = ldb_dn_get_linearized(source_dsa_dn);
+	neigh->naming_context_dn = ldb_dn_get_linearized(nc_dn);
+
+	ret = dsdb_find_guid_by_dn(samdb, nc_dn,
+			&neigh->naming_context_obj_guid);
+	if (ret != LDB_SUCCESS) {
+		DEBUG(0,(__location__ ": Failed to find GUID for DN %s\n",
+			 ldb_dn_get_linearized(nc_dn)));
+		return WERR_DS_DRA_INTERNAL_ERROR;
 	}
 
-	for (i = 0; i < res->count; i++) {
+	return WERR_OK;
+}
 
-		struct ldb_message_element *msg_elem = ldb_msg_find_element(
-				res->msgs[i], "hasMasterNCs");
-		int k;
+/*
+  Get the outbound neighbours of this DC
+  See details on MS-DRSR 4.1.13.3, for infoType DS_REPL_INFO_REPSTO
+*/
+static WERROR kccdrs_replica_get_info_repsto(TALLOC_CTX *mem_ctx,
+					     struct kccsrv_service *service,
+					     struct ldb_context *samdb,
+					     struct drsuapi_DsReplicaGetInfo *r,
+					     union drsuapi_DsReplicaInfo *reply,
+					     int base_index,
+					     struct GUID req_src_dsa_guid,
+					     const char *object_dn_str)
+{
+	WERROR status;
+	int i, j;
+	struct ncList *p_nc_list = NULL;
+	struct ldb_dn *nc_dn = NULL;
+	struct repsFromToBlob *reps_to_blob;
+	struct repsFromTo2 *reps_to;
+	uint32_t c_reps_to;
+	int i_rep;
+	struct drsuapi_DsReplicaNeighbour neigh;
+	struct ncList *nc_list = NULL;
 
-		if (!msg_elem || msg_elem->num_values == 0) {
-			DEBUG(0,(__location__ ": Failed: Attribute hasMasterNCs not found - %s\n",
-			      ldb_errstring(samdb)));
-			status = WERR_INTERNAL_ERROR;
-			goto DONE;
-		}
+	status = get_ncs_list(mem_ctx, samdb, service, object_dn_str, &nc_list);
+	W_ERROR_NOT_OK_RETURN(status);
 
-		for (k = 0; k < msg_elem->num_values; k++) {
-			int len = msg_elem->values[k].length;
+	i = j = 0;
 
-			/* copy the string on msg_elem->values[k]->data to nc_str */
-			nc_str = talloc_array(mem_ctx, char, len);
-			W_ERROR_HAVE_NO_MEMORY(nc_str);
-			memcpy(nc_str, msg_elem->values[k].data, len);
-			nc_str[len] = '\0';
+	reply->neighbours02 = talloc_zero(mem_ctx, struct drsuapi_DsReplicaNeighbourCtr);
+	W_ERROR_HAVE_NO_MEMORY(reply->neighbours02);
+	reply->neighbours02->reserved = 0;
+	reply->neighbours02->count = 0;
 
-			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);
-		}
+	/* foreach nc in ncs */
+	for (p_nc_list = nc_list; p_nc_list != NULL; p_nc_list = p_nc_list->next) {
+
+		nc_dn = p_nc_list->dn;
+
+		status = dsdb_loadreps(samdb, mem_ctx, nc_dn, "repsTo",
+				&reps_to_blob, &c_reps_to);
+		W_ERROR_NOT_OK_RETURN(status);
+
+		/* foreach r in nc!repsTo */
+		for (i_rep = 0; i_rep < c_reps_to; i_rep++) {
+
+			/* put all info on reps_to */
+			if (reps_to_blob[i_rep].version == 1) {
+				status = copy_repsfrom_1_to_2(mem_ctx,
+							      &reps_to,
+							      &reps_to_blob[i_rep].ctr.ctr1);
+				W_ERROR_NOT_OK_RETURN(status);
+			} else { /* reps_to->version == 2 */
+				reps_to = &reps_to_blob[i_rep].ctr.ctr2;
+			}
 
+			if (i >= base_index) {
+				status = fill_neighbor_from_repsTo(mem_ctx,
+								   samdb, nc_dn,
+								   &neigh, reps_to);
+				W_ERROR_NOT_OK_RETURN(status);
+
+				/* append the neighbour to the neighbours array */
+				reply->neighbours02->array = talloc_realloc(mem_ctx,
+									    reply->neighbours02->array,
+									    struct drsuapi_DsReplicaNeighbour,
+									    reply->neighbours02->count + 1);
+				reply->neighbours02->array[reply->neighbours02->count++] = neigh;
+				j++;
+			}
+			i++;
+		}
 	}
 
-	*master_nc_list = nc_list;
-	/* If everything went fine so far, set the status to OK */
-	status = WERR_OK;
-DONE:
-	return status;
+	return WERR_OK;
 }
 
 NTSTATUS kccdrs_replica_get_info(struct irpc_message *msg,
 				 struct drsuapi_DsReplicaGetInfo *req)
 {
 	WERROR status;
-
 	struct drsuapi_DsReplicaGetInfoRequest1 *req1;
 	struct drsuapi_DsReplicaGetInfoRequest2 *req2;
-	enum drsuapi_DsReplicaInfoType info_type, *tmp_p_info_type;
-
 	int base_index;
 	union drsuapi_DsReplicaInfo *reply;
-
 	struct GUID req_src_dsa_guid;
-	const char *object_dn = NULL;
-	struct ldb_dn *nc_dn = NULL;
-	struct ncList *nc_list = NULL, *nc_list_elem = NULL;
-
+	const char *object_dn_str = NULL;
 	struct kccsrv_service *service;
 	struct ldb_context *samdb;
 	TALLOC_CTX *mem_ctx;
+	enum drsuapi_DsReplicaInfoType info_type;
 
 	service = talloc_get_type(msg->private_data, struct kccsrv_service);
 	samdb = service->samdb;
@@ -421,14 +530,14 @@ NTSTATUS kccdrs_replica_get_info(struct irpc_message *msg,
 		DEBUG(1,(__location__ ": Unsupported DsReplicaGetInfo level %u\n",
 			 req->in.level));
 		status = WERR_REVISION_MISMATCH;
-		goto DONE;
+		goto done;
 	}
 
 	if (req->in.level == DRSUAPI_DS_REPLICA_GET_INFO) {
 		req1 = &req->in.req->req1;
 		base_index = 0;
 		info_type = req1->info_type;
-		object_dn = req1->object_dn;
+		object_dn_str = req1->object_dn;
 		req_src_dsa_guid = req1->guid1;
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list