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 <abart...@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 <abart...@samba.org>
    Reviewed-by: Garming Sam <garm...@catalyst.net.nz>
    
    Autobuild-User(master): Andrew Bartlett <abart...@samba.org>
    Autobuild-Date(master): Wed Jun  1 14:01:36 CEST 2016 on sn-devel-144

commit cb32e25fbecb435b840deddf873aea8d89a3c506
Author: Andrew Bartlett <abart...@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 <abart...@samba.org>
    Reviewed-by: Garming Sam <garm...@catalyst.net.nz>

commit 2d9383e1d4aef758ec2fdaa57203e9a0dbcbca2f
Author: Andrew Bartlett <abart...@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 <abart...@samba.org>
    Reviewed-by: Garming Sam <garm...@catalyst.net.nz>

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

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

commit 59d6c7c6749fba003ca4895cfd7c177ca455d81f
Author: Andrew Bartlett <abart...@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 <abart...@samba.org>
    Reviewed-by: Garming Sam <garm...@catalyst.net.nz>

commit dfda45802c7d30d00eab757497e598732c062e81
Author: Andrew Bartlett <abart...@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 <abart...@samba.org>
    Reviewed-by: Garming Sam <garm...@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

Reply via email to