s4/libnet: Fix joining a Windows pre-2008R2 DC
authorTim Beale <timbeale@catalyst.net.nz>
Mon, 1 Jul 2019 05:06:31 +0000 (17:06 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 4 Jul 2019 22:49:23 +0000 (22:49 +0000)
From v4.8 onwards, Samba may not be able join a DC older than 2008R2
because the Windows DC doesn't support GET_TGT.

If the dsdb repl_md code can't resolve a link target it returns an
error, and the calling code (e.g. drs_util.py) should retry with
GET_TGT. However, GET_TGT is only supported on Windows 2008R2 and later,
so if you try to join an earlier Windows DC, the join will throw an
error that you can't work-around.

We can avoid this problem by setting the same DSDB flag that GET_TGT
sets to indicate that the link targets are as up-to-date as possible,
and so there's no point retrying. Missing targets are still logged, so
this at least allows the admin to fix up any problems after the join
completed.

I've only done this for the join case (problems during periodic
replication are probably still worth escalating to an error).

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14021
RN: From Samba v4.8 onwards, joining a Windows 2003 or 2008 (non-R2) AD
DC may not have worked. When this problem occurred, the following
message would be displayed:
 'Failed to commit objects: DOS code 0x000021bf'
This particular issue has now been resolved. Note that there may still
be other potential problems that occur when joining an older Windows DC.

Signed-off-by: Tim Beale <timbeale@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/libnet/libnet_vampire.c

index 0a2f62d703bf913102f5ce7bddbb05ee76f3f95d..a0de1b7d3e005fa884cbed9652f2f8ad5e345d24 100644 (file)
@@ -665,6 +665,15 @@ WERROR libnet_vampire_cb_store_chunk(void *private_data,
                return WERR_INVALID_PARAMETER;
        }
 
+       /*
+        * If the peer DC doesn't support GET_TGT (req v10), then the link
+        * targets are as up-to-date as they're ever gonna be. (Without this,
+        * cases where we'd normally retry with GET_TGT cause the join to fail)
+        */
+       if (c->req_level < 10) {
+               dsdb_repl_flags |= DSDB_REPL_FLAG_TARGETS_UPTODATE;
+       }
+
        if (req_replica_flags & DRSUAPI_DRS_CRITICAL_ONLY || is_exop) {
                /*
                 * If we only replicate the critical objects, or this