The branch, master has been updated
       via  939b936d1af9a5221922864ad579bf50157b957b (commit)
      from  dca7afb799477a34f704c04397a6afa1ee6b9973 (commit)

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


- Log -----------------------------------------------------------------
commit 939b936d1af9a5221922864ad579bf50157b957b
Author: Andrew Tridgell <tri...@samba.org>
Date:   Wed Sep 9 17:04:16 2009 +1000

    s4/repl: added refresh of repsTo
    
    I've found that w2k3 deletes the repsTo records we carefully created
    in the vampire join if we don't refresh them frequently. After about
    30mins all 3 repsTo records are gone.
    
    This patch adds automatic refresh of the repsTo by calling
    DSReplicaUpdateRefs every time we do a sync cycle with the server

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

Summary of changes:
 source4/dsdb/repl/drepl_out_helpers.c |   88 ++++++++++++++++++++++++++++++++-
 1 files changed, 87 insertions(+), 1 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/repl/drepl_out_helpers.c 
b/source4/dsdb/repl/drepl_out_helpers.c
index c292c6d..59b3176 100644
--- a/source4/dsdb/repl/drepl_out_helpers.c
+++ b/source4/dsdb/repl/drepl_out_helpers.c
@@ -33,6 +33,7 @@
 #include "librpc/gen_ndr/ndr_drsblobs.h"
 #include "libcli/composite/composite.h"
 #include "auth/gensec/gensec.h"
+#include "param/param.h"
 
 struct dreplsrv_out_drsuapi_state {
        struct composite_context *creq;
@@ -355,6 +356,8 @@ static void dreplsrv_op_pull_source_get_changes_recv(struct 
rpc_request *req)
        dreplsrv_op_pull_source_apply_changes_send(st, r, ctr_level, ctr1, 
ctr6);
 }
 
+static void dreplsrv_update_refs_send(struct dreplsrv_op_pull_source_state 
*st);
+
 static void dreplsrv_op_pull_source_apply_changes_send(struct 
dreplsrv_op_pull_source_state *st,
                                                       struct 
drsuapi_DsGetNCChanges *r,
                                                       uint32_t ctr_level,
@@ -430,7 +433,12 @@ static void 
dreplsrv_op_pull_source_apply_changes_send(struct dreplsrv_op_pull_s
                return;
        }
 
-       composite_done(c);
+       /* now we need to update the repsTo record for this partition
+          on the server. These records are initially established when
+          we join the domain, but they quickly expire.  We do it here
+          so we can use the already established DRSUAPI pipe
+       */
+       dreplsrv_update_refs_send(st);
 }
 
 WERROR dreplsrv_op_pull_source_recv(struct composite_context *c)
@@ -442,3 +450,81 @@ WERROR dreplsrv_op_pull_source_recv(struct 
composite_context *c)
        talloc_free(c);
        return ntstatus_to_werror(status);
 }
+
+/*
+  receive a UpdateRefs reply
+ */
+static void dreplsrv_update_refs_recv(struct rpc_request *req)
+{
+       struct dreplsrv_op_pull_source_state *st = 
talloc_get_type(req->async.private_data,
+                                                  struct 
dreplsrv_op_pull_source_state);
+       struct composite_context *c = st->creq;
+       struct drsuapi_DsReplicaUpdateRefs *r = 
talloc_get_type(req->ndr.struct_ptr,
+                                                               struct 
drsuapi_DsReplicaUpdateRefs);
+
+       c->status = dcerpc_ndr_request_recv(req);
+       if (!composite_is_ok(c)) {
+               DEBUG(0,("UpdateRefs failed with %s for %s %s\n", 
+                        nt_errstr(c->status),
+                        r->in.req.req1.dest_dsa_dns_name,
+                        r->in.req.req1.naming_context->dn));
+               return;
+       }
+
+       if (!W_ERROR_IS_OK(r->out.result)) {
+               DEBUG(0,("UpdateRefs failed with %s for %s %s\n", 
+                        win_errstr(r->out.result),
+                        r->in.req.req1.dest_dsa_dns_name,
+                        r->in.req.req1.naming_context->dn));
+               composite_error(c, werror_to_ntstatus(r->out.result));
+               return;
+       }
+
+       DEBUG(4,("UpdateRefs OK for %s %s\n", 
+                r->in.req.req1.dest_dsa_dns_name,
+                r->in.req.req1.naming_context->dn));
+
+       composite_done(c);
+}
+
+/*
+  send a UpdateRefs request to refresh our repsTo record on the server
+ */
+static void dreplsrv_update_refs_send(struct dreplsrv_op_pull_source_state *st)
+{
+       struct composite_context *c = st->creq;
+       struct dreplsrv_service *service = st->op->service;
+       struct dreplsrv_partition *partition = st->op->source_dsa->partition;
+       struct dreplsrv_drsuapi_connection *drsuapi = 
st->op->source_dsa->conn->drsuapi;
+       struct rpc_request *req;
+       struct drsuapi_DsReplicaUpdateRefs *r;
+       char *ntds_guid_str;
+       char *ntds_dns_name;
+
+       r = talloc(st, struct drsuapi_DsReplicaUpdateRefs);
+       if (composite_nomem(r, c)) return;
+
+       ntds_guid_str = GUID_string(r, &service->ntds_guid);
+       if (composite_nomem(ntds_guid_str, c)) return;
+
+       /* lp_realm() is not really right here */
+       ntds_dns_name = talloc_asprintf(r, "%s._msdcs.%s",
+                                       ntds_guid_str,
+                                       lp_realm(service->task->lp_ctx));
+       if (composite_nomem(ntds_dns_name, c)) return;
+
+       r->in.bind_handle       = &drsuapi->bind_handle;
+       r->in.level             = 1;
+       r->in.req.req1.naming_context     = &partition->nc;
+       r->in.req.req1.dest_dsa_dns_name  = ntds_dns_name;
+       r->in.req.req1.dest_dsa_guid      = service->ntds_guid;
+       r->in.req.req1.options            = 
+               DRSUAPI_DS_REPLICA_UPDATE_ADD_REFERENCE |
+               DRSUAPI_DS_REPLICA_UPDATE_DELETE_REFERENCE;
+       if (!lp_parm_bool(service->task->lp_ctx, NULL, "repl", "RODC", false)) {
+               r->in.req.req1.options |= DRSUAPI_DS_REPLICA_UPDATE_WRITEABLE;
+       }
+
+       req = dcerpc_drsuapi_DsReplicaUpdateRefs_send(drsuapi->pipe, r, r);
+       composite_continue_rpc(c, req, dreplsrv_update_refs_recv, st);
+}


-- 
Samba Shared Repository

Reply via email to