The branch, master has been updated via 63c6209 updaterefs: Do not open transaction even when unnecessary via d055b20 drepl_server: Allow refresh of partitions on UpdateRef via 6c406fe dns_update: RODC updates should use lower case realm via b10ee68 rodc/dns: Do not put a trailing dot at end of a DNS record via 58113e5 join.py: Allow RODC to have push replication at join via 94256c9 password-lockout: Allow RODC to ensure lockout and lockout reset via 050d21a replmd: Reduce calls to ldb_request_get_control via 1cfabd6 rodc: Allow local RODC changes with version 0 via a6f62a4 drepl: Add partial attribute set in the case of repl secret via 613d9e2 password_lockout: Tests against RODC (once preloaded) via f4170a4 tests/rodc: Add a number of tests for RODC-RWDC interaction via de26e2f sam.c: Make NTLM login set logonCount when unset via 7f0c839 password_lockout: Move some unnecessary methods from base via ad55cbb password_lockout: Move lockoutObservationWindow tests from setUp via a3cb12a password_lockout: Factor out a base testcase via 0beaef5 password_lockout: Remove use of global creds variables via 9510be0 password_lockout: Remove use of global lp and host vars via 0753eb0 password_lockout: Move more helper methods to a base class via 9b523f0 password_lockout: Move more helper methods to a base class via cd7adbd password_lockout: Begin moving helper methods to a base class via 93af559 selftest: Make some assertions about RODC referrals via b3ba0c8 rodc: Force all RODC add and delete to cause a referral via 63a8376 selftest: Add ldap rodc python test via c7a8a9c replmd: Send RODC referrals preferably to the PDC via acc66d9 drsuapi.idl: Expose GetNCChanges req8 like req10 via 6e8fcd8 samba_dnsupdate: Remove extra argument from debug via 7915987 winbindd: Make some debugging clearer via 147c0b5 whitespace: Remove some whitespace from 9cf3ac1 s3:tests: fix commment typo in the offline test
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 63c6209f5c04e4fe1ac41a034d2f0d06d7709305 Author: Garming Sam <garm...@catalyst.net.nz> Date: Wed Mar 29 15:21:04 2017 +1300 updaterefs: Do not open transaction even when unnecessary This can be called during GetNCChanges (a generally read-only call), it is not wise to be blocking the database for no reason. Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> Autobuild-User(master): Garming Sam <garm...@samba.org> Autobuild-Date(master): Thu Apr 13 11:25:06 CEST 2017 on sn-devel-144 commit d055b202985e175a9e6282d9cb9ce767b6202ec1 Author: Garming Sam <garm...@catalyst.net.nz> Date: Wed Mar 29 11:24:50 2017 +1300 drepl_server: Allow refresh of partitions on UpdateRef When we call UpdateRef, the push replication will not begin until the drepl_server has done its periodic refresh. If UpdateRefs is called, we should just send an IRPC message to call the refresh. NOTE: This has the same dependencies and issues as repl_secrets in auth_sam.c in terms of IRPC implementation. Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 6c406feef989bdccb209b37f797fbcb79ef667a6 Author: Garming Sam <garm...@catalyst.net.nz> Date: Mon Apr 3 15:31:14 2017 +1200 dns_update: RODC updates should use lower case realm This is consistent with the standard update list we write. Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit b10ee68600bbdf51d71d9b46edbc4de846955580 Author: Garming Sam <garm...@catalyst.net.nz> Date: Wed Mar 29 13:16:48 2017 +1300 rodc/dns: Do not put a trailing dot at end of a DNS record This causes RESOLV_WRAPPER to not detect the record correctly (while also creating inconsistent and possibly breaking records). Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 58113e5bc954aba470e1d240d74d7210e9a22dca Author: Garming Sam <garm...@catalyst.net.nz> Date: Tue Mar 28 14:29:26 2017 +1300 join.py: Allow RODC to have push replication at join Normally DsAddEntry connects to DRSUAPI, however not in the RODC case. This meant that it never called DsReplicaUpdateRefs and so never got push-replication after join. Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 94256c9606f7525d0c426cf2ae1f17f46d4e1704 Author: Garming Sam <garm...@catalyst.net.nz> Date: Tue Mar 28 14:34:01 2017 +1300 password-lockout: Allow RODC to ensure lockout and lockout reset Prior to this, the modification of lockoutTime triggered referrals. Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 050d21ab96de0ff2301c274319cdbf335f0d813e Author: Garming Sam <garm...@catalyst.net.nz> Date: Thu Mar 30 15:50:01 2017 +1300 replmd: Reduce calls to ldb_request_get_control Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 1cfabd663dd3c25d4cfc71cc686c7821d453a6d5 Author: Garming Sam <garm...@catalyst.net.nz> Date: Fri Mar 24 10:24:21 2017 +1300 rodc: Allow local RODC changes with version 0 These changes will get clobbered by RWDCs through replication. This behaviour is required for lockoutTime to enforce the password lockout locally on the RODC (and is consistent with Windows). Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit a6f62a4c0b8fc8a94c78d9e7692c3d73408ecf37 Author: Garming Sam <garm...@catalyst.net.nz> Date: Fri Mar 17 16:09:06 2017 +1300 drepl: Add partial attribute set in the case of repl secret Against Windows, the call will always fail without it. Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 613d9e234e2227337bcdf0b1eedc7dbd21e54c25 Author: Garming Sam <garm...@catalyst.net.nz> Date: Thu Apr 6 16:26:26 2017 +1200 password_lockout: Tests against RODC (once preloaded) In this scenario, both the login server and the verification server are the RODC. This tests that a user is locked out correctly once the lockout limit is reached and they are also unlocked correctly when the lockout time period expires. Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit f4170a49fb4b3d35053cd2ded1ff318d2dab6122 Author: Garming Sam <garm...@catalyst.net.nz> Date: Mon Apr 10 10:16:57 2017 +1200 tests/rodc: Add a number of tests for RODC-RWDC interaction This tests password fallback to RWDC in preloaded and non-preloaded cases. It also tests some basic scenarios around what things are replicated between the two DCs. Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> Pair-programmed-with: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> commit de26e2f87aaa6255ed87f5d97509a1af9ca221ec Author: Garming Sam <garm...@catalyst.net.nz> Date: Fri Apr 7 14:41:05 2017 +1200 sam.c: Make NTLM login set logonCount when unset Previously, it only bothered if it was being incremented. Now on first logon, it should turn the unset logonCount to 0. Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 7f0c839bfbf9e9473b03fd096c3cf4ba257a5f37 Author: Garming Sam <garm...@catalyst.net.nz> Date: Thu Apr 6 16:57:13 2017 +1200 password_lockout: Move some unnecessary methods from base Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit ad55cbb62c0d1c610421fc5cfb69a86eb90d5550 Author: Garming Sam <garm...@catalyst.net.nz> Date: Thu Apr 6 16:21:53 2017 +1200 password_lockout: Move lockoutObservationWindow tests from setUp These should not belong in the setUp, and should be a separate test. Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit a3cb12a7d840f68dc6461cb2622139a5e94b82e1 Author: Garming Sam <garm...@catalyst.net.nz> Date: Thu Apr 6 15:53:25 2017 +1200 password_lockout: Factor out a base testcase This allows it to be used for the RODC testing. Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 0beaef561c8bcd9a1566320f69c54c0a5124e35e Author: Garming Sam <garm...@catalyst.net.nz> Date: Mon Apr 10 16:12:21 2017 +1200 password_lockout: Remove use of global creds variables This is so that we can import the login tests into the RODC-RWDC tests. Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 9510be0c924460f75630c5c6869219d60cd4f5bd Author: Garming Sam <garm...@catalyst.net.nz> Date: Mon Apr 10 16:08:57 2017 +1200 password_lockout: Remove use of global lp and host vars This is so that we can import the login tests into the RODC-RWDC tests. Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 0753eb05be80ab8ddf7168f61c5d40d2da5a5575 Author: Garming Sam <garm...@catalyst.net.nz> Date: Mon Apr 10 16:33:03 2017 +1200 password_lockout: Move more helper methods to a base class This is so that we can import the login tests into the RODC-RWDC tests. Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 9b523f0137670e5fcd360c21982c0e7e097cd055 Author: Garming Sam <garm...@catalyst.net.nz> Date: Mon Apr 10 16:48:23 2017 +1200 password_lockout: Move more helper methods to a base class This is so that we can import the login tests into the RODC-RWDC tests. Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit cd7adbd02277a02a6f4c154ed46a4d3577d05a60 Author: Garming Sam <garm...@catalyst.net.nz> Date: Wed Apr 5 14:30:28 2017 +1200 password_lockout: Begin moving helper methods to a base class This is so that we can import the login tests into the RODC-RWDC tests. Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 93af559afdc70a84e0b867f67ca2fd4b271ee787 Author: Garming Sam <garm...@catalyst.net.nz> Date: Mon Apr 10 10:41:44 2017 +1200 selftest: Make some assertions about RODC referrals Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit b3ba0c85ffe08c39b9144b644b6aabca4ca17dfe Author: Garming Sam <garm...@catalyst.net.nz> Date: Tue Sep 20 04:25:34 2016 +0000 rodc: Force all RODC add and delete to cause a referral Previously, you could add or delete and cause replication conflicts on an RODC. Modifies are already partly restricted in repl_meta_data and have more specific requirements, so they cannot be handled here. We still differ against Windows for modifies of non-replicated attributes over LDAP. Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> Pair-programmed-with: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> BUG: https://bugzilla.samba.org/show_bug.cgi?id=12008 commit 63a8376b6bf6523094f86169197c11eace45cae4 Author: Garming Sam <garm...@catalyst.net.nz> Date: Tue Mar 14 10:36:13 2017 +1300 selftest: Add ldap rodc python test Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> Pair-programmed-with: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> BUG: https://bugzilla.samba.org/show_bug.cgi?id=12008 commit c7a8a9c991d1601c9c8676303798ee574b4267a0 Author: Garming Sam <garm...@catalyst.net.nz> Date: Tue Apr 4 13:13:16 2017 +1200 replmd: Send RODC referrals preferably to the PDC The Windows protocol test suites check that a particular DC is used when sending referrals. Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> BUG: https://bugzilla.samba.org/show_bug.cgi?id=12008 commit acc66d91b2755e0535113cdbbec1c50ddb4a54a7 Author: Garming Sam <garm...@catalyst.net.nz> Date: Tue Apr 4 12:18:42 2017 +1200 drsuapi.idl: Expose GetNCChanges req8 like req10 Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 6e8fcd883362aef8bf1053e9adb94d827ebe9f21 Author: Garming Sam <garm...@catalyst.net.nz> Date: Wed Mar 29 10:32:39 2017 +1300 samba_dnsupdate: Remove extra argument from debug Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 7915987dbac29ab0abf577d6a980ba247fa91f94 Author: Garming Sam <garm...@catalyst.net.nz> Date: Tue Apr 4 12:21:34 2017 +1200 winbindd: Make some debugging clearer Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 147c0b50ba7aed1cec8f0bbfdf90a014838b5f60 Author: Garming Sam <garm...@catalyst.net.nz> Date: Tue Apr 4 13:11:16 2017 +1200 whitespace: Remove some whitespace Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> ----------------------------------------------------------------------- Summary of changes: librpc/idl/drsuapi.idl | 2 +- python/samba/join.py | 6 +- selftest/knownfail | 3 + source3/winbindd/winbindd_pam.c | 4 +- source4/auth/sam.c | 89 +- source4/dsdb/dns/dns_update.c | 17 +- source4/dsdb/repl/drepl_out_helpers.c | 2 +- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 109 ++- source4/dsdb/samdb/ldb_modules/samldb.c | 74 +- source4/dsdb/samdb/samdb.h | 6 + source4/dsdb/tests/python/password_lockout.py | 1000 ++++---------------- source4/dsdb/tests/python/password_lockout_base.py | 776 +++++++++++++++ source4/dsdb/tests/python/rodc.py | 252 +++++ source4/dsdb/tests/python/rodc_rwdc.py | 715 ++++++++++++++ source4/rpc_server/drsuapi/dcesrv_drsuapi.h | 4 +- source4/rpc_server/drsuapi/getncchanges.c | 4 +- source4/rpc_server/drsuapi/updaterefs.c | 104 +- source4/scripting/bin/samba_dnsupdate | 2 +- source4/selftest/tests.py | 13 + source4/setup/schema_samba4.ldif | 2 + 20 files changed, 2279 insertions(+), 905 deletions(-) create mode 100644 source4/dsdb/tests/python/password_lockout_base.py create mode 100755 source4/dsdb/tests/python/rodc.py create mode 100644 source4/dsdb/tests/python/rodc_rwdc.py Changeset truncated at 500 lines: diff --git a/librpc/idl/drsuapi.idl b/librpc/idl/drsuapi.idl index d08054f..2eb1d65 100644 --- a/librpc/idl/drsuapi.idl +++ b/librpc/idl/drsuapi.idl @@ -561,7 +561,7 @@ interface drsuapi [size_is(num_attids)] drsuapi_DsAttributeId attids[]; } drsuapi_DsPartialAttributeSet; - typedef struct { + typedef [public] struct { GUID destination_dsa_guid; GUID source_dsa_invocation_id; /* the 'invocationId' field of the CN=NTDS Settings object */ [ref] drsuapi_DsReplicaObjectIdentifier *naming_context; diff --git a/python/samba/join.py b/python/samba/join.py index 88b8d4b..6a92435 100644 --- a/python/samba/join.py +++ b/python/samba/join.py @@ -964,8 +964,10 @@ class dc_join(object): if not ctx.RODC: r.options |= drsuapi.DRSUAPI_DRS_WRIT_REP - if ctx.drsuapi: - ctx.drsuapi.DsReplicaUpdateRefs(ctx.drsuapi_handle, 1, r) + if ctx.drsuapi is None: + ctx.drsuapi_connect() + + ctx.drsuapi.DsReplicaUpdateRefs(ctx.drsuapi_handle, 1, r) def join_finalise(ctx): """Finalise the join, mark us synchronised and setup secrets db.""" diff --git a/selftest/knownfail b/selftest/knownfail index 1a606c8..2cc9c70 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -326,3 +326,6 @@ ^samba4.blackbox.trust_ntlm.Test08.*client.*with.ADDOM.SAMBA.EXAMPLE.COM\\Administrator%locDCpass1\(fl2003dc:local\) ^samba4.blackbox.trust_ntlm.Test09.*client.*with.Administrator@ADDOMAIN%locDCpass1\(fl2003dc:local\) ^samba4.blackbox.trust_ntlm.Test10.*client.*with.administra...@addom.samba.example.com%locDCpass1\(fl2003dc:local\) +# We currently don't send referrals for LDAP modify of non-replicated attrs +^samba4.ldap.rodc.python\(rodc\).__main__.RodcTests.test_modify_nonreplicated.* +^samba4.ldap.rodc_rwdc.python.*.__main__.RodcRwdcTests.test_change_password_reveal_on_demand_kerberos diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 718acd7..c792cfe 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -1420,7 +1420,7 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain, */ DEBUG(3, ("This is the third problem for this " "particular call, adding DC to the " - "negative cache list\n")); + "negative cache list: %s %s\n", domain->name, domain->dcname)); add_failed_connection_entry(domain->name, domain->dcname, result); @@ -1530,7 +1530,7 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain, if (NT_STATUS_EQUAL(result, NT_STATUS_IO_TIMEOUT)) { DEBUG(3,("winbind_samlogon_retry_loop: sam_network_logon(ex) " - "returned NT_STATUS_IO_TIMEOUT after the retry." + "returned NT_STATUS_IO_TIMEOUT after the retry. " "Killing connections to domain %s\n", domainname)); invalidate_cm_connection(domain); diff --git a/source4/auth/sam.c b/source4/auth/sam.c index 7df23d5..9b0f061 100644 --- a/source4/auth/sam.c +++ b/source4/auth/sam.c @@ -702,13 +702,36 @@ NTSTATUS authsam_update_bad_pwd_count(struct ldb_context *sam_ctx, } if (msg_mod != NULL) { - ret = dsdb_modify(sam_ctx, msg_mod, 0); + struct ldb_request *req; + + ret = ldb_build_mod_req(&req, sam_ctx, sam_ctx, + msg_mod, + NULL, + NULL, + ldb_op_default_callback, + NULL); if (ret != LDB_SUCCESS) { - DEBUG(0, ("Failed to update badPwdCount, badPasswordTime or set lockoutTime on %s: %s\n", - ldb_dn_get_linearized(msg_mod->dn), ldb_errstring(sam_ctx))); - TALLOC_FREE(mem_ctx); - return NT_STATUS_INTERNAL_ERROR; + goto done; + } + + ret = ldb_request_add_control(req, + DSDB_CONTROL_FORCE_RODC_LOCAL_CHANGE, + false, NULL); + if (ret != LDB_SUCCESS) { + talloc_free(req); + goto done; } + + ret = dsdb_autotransaction_request(sam_ctx, req); + talloc_free(req); + } + +done: + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Failed to update badPwdCount, badPasswordTime or set lockoutTime on %s: %s\n", + ldb_dn_get_linearized(msg_mod->dn), ldb_errstring(sam_ctx))); + TALLOC_FREE(mem_ctx); + return NT_STATUS_INTERNAL_ERROR; } TALLOC_FREE(mem_ctx); @@ -901,6 +924,16 @@ NTSTATUS authsam_logon_success_accounting(struct ldb_context *sam_ctx, TALLOC_FREE(mem_ctx); return NT_STATUS_NO_MEMORY; } + } else { + /* Set an unset logonCount to 0 on first successful login */ + if (ldb_msg_find_ldb_val(msg, "logonCount") == NULL) { + ret = samdb_msg_add_int(sam_ctx, msg_mod, msg_mod, + "logonCount", 0); + if (ret != LDB_SUCCESS) { + TALLOC_FREE(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + } } ret = samdb_rodc(sam_ctx, &am_rodc); @@ -920,17 +953,47 @@ NTSTATUS authsam_logon_success_accounting(struct ldb_context *sam_ctx, } if (msg_mod->num_elements > 0) { - ret = dsdb_replace(sam_ctx, msg_mod, 0); + unsigned int i; + struct ldb_request *req; + + /* mark all the message elements as LDB_FLAG_MOD_REPLACE */ + for (i=0;i<msg_mod->num_elements;i++) { + msg_mod->elements[i].flags = LDB_FLAG_MOD_REPLACE; + } + + ret = ldb_build_mod_req(&req, sam_ctx, sam_ctx, + msg_mod, + NULL, + NULL, + ldb_op_default_callback, + NULL); if (ret != LDB_SUCCESS) { - DEBUG(0, ("Failed to set badPwdCount and lockoutTime " - "to 0 and/or lastlogon to now (%lld) " - "%s: %s\n", (long long int)now, - ldb_dn_get_linearized(msg_mod->dn), - ldb_errstring(sam_ctx))); - TALLOC_FREE(mem_ctx); - return NT_STATUS_INTERNAL_ERROR; + goto done; } + + ret = ldb_request_add_control(req, + DSDB_CONTROL_FORCE_RODC_LOCAL_CHANGE, + false, NULL); + if (ret != LDB_SUCCESS) { + talloc_free(req); + goto done; + } + + ret = dsdb_autotransaction_request(sam_ctx, req); + talloc_free(req); } + +done: + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Failed to set badPwdCount and lockoutTime " + "to 0 and/or lastlogon to now (%lld) " + "%s: %s\n", (long long int)now, + ldb_dn_get_linearized(msg_mod->dn), + ldb_errstring(sam_ctx))); + TALLOC_FREE(mem_ctx); + return NT_STATUS_INTERNAL_ERROR; + } + TALLOC_FREE(mem_ctx); return NT_STATUS_OK; } diff --git a/source4/dsdb/dns/dns_update.c b/source4/dsdb/dns/dns_update.c index 0591e34..8962b08 100644 --- a/source4/dsdb/dns/dns_update.c +++ b/source4/dsdb/dns/dns_update.c @@ -515,7 +515,7 @@ static NTSTATUS dnsupdate_dnsupdate_RODC(struct irpc_message *msg, /* find dnsdomain and dnsforest */ - dnsdomain = lpcfg_realm(s->task->lp_ctx); + dnsdomain = lpcfg_dnsdomain(s->task->lp_ctx); dnsforest = dnsdomain; /* find the hostname */ @@ -531,36 +531,35 @@ static NTSTATUS dnsupdate_dnsupdate_RODC(struct irpc_message *msg, return NT_STATUS_OK; } - for (i=0; i<st->r->in.dns_names->count; i++) { struct NL_DNS_NAME_INFO *n = &r->in.dns_names->names[i]; switch (n->type) { case NlDnsLdapAtSite: - dprintf(st->fd, "SRV _ldap._tcp.%s._sites.%s. %s %u\n", + dprintf(st->fd, "SRV _ldap._tcp.%s._sites.%s %s %u\n", site, dnsdomain, hostname, n->port); break; case NlDnsGcAtSite: - dprintf(st->fd, "SRV _ldap._tcp.%s._sites.gc._msdcs.%s. %s %u\n", + dprintf(st->fd, "SRV _ldap._tcp.%s._sites.gc._msdcs.%s %s %u\n", site, dnsdomain, hostname, n->port); break; case NlDnsDsaCname: - dprintf(st->fd, "CNAME %s._msdcs.%s. %s\n", + dprintf(st->fd, "CNAME %s._msdcs.%s %s\n", ntdsguid, dnsforest, hostname); break; case NlDnsKdcAtSite: - dprintf(st->fd, "SRV _kerberos._tcp.%s._sites.dc._msdcs.%s. %s %u\n", + dprintf(st->fd, "SRV _kerberos._tcp.%s._sites.dc._msdcs.%s %s %u\n", site, dnsdomain, hostname, n->port); break; case NlDnsDcAtSite: - dprintf(st->fd, "SRV _ldap._tcp.%s._sites.dc._msdcs.%s. %s %u\n", + dprintf(st->fd, "SRV _ldap._tcp.%s._sites.dc._msdcs.%s %s %u\n", site, dnsdomain, hostname, n->port); break; case NlDnsRfc1510KdcAtSite: - dprintf(st->fd, "SRV _kerberos._tcp.%s._sites.%s. %s %u\n", + dprintf(st->fd, "SRV _kerberos._tcp.%s._sites.%s %s %u\n", site, dnsdomain, hostname, n->port); break; case NlDnsGenericGcAtSite: - dprintf(st->fd, "SRV _gc._tcp.%s._sites.%s. %s %u\n", + dprintf(st->fd, "SRV _gc._tcp.%s._sites.%s %s %u\n", site, dnsforest, hostname, n->port); break; } diff --git a/source4/dsdb/repl/drepl_out_helpers.c b/source4/dsdb/repl/drepl_out_helpers.c index ac0b947..d526f45 100644 --- a/source4/dsdb/repl/drepl_out_helpers.c +++ b/source4/dsdb/repl/drepl_out_helpers.c @@ -498,7 +498,7 @@ static void dreplsrv_op_pull_source_get_changes_trigger(struct tevent_req *req) return; } replica_flags &= ~DRSUAPI_DRS_WRIT_REP; - } else if (partition->rodc_replica) { + } else if (partition->rodc_replica || state->op->extended_op == DRSUAPI_EXOP_REPL_SECRET) { bool for_schema = false; if (ldb_dn_compare_base(schema_dn, partition->dn) == 0) { for_schema = true; diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index d9b414d..4f077c0 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -41,6 +41,7 @@ #include "dsdb/common/proto.h" #include "dsdb/common/util.h" #include "../libds/common/flags.h" +#include "librpc/gen_ndr/irpc.h" #include "librpc/gen_ndr/ndr_misc.h" #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_drsblobs.h" @@ -234,7 +235,6 @@ static bool replmd_check_urgent_attribute(const struct ldb_message_element *el) return false; } - static int replmd_replicated_apply_isDeleted(struct replmd_replicated_request *ar); /* @@ -1367,6 +1367,7 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb, const struct GUID *our_invocation_id, NTTIME now, bool is_schema_nc, + bool is_forced_rodc, struct ldb_request *req) { uint32_t i; @@ -1505,6 +1506,7 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb, md1 = &omd->ctr.ctr1.array[i]; md1->version++; md1->attid = attid; + if (md1->attid == DRSUAPI_ATTID_isDeleted) { const struct ldb_val *rdn_val = ldb_dn_get_rdn_val(msg->dn); const char* rdn; @@ -1531,6 +1533,11 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb, md1->originating_usn = *seq_num; md1->local_usn = *seq_num; + if (is_forced_rodc) { + /* Force version to 0 to be overriden later via replication */ + md1->version = 0; + } + return LDB_SUCCESS; } @@ -1551,7 +1558,8 @@ static int replmd_update_rpmd_rdn_attr(struct ldb_context *ldb, struct replPropertyMetaDataBlob *omd, struct replmd_replicated_request *ar, NTTIME now, - bool is_schema_nc) + bool is_schema_nc, + bool is_forced_rodc) { const char *rdn_name = ldb_dn_get_rdn_name(msg->dn); const struct dsdb_attribute *rdn_attr = @@ -1582,7 +1590,8 @@ static int replmd_update_rpmd_rdn_attr(struct ldb_context *ldb, return replmd_update_rpmd_element(ldb, msg, &new_el, NULL, omd, ar->schema, &ar->seq_num, &ar->our_invocation_id, - now, is_schema_nc, ar->req); + now, is_schema_nc, is_forced_rodc, + ar->req); } @@ -1629,6 +1638,7 @@ static int replmd_update_rpmd(struct ldb_module *module, bool rmd_is_provided; bool rmd_is_just_resorted = false; const char *not_rename_attrs[4 + msg->num_elements]; + bool is_forced_rodc = false; if (rename_attrs) { attrs = rename_attrs; @@ -1645,6 +1655,17 @@ static int replmd_update_rpmd(struct ldb_module *module, ldb = ldb_module_get_ctx(module); + ret = samdb_rodc(ldb, rodc); + if (ret != LDB_SUCCESS) { + DEBUG(4, (__location__ ": unable to tell if we are an RODC\n")); + *rodc = false; + } + + if (*rodc && + ldb_request_get_control(req, DSDB_CONTROL_FORCE_RODC_LOCAL_CHANGE)) { + is_forced_rodc = true; + } + our_invocation_id = samdb_ntds_invocation_id(ldb); if (!our_invocation_id) { /* this happens during an initial vampire while @@ -1781,6 +1802,7 @@ static int replmd_update_rpmd(struct ldb_module *module, &omd, schema, seq_num, our_invocation_id, now, is_schema_nc, + is_forced_rodc, req); if (ret != LDB_SUCCESS) { return ret; @@ -1836,13 +1858,11 @@ static int replmd_update_rpmd(struct ldb_module *module, /*if we are RODC and this is a DRSR update then its ok*/ if (!ldb_request_get_control(req, DSDB_CONTROL_REPLICATED_UPDATE_OID) - && !ldb_request_get_control(req, DSDB_CONTROL_DBCHECK_MODIFY_RO_REPLICA)) { + && !ldb_request_get_control(req, DSDB_CONTROL_DBCHECK_MODIFY_RO_REPLICA) + && !is_forced_rodc) { unsigned instanceType; - ret = samdb_rodc(ldb, rodc); - if (ret != LDB_SUCCESS) { - DEBUG(4, (__location__ ": unable to tell if we are an RODC\n")); - } else if (*rodc) { + if (*rodc) { ldb_set_errstring(ldb, "RODC modify is forbidden!"); return LDB_ERR_REFERRAL; } @@ -3153,6 +3173,47 @@ static int replmd_modify_handle_linked_attribs(struct ldb_module *module, } +static int send_rodc_referral(struct ldb_request *req, + struct ldb_context *ldb, + struct ldb_dn *dn) +{ + char *referral = NULL; + struct loadparm_context *lp_ctx = NULL; + struct ldb_dn *fsmo_role_dn = NULL; + struct ldb_dn *role_owner_dn = NULL; + const char *domain = NULL; + WERROR werr; + + lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"), + struct loadparm_context); + + werr = dsdb_get_fsmo_role_info(req, ldb, DREPL_PDC_MASTER, + &fsmo_role_dn, &role_owner_dn); + + if (W_ERROR_IS_OK(werr)) { + struct ldb_dn *server_dn = ldb_dn_copy(req, role_owner_dn); + if (server_dn != NULL) { + ldb_dn_remove_child_components(server_dn, 1); + domain = samdb_dn_to_dnshostname(ldb, req, + server_dn); + } + } + + if (domain == NULL) { + domain = lpcfg_dnsdomain(lp_ctx); + } + + referral = talloc_asprintf(req, "ldap://%s/%s", + domain, + ldb_dn_get_linearized(dn)); + if (referral == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_module_send_referral(req, referral); +} + static int replmd_modify(struct ldb_module *module, struct ldb_request *req) { @@ -3225,19 +3286,10 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) msg, &ac->seq_num, t, is_schema_nc, &is_urgent, &rodc); if (rodc && (ret == LDB_ERR_REFERRAL)) { - struct loadparm_context *lp_ctx; - char *referral; - - lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"), - struct loadparm_context); - - referral = talloc_asprintf(req, - "ldap://%s/%s", - lpcfg_dnsdomain(lp_ctx), - ldb_dn_get_linearized(msg->dn)); - ret = ldb_module_send_referral(req, referral); + ret = send_rodc_referral(req, ldb, msg->dn); talloc_free(ac); return ret; + } if (ret != LDB_SUCCESS) { @@ -3497,18 +3549,7 @@ static int replmd_rename_callback(struct ldb_request *req, struct ldb_reply *are msg, &ac->seq_num, t, is_schema_nc, &is_urgent, &rodc); if (rodc && (ret == LDB_ERR_REFERRAL)) { - struct ldb_dn *olddn = ac->req->op.rename.olddn; - struct loadparm_context *lp_ctx; - char *referral; - - lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"), - struct loadparm_context); - - referral = talloc_asprintf(req, - "ldap://%s/%s", - lpcfg_dnsdomain(lp_ctx), - ldb_dn_get_linearized(olddn)); - ret = ldb_module_send_referral(req, referral); + ret = send_rodc_referral(req, ldb, ac->req->op.rename.olddn); talloc_free(ares); return ldb_module_done(req, NULL, NULL, ret); } @@ -4921,7 +4962,8 @@ static int replmd_replicated_apply_add(struct replmd_replicated_request *ar) rdn_val = ldb_dn_get_rdn_val(msg->dn); ret = replmd_update_rpmd_rdn_attr(ldb, msg, rdn_val, NULL, - md, ar, now, is_schema_nc); + md, ar, now, is_schema_nc, + false); if (ret != LDB_SUCCESS) { ldb_asprintf_errstring(ldb, "%s: error during DRS repl ADD: %s", __func__, ldb_errstring(ldb)); return replmd_replicated_request_error(ar, ret); @@ -5651,7 +5693,8 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar) if (renamed) { ret = replmd_update_rpmd_rdn_attr(ldb, msg, new_rdn, old_rdn, - &nmd, ar, now, is_schema_nc); + &nmd, ar, now, is_schema_nc, + false); if (ret != LDB_SUCCESS) { ldb_asprintf_errstring(ldb, "%s: error during DRS repl merge: %s", __func__, ldb_errstring(ldb)); return replmd_replicated_request_error(ar, ret); diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 2c47ff1..971048d 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -44,6 +44,7 @@ #include "param/param.h" #include "libds/common/flag_mapping.h" #include "system/network.h" +#include "librpc/gen_ndr/irpc.h" struct samldb_ctx; enum samldb_add_type { @@ -2850,12 +2851,12 @@ static int samldb_service_principal_names_change(struct samldb_ctx *ac) if (ret != LDB_SUCCESS) { return ret; } - dns_hostname = talloc_strdup(ac, + dns_hostname = talloc_strdup(ac, ldb_msg_find_attr_as_string(msg, "dNSHostName", NULL)); -- Samba Shared Repository