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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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

Reply via email to