diff options
author | Andrew Tridgell <tridge@samba.org> | 2009-09-09 17:04:16 +1000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2009-09-09 17:04:16 +1000 |
commit | 939b936d1af9a5221922864ad579bf50157b957b (patch) | |
tree | 042fffd75b217a8e8ed9d6df483232f1fc5dea1c | |
parent | dca7afb799477a34f704c04397a6afa1ee6b9973 (diff) | |
download | samba-939b936d1af9a5221922864ad579bf50157b957b.tar.gz samba-939b936d1af9a5221922864ad579bf50157b957b.tar.bz2 samba-939b936d1af9a5221922864ad579bf50157b957b.zip |
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
-rw-r--r-- | source4/dsdb/repl/drepl_out_helpers.c | 88 |
1 files changed, 87 insertions, 1 deletions
diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c index c292c6db74..59b3176444 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); +} |