[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