From 7a623d8d5626b4e6c88ffb85e36f0934d89ed830 Mon Sep 17 00:00:00 2001 From: Douglas Bagnall Date: Wed, 7 Aug 2024 17:25:30 +1200 Subject: [PATCH] s4:drsuapi:getncchanges: allow 0 reserved_usn reply Azure AD will set reserved_usn to zero when we expect it to be the number we gave them. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15701 Signed-off-by: Douglas Bagnall Reviewed-by: Jennifer Sutton --- selftest/knownfail.d/getncchanges-azure-ad | 5 -- source4/rpc_server/drsuapi/getncchanges.c | 71 +++++++++++++++++++--- 2 files changed, 61 insertions(+), 15 deletions(-) delete mode 100644 selftest/knownfail.d/getncchanges-azure-ad diff --git a/selftest/knownfail.d/getncchanges-azure-ad b/selftest/knownfail.d/getncchanges-azure-ad deleted file mode 100644 index a8e05bb47f9..00000000000 --- a/selftest/knownfail.d/getncchanges-azure-ad +++ /dev/null @@ -1,5 +0,0 @@ -^samba4.drs.getncchanges.python\(vampire_dc\).getncchanges.DrsReplicaSyncFakeAzureAdTests.test_repl_get_tgt_multivalued_links\(vampire_dc\) -^samba4.drs.getncchanges.python\(vampire_dc\).getncchanges.DrsReplicaSyncFakeAzureAdTests.test_repl_integrity\(vampire_dc\) -^samba4.drs.getncchanges.python\(vampire_dc\).getncchanges.DrsReplicaSyncFakeAzureAdTests.test_repl_integrity_link_attr\(vampire_dc\) -^samba4.drs.getncchanges.python\(promoted_dc\).getncchanges.DrsReplicaSyncFakeAzureAdTests.test_repl_integrity\(promoted_dc\) -^samba4.drs.getncchanges.python\(promoted_dc\).getncchanges.DrsReplicaSyncFakeAzureAdTests.test_repl_integrity_link_attr\(promoted_dc\) diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index d37662bdceb..a73efe93eb9 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -3029,16 +3029,67 @@ allowed: ret = drsuapi_DsReplicaHighWaterMark_cmp(&getnc_state->last_hwm, &req10->highwatermark); if (ret != 0) { - DBG_ERR("DsGetNCChanges 2nd replication " - "on DN %s %s highwatermark " - "(last_dn %s)\n", - ldb_dn_get_linearized( - getnc_state->ncRoot_dn), - (ret > 0) ? "older" : "newer", - ldb_dn_get_linearized( - getnc_state->last_dn)); - TALLOC_FREE(getnc_state); - b_state->getncchanges_full_repl_state = NULL; + if (req10->highwatermark.reserved_usn == 0) { + /* + * Entra ID Connect / Azure AD is known to set + * reserved_usn to zero in replies, when we + * were expecting it to be returned unchanged + * (it is supposed to be an opaque cookie). + * + * If the only difference is in the + * reserved_usn, and it is 0 on the return, we + * assume it is Azure AD and treat the + * highwatermarks as equal. + */ + req10->highwatermark.reserved_usn = + getnc_state->last_hwm.reserved_usn; + + ret = drsuapi_DsReplicaHighWaterMark_cmp( + &getnc_state->last_hwm, + &req10->highwatermark); + + /* put things as they were */ + req10->highwatermark.reserved_usn = 0; + + if (ret != 0) { + /* we will start again */ + DBG_ERR("DsGetNCChanges 2nd replication " + "on DN %s %s highwatermark " + "(last_dn %s) after Azure AD " + "reserved_usn adjustment\n", + ldb_dn_get_linearized( + getnc_state->ncRoot_dn), + (ret > 0) ? "older" : "newer", + ldb_dn_get_linearized( + getnc_state->last_dn)); + TALLOC_FREE(getnc_state); + b_state->getncchanges_full_repl_state = + NULL; + } else { + /* log and continue as normal */ + DBG_NOTICE( + "DsGetNCChanges 2nd replication " + "on DN %s: highwatermark " + "matches only after Azure AD " + "reserved_usn adjustment " + "(last_dn %s)\n", + ldb_dn_get_linearized( + getnc_state->ncRoot_dn), + ldb_dn_get_linearized( + getnc_state->last_dn)); + } + } else { + DBG_ERR("DsGetNCChanges 2nd replication " + "on DN %s %s highwatermark " + "(last_dn %s)\n", + ldb_dn_get_linearized( + getnc_state->ncRoot_dn), + (ret > 0) ? "older" : "newer", + ldb_dn_get_linearized( + getnc_state->last_dn)); + TALLOC_FREE(getnc_state); + b_state->getncchanges_full_repl_state = NULL; + } } } -- 2.47.3