[SCM] Samba Shared Repository - branch master updated

Kamen Mazdrashki kamenim at samba.org
Fri Sep 3 04:27:11 MDT 2010


The branch, master has been updated
       via  fdffa90 s4-drs: A quick fix for DRSUAPI_EXOP_FSMO_RID_ALLOC extended_op handling
       via  65b21c0 s4-dreplsrv: Refactor drepl_replica_sync() to behave as described in MS-DRSR
       via  715743b s4-dreplsrv: Helpers to locate source DSA in a partition by GUID or DNS name
       via  3691e6c s4-dreplsrv: Helper to find NC by DN or GUID or SID
       via  5685fb6 s4-dreplsrv: Add caller-specific data parameter for dreplsrv_fsmo_callback_t
      from  cf728f8 s3-spoolss: fix some debug statements.

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


- Log -----------------------------------------------------------------
commit fdffa90ef99e10b963ecec73a65e18ecb6cec932
Author: Kamen Mazdrashki <kamenim at samba.org>
Date:   Fri Sep 3 06:20:49 2010 +0300

    s4-drs: A quick fix for DRSUAPI_EXOP_FSMO_RID_ALLOC extended_op handling
    
    When DRSUAPI_EXOP_FSMO_RID_ALLOC extended op is handled
    in DsGetNCChanges() stub, we need to returned a well know set of
    object - see: [ms-adts], 3.1.1.5.1.7
    
    With this hack we are going to return just objects modified
    during RID allocation procedure - i.e. "RID Manager$", "RID Set" for
    computer object and computer object itself.
    
    Which is a close approximation of what we are expected to return.

commit 65b21c056217b03ad0e0aa321bc9d85e048d2ee6
Author: Kamen Mazdrashki <kamenim at samba.org>
Date:   Fri Sep 3 04:29:02 2010 +0300

    s4-dreplsrv: Refactor drepl_replica_sync() to behave as described in MS-DRSR
    
    see: MS-DRSR - 4.1.23.2
    
    Note: Synchronious replication not implemented yet.

commit 715743b38dec1968dce843573a12947407d74324
Author: Kamen Mazdrashki <kamenim at samba.org>
Date:   Tue Aug 31 04:16:18 2010 +0300

    s4-dreplsrv: Helpers to locate source DSA in a partition by GUID or DNS name

commit 3691e6c97b2187730d42a2bb79ecc06f37aab344
Author: Kamen Mazdrashki <kamenim at samba.org>
Date:   Tue Aug 31 04:15:37 2010 +0300

    s4-dreplsrv: Helper to find NC by DN or GUID or SID

commit 5685fb64e4f4660d586e57c59800d0f374d10749
Author: Kamen Mazdrashki <kamenim at samba.org>
Date:   Tue Aug 31 00:01:25 2010 +0300

    s4-dreplsrv: Add caller-specific data parameter for dreplsrv_fsmo_callback_t
    
    It is to be used when we need to preserve a state
    to be used in tha callback when dreplsrv_out_operation is completed

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

Summary of changes:
 source4/dsdb/repl/drepl_out_pull.c        |   10 ++-
 source4/dsdb/repl/drepl_partitions.c      |   73 ++++++++++++++++++
 source4/dsdb/repl/drepl_ridalloc.c        |    5 +-
 source4/dsdb/repl/drepl_service.c         |  119 +++++++++++++++++++++++++++--
 source4/dsdb/repl/drepl_service.h         |    6 +-
 source4/rpc_server/drsuapi/getncchanges.c |    9 ++
 6 files changed, 207 insertions(+), 15 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/repl/drepl_out_pull.c b/source4/dsdb/repl/drepl_out_pull.c
index e9b57a1..db77a4e 100644
--- a/source4/dsdb/repl/drepl_out_pull.c
+++ b/source4/dsdb/repl/drepl_out_pull.c
@@ -38,7 +38,8 @@ WERROR dreplsrv_schedule_partition_pull_source(struct dreplsrv_service *s,
 					       struct dreplsrv_partition_source_dsa *source,
 					       enum drsuapi_DsExtendedOperation extended_op,
 					       uint64_t fsmo_info,
-					       dreplsrv_fsmo_callback_t callback)
+					       dreplsrv_fsmo_callback_t callback,
+					       void *cb_data)
 {
 	struct dreplsrv_out_operation *op;
 
@@ -50,6 +51,7 @@ WERROR dreplsrv_schedule_partition_pull_source(struct dreplsrv_service *s,
 	op->extended_op = extended_op;
 	op->fsmo_info   = fsmo_info;
 	op->callback    = callback;
+	op->cb_data	= cb_data;
 
 	DLIST_ADD_END(s->ops.pending, op, struct dreplsrv_out_operation *);
 
@@ -64,7 +66,9 @@ static WERROR dreplsrv_schedule_partition_pull(struct dreplsrv_service *s,
 	struct dreplsrv_partition_source_dsa *cur;
 
 	for (cur = p->sources; cur; cur = cur->next) {
-		status = dreplsrv_schedule_partition_pull_source(s, cur, DRSUAPI_EXOP_NONE, 0, NULL);
+		status = dreplsrv_schedule_partition_pull_source(s, cur,
+		                                                 DRSUAPI_EXOP_NONE, 0,
+		                                                 NULL, NULL);
 		W_ERROR_NOT_OK_RETURN(status);
 	}
 
@@ -160,7 +164,7 @@ static void dreplsrv_pending_op_callback(struct tevent_req *subreq)
 
 done:
 	if (op->callback) {
-		op->callback(s, rf->result_last_attempt, op->extended_ret);
+		op->callback(s, rf->result_last_attempt, op->extended_ret, op->cb_data);
 	}
 	talloc_free(op);
 	s->ops.current = NULL;
diff --git a/source4/dsdb/repl/drepl_partitions.c b/source4/dsdb/repl/drepl_partitions.c
index 5a11dce..caa93e6 100644
--- a/source4/dsdb/repl/drepl_partitions.c
+++ b/source4/dsdb/repl/drepl_partitions.c
@@ -31,6 +31,7 @@
 #include "librpc/gen_ndr/ndr_misc.h"
 #include "librpc/gen_ndr/ndr_drsuapi.h"
 #include "librpc/gen_ndr/ndr_drsblobs.h"
+#include "libcli/security/dom_sid.h"
 #include "param/param.h"
 
 WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
@@ -234,6 +235,78 @@ static WERROR udv_convert(TALLOC_CTX *mem_ctx,
 	return WERR_OK;
 }
 
+WERROR dreplsrv_partition_find_for_nc(struct dreplsrv_service *s,
+				      const struct GUID *nc_guid,
+				      const struct dom_sid *nc_sid,
+				      const char *nc_dn_str,
+				      struct dreplsrv_partition **_p)
+{
+	struct dreplsrv_partition *p;
+	bool valid_sid, valid_guid;
+	struct dom_sid null_sid;
+	ZERO_STRUCT(null_sid);
+
+	SMB_ASSERT(_p);
+
+	valid_sid  = nc_sid && !dom_sid_equal(&null_sid, nc_sid);
+	valid_guid = nc_guid && !GUID_all_zero(nc_guid);
+
+	if (!valid_sid && !valid_guid && !nc_dn_str) {
+		return WERR_DS_DRA_INVALID_PARAMETER;
+	}
+
+	for (p = s->partitions; p; p = p->next) {
+		if ((valid_guid && GUID_equal(&p->nc.guid, nc_guid))
+		    || strequal(p->nc.dn, nc_dn_str)
+		    || (valid_sid && dom_sid_equal(&p->nc.sid, nc_sid)))
+		{
+			*_p = p;
+			return WERR_OK;
+		}
+	}
+
+	return WERR_DS_DRA_BAD_NC;
+}
+
+WERROR dreplsrv_partition_source_dsa_by_guid(struct dreplsrv_partition *p,
+					     const struct GUID *dsa_guid,
+					     struct dreplsrv_partition_source_dsa **_dsa)
+{
+	struct dreplsrv_partition_source_dsa *dsa;
+
+	SMB_ASSERT(dsa_guid != NULL);
+	SMB_ASSERT(!GUID_all_zero(dsa_guid));
+	SMB_ASSERT(_dsa);
+
+	for (dsa = p->sources; dsa; dsa = dsa->next) {
+		if (GUID_equal(dsa_guid, &dsa->repsFrom1->source_dsa_obj_guid)) {
+			*_dsa = dsa;
+			return WERR_OK;
+		}
+	}
+
+	return WERR_DS_DRA_NO_REPLICA;
+}
+
+WERROR dreplsrv_partition_source_dsa_by_dns(const struct dreplsrv_partition *p,
+					    const char *dsa_dns,
+					    struct dreplsrv_partition_source_dsa **_dsa)
+{
+	struct dreplsrv_partition_source_dsa *dsa;
+
+	SMB_ASSERT(dsa_dns != NULL);
+	SMB_ASSERT(_dsa);
+
+	for (dsa = p->sources; dsa; dsa = dsa->next) {
+		if (strequal(dsa_dns, dsa->repsFrom1->other_info->dns_name)) {
+			*_dsa = dsa;
+			return WERR_OK;
+		}
+	}
+
+	return WERR_DS_DRA_NO_REPLICA;
+}
+
 
 static WERROR dreplsrv_refresh_partition(struct dreplsrv_service *s,
 					 struct dreplsrv_partition *p)
diff --git a/source4/dsdb/repl/drepl_ridalloc.c b/source4/dsdb/repl/drepl_ridalloc.c
index c036228..6d4b0da 100644
--- a/source4/dsdb/repl/drepl_ridalloc.c
+++ b/source4/dsdb/repl/drepl_ridalloc.c
@@ -102,7 +102,8 @@ static WERROR drepl_create_rid_manager_source_dsa(struct dreplsrv_service *servi
  */
 static void drepl_new_rid_pool_callback(struct dreplsrv_service *service,
 					WERROR werr,
-					enum drsuapi_DsExtendedError ext_err)
+					enum drsuapi_DsExtendedError ext_err,
+					void *cb_data)
 {
 	if (!W_ERROR_IS_OK(werr)) {
 		DEBUG(0,(__location__ ": RID Manager failed RID allocation - %s - extended_ret[0x%X]\n",
@@ -139,7 +140,7 @@ static WERROR drepl_request_new_rid_pool(struct dreplsrv_service *service,
 
 	werr = dreplsrv_schedule_partition_pull_source(service, service->ridalloc.rid_manager_source_dsa,
 						       DRSUAPI_EXOP_FSMO_RID_ALLOC, alloc_pool,
-						       drepl_new_rid_pool_callback);
+						       drepl_new_rid_pool_callback, NULL);
 	return werr;
 }
 
diff --git a/source4/dsdb/repl/drepl_service.c b/source4/dsdb/repl/drepl_service.c
index d118c45..252ec5f 100644
--- a/source4/dsdb/repl/drepl_service.c
+++ b/source4/dsdb/repl/drepl_service.c
@@ -103,28 +103,131 @@ static WERROR dreplsrv_connect_samdb(struct dreplsrv_service *service, struct lo
 	return WERR_OK;
 }
 
+
 /*
   DsReplicaSync messages from the DRSUAPI server are forwarded here
  */
 static NTSTATUS drepl_replica_sync(struct irpc_message *msg, 
 				   struct drsuapi_DsReplicaSync *r)
 {
+	WERROR werr;
+	struct dreplsrv_partition *p;
+	struct dreplsrv_partition_source_dsa *dsa;
+	struct drsuapi_DsReplicaSyncRequest1 *req1;
+	struct drsuapi_DsReplicaObjectIdentifier *nc;
 	struct dreplsrv_service *service = talloc_get_type(msg->private_data,
 							   struct dreplsrv_service);
-	struct drsuapi_DsReplicaObjectIdentifier *nc = r->in.req->req1.naming_context;
 
-	r->out.result = dreplsrv_schedule_partition_pull_by_nc(service, msg, nc);
-	if (W_ERROR_IS_OK(r->out.result)) {
-		DEBUG(3,("drepl_replica_sync: forcing sync of partition (%s, %s)\n",
+#define REPLICA_SYNC_FAIL(_werr) do {r->out.result = _werr; goto done;} while(0)
+
+	if (r->in.level != 1) {
+		DEBUG(0,("%s: Level %d is not supported yet.\n",
+			 __FUNCTION__, r->in.level));
+		REPLICA_SYNC_FAIL(WERR_DS_DRA_INVALID_PARAMETER);
+	}
+
+	req1 = &r->in.req->req1;
+	nc   = req1->naming_context;
+
+	/* Check input parameters */
+	if (!nc) {
+		REPLICA_SYNC_FAIL(WERR_DS_DRA_INVALID_PARAMETER);
+	}
+
+	/* Find Naming context to be synchronized */
+	werr = dreplsrv_partition_find_for_nc(service,
+	                                      &nc->guid, &nc->sid, nc->dn,
+	                                      &p);
+	if (!W_ERROR_IS_OK(werr)) {
+		DEBUG(0,("%s: failed to find NC for (%s, %s) - %s\n",
+			 __FUNCTION__,
 			 GUID_string(msg, &nc->guid),
-			 nc->dn));
-		dreplsrv_run_pending_ops(service);
+			 nc->dn,
+			 win_errstr(werr)));
+		REPLICA_SYNC_FAIL(werr);
+	}
+
+	/* collect source DSAs to sync with */
+	if (req1->options & DRSUAPI_DRS_SYNC_ALL) {
+		for (dsa = p->sources; dsa; dsa = dsa->next) {
+			/* schedule replication item */
+			werr = dreplsrv_schedule_partition_pull_source(service, dsa,
+			                                               DRSUAPI_EXOP_NONE, 0,
+			                                               NULL, NULL);
+			if (!W_ERROR_IS_OK(werr)) {
+				DEBUG(0,("%s: failed setup of sync of partition (%s, %s, %s) - %s\n",
+					 __FUNCTION__,
+					 GUID_string(msg, &nc->guid),
+					 nc->dn,
+					 dsa->repsFrom1->other_info->dns_name,
+					 win_errstr(werr)));
+				REPLICA_SYNC_FAIL(werr);
+			}
+			/* log we've scheduled replication item */
+			DEBUG(3,("%s: forcing sync of partition (%s, %s, %s)\n",
+				 __FUNCTION__,
+				 GUID_string(msg, &nc->guid),
+				 nc->dn,
+				 dsa->repsFrom1->other_info->dns_name));
+		}
 	} else {
-		DEBUG(3,("drepl_replica_sync: failed setup of sync of partition (%s, %s) - %s\n",
+		if (req1->options & DRSUAPI_DRS_SYNC_BYNAME) {
+			/* client should pass at least valid string */
+			if (!req1->source_dsa_dns) {
+				REPLICA_SYNC_FAIL(WERR_DS_DRA_INVALID_PARAMETER);
+			}
+
+			werr = dreplsrv_partition_source_dsa_by_dns(p,
+			                                            req1->source_dsa_dns,
+			                                            &dsa);
+		} else {
+			/* client should pass at least some GUID */
+			if (GUID_all_zero(&req1->source_dsa_guid)) {
+				REPLICA_SYNC_FAIL(WERR_DS_DRA_INVALID_PARAMETER);
+			}
+
+			werr = dreplsrv_partition_source_dsa_by_guid(p,
+			                                             &req1->source_dsa_guid,
+			                                             &dsa);
+		}
+		if (!W_ERROR_IS_OK(werr)) {
+			DEBUG(0,("%s: Failed to locate source DSA %s for NC %s.\n",
+				 __FUNCTION__,
+				 (req1->options & DRSUAPI_DRS_SYNC_BYNAME)
+					 ? req1->source_dsa_dns
+					 : GUID_string(r, &req1->source_dsa_guid),
+				 nc->dn));
+			REPLICA_SYNC_FAIL(WERR_DS_DRA_NO_REPLICA);
+		}
+
+		/* schedule replication item */
+		werr = dreplsrv_schedule_partition_pull_source(service, dsa,
+		                                               DRSUAPI_EXOP_NONE, 0,
+		                                               NULL, NULL);
+		if (!W_ERROR_IS_OK(werr)) {
+			DEBUG(0,("%s: failed setup of sync of partition (%s, %s, %s) - %s\n",
+				 __FUNCTION__,
+				 GUID_string(msg, &nc->guid),
+				 nc->dn,
+				 dsa->repsFrom1->other_info->dns_name,
+				 win_errstr(werr)));
+			REPLICA_SYNC_FAIL(werr);
+		}
+		/* log we've scheduled replication item */
+		DEBUG(3,("%s: forcing sync of partition (%s, %s, %s)\n",
+			 __FUNCTION__,
 			 GUID_string(msg, &nc->guid),
 			 nc->dn,
-			 win_errstr(r->out.result)));
+			 dsa->repsFrom1->other_info->dns_name));
 	}
+
+	/* if we got here, everything is OK */
+	r->out.result = WERR_OK;
+
+	/* force execution of scheduled replications */
+	dreplsrv_run_pending_ops(service);
+
+done:
 	return NT_STATUS_OK;
 }
 
diff --git a/source4/dsdb/repl/drepl_service.h b/source4/dsdb/repl/drepl_service.h
index 4019bf7..00fd3bf 100644
--- a/source4/dsdb/repl/drepl_service.h
+++ b/source4/dsdb/repl/drepl_service.h
@@ -105,7 +105,8 @@ struct dreplsrv_partition {
 
 typedef void (*dreplsrv_fsmo_callback_t)(struct dreplsrv_service *,
 					 WERROR,
-					 enum drsuapi_DsExtendedError);
+					 enum drsuapi_DsExtendedError,
+					 void *cb_data);
 
 struct dreplsrv_out_operation {
 	struct dreplsrv_out_operation *prev, *next;
@@ -116,8 +117,9 @@ struct dreplsrv_out_operation {
 
 	enum drsuapi_DsExtendedOperation extended_op;
 	uint64_t fsmo_info;
-	dreplsrv_fsmo_callback_t callback;
 	enum drsuapi_DsExtendedError extended_ret;
+	dreplsrv_fsmo_callback_t callback;
+	void *cb_data;
 };
 
 struct dreplsrv_notify_operation {
diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c
index 2625595..2659cf3 100644
--- a/source4/rpc_server/drsuapi/getncchanges.c
+++ b/source4/rpc_server/drsuapi/getncchanges.c
@@ -652,6 +652,15 @@ 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, &req8->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",


-- 
Samba Shared Repository


More information about the samba-cvs mailing list