The branch, master has been updated via fde9f7c81b4 CVE-2018-16857 dsdb/util: Add better default lockOutObservationWindow via 13014aea13a CVE-2018-16857 dsdb/util: Fix lockOutObservationWindow for PSOs via c7b937c5aae CVE-2018-16857 dsdb/util: Correctly treat lockOutObservationWindow as 64-bit int via 77de8278e4b CVE-2018-16857 tests: Sanity-check password lockout works with default values via 6ab51b2af90 CVE-2018-16853: fix crash in expired passowrd case via 7cddbcf039a CVE-2018-16853: Do not segfault if client is not set via c556ac5c66b CVE-2018-16853: Add a test to verify s4u2self doesn't crash via 6c453aeb0c7 CVE-2018-16853: The ticket in check_policy_as can actually be a TGS via bf0e9041bec CVE-2018-16853: Fix kinit test on system lacking ldbsearch via c5370a4349d CVE-2018-16853 WHATSNEW: The Samba AD DC, when build with MIT Kerberos is experimental via 07c49d25cdc CVE-2018-16853 build: The Samba AD DC, when build with MIT Kerberos is experimental via 9a12a001466 CVE-2018-16852 dcerpc dnsserver: refactor common properties handling via 2b00f8fa9fd CVE-2018-16852 dcerpc dnsserver: Ensure properties are handled correctly via c1d4033e09a CVE-2018-16852 dcerpc dnsserver: Verification tests via d2c98abde12 CVE-2018-16851 ldap_server: Check ret before manipulating blob via c835e27a998 CVE-2018-16841 selftest: Check for mismatching principal in certficate compared with principal in AS-REQ via b6e9c4b8bbd CVE-2018-16841 heimdal: Fix segfault on PKINIT with mis-matching principal via 97b426babaa CVE-2018-14629 dns: CNAME loop prevention using counter via c3f60859919 dns: prevent self-referencing CNAME from 1f42e62e46f notifyd: Improve a debug message
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit fde9f7c81b42419e71b2fc8c31d92db4a05176af Author: Tim Beale <timbe...@catalyst.net.nz> Date: Tue Nov 13 13:22:41 2018 +1300 CVE-2018-16857 dsdb/util: Add better default lockOutObservationWindow Clearly the lockOutObservationWindow value is important, and using a default value of zero doesn't work very well. This patch adds a better default value (the domain default setting of 30 minutes). BUG: https://bugzilla.samba.org/show_bug.cgi?id=13683 Signed-off-by: Tim Beale <timbe...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> Autobuild-User(master): Karolin Seeger <ksee...@samba.org> Autobuild-Date(master): Wed Nov 28 11:31:14 CET 2018 on sn-devel-144 commit 13014aea13a77f6a75ab948e2a29d814ebd9dd22 Author: Tim Beale <timbe...@catalyst.net.nz> Date: Tue Nov 13 13:19:04 2018 +1300 CVE-2018-16857 dsdb/util: Fix lockOutObservationWindow for PSOs Fix a remaining place where we were trying to read the msDS-LockoutObservationWindow as an int instead of an int64. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13683 Signed-off-by: Tim Beale <timbe...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit c7b937c5aae40483f2f37727758ed50877f17a5b Author: Tim Beale <timbe...@catalyst.net.nz> Date: Tue Nov 13 12:24:16 2018 +1300 CVE-2018-16857 dsdb/util: Correctly treat lockOutObservationWindow as 64-bit int Commit 442a38c918ae1666b35 refactored some code into a new get_lockout_observation_window() function. However, in moving the code, an ldb_msg_find_attr_as_int64() inadvertently got converted to a ldb_msg_find_attr_as_int(). ldb_msg_find_attr_as_int() will only work for values up to -2147483648 (about 3.5 minutes in MS timestamp form). Unfortunately, the automated tests used a low enough timeout that they still worked, however, password lockout would not work with the Samba default settings. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13683 Signed-off-by: Tim Beale <timbe...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 77de8278e4b467b66a477c09945a9bcc6b08b194 Author: Tim Beale <timbe...@catalyst.net.nz> Date: Tue Nov 13 11:49:56 2018 +1300 CVE-2018-16857 tests: Sanity-check password lockout works with default values Sanity-check that when we use the default lockOutObservationWindow that user lockout actually works. The easiest way to do this is to reuse the _test_login_lockout() test-case, but stop at the point where we wait for the lockout duration to expire (because we don't want the test to wait 30 mins). This highlights a problem currently where the default values don't work. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13683 Signed-off-by: Tim Beale <timbe...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 6ab51b2af90f5dca11b8587b2a16215ab4497069 Author: Isaac Boukris <ibouk...@gmail.com> Date: Wed Nov 7 22:53:35 2018 +0200 CVE-2018-16853: fix crash in expired passowrd case When calling encode_krb5_padata_sequence() make sure to pass a null terminated array as required. Fixes expired passowrd case in samba4.blackbox.kinit test. Signed-off-by: Isaac Boukris <ibouk...@gmail.com> Reviewed-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 7cddbcf039a7a67df2bae1779254e2a136f673f0 Author: Andreas Schneider <a...@samba.org> Date: Wed Sep 28 07:22:32 2016 +0200 CVE-2018-16853: Do not segfault if client is not set This can be triggered with FAST but we don't support this yet. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13571 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit c556ac5c66bf31e9065e723541ff6173e16ca70b Author: Isaac Boukris <ibouk...@gmail.com> Date: Sat Aug 18 16:01:59 2018 +0300 CVE-2018-16853: Add a test to verify s4u2self doesn't crash BUG: https://bugzilla.samba.org/show_bug.cgi?id=13571 Signed-off-by: Isaac Boukris <ibouk...@gmail.com> Reviewed-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 6c453aeb0c771d14fe501e9a37d9f51b9403872b Author: Isaac Boukris <ibouk...@gmail.com> Date: Sat Aug 18 00:40:30 2018 +0300 CVE-2018-16853: The ticket in check_policy_as can actually be a TGS This happens when we are called from S4U2Self flow, and in that case kdcreq->client is NULL. Use the name from client entry instead. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13571 Signed-off-by: Isaac Boukris <ibouk...@gmail.com> Reviewed-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit bf0e9041becde3ad15e03d820cd2919c708dd9f5 Author: Isaac Boukris <ibouk...@gmail.com> Date: Sat Aug 18 15:32:43 2018 +0300 CVE-2018-16853: Fix kinit test on system lacking ldbsearch By fixing bindir variable name. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13571 Signed-off-by: Isaac Boukris <ibouk...@gmail.com> Reviewed-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit c5370a4349d381ba3b64b063dc28a2c54cfacdfc Author: Andrew Bartlett <abart...@samba.org> Date: Tue Nov 6 13:40:48 2018 +1300 CVE-2018-16853 WHATSNEW: The Samba AD DC, when build with MIT Kerberos is experimental BUG: https://bugzilla.samba.org/show_bug.cgi?id=13678 Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Gary Lockyer <g...@catalyst.net.nz> commit 07c49d25cdca605bd84294603713d51f913a7ed2 Author: Andrew Bartlett <abart...@samba.org> Date: Tue Nov 6 13:32:05 2018 +1300 CVE-2018-16853 build: The Samba AD DC, when build with MIT Kerberos is experimental This matches https://wiki.samba.org/index.php/Running_a_Samba_AD_DC_with_MIT_Kerberos_KDC BUG: https://bugzilla.samba.org/show_bug.cgi?id=13678 Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Gary Lockyer <g...@catalyst.net.nz> commit 9a12a001466b21cfb27cb77ee01b11d84bcb36b4 Author: Gary Lockyer <g...@catalyst.net.nz> Date: Wed Nov 7 15:08:04 2018 +1300 CVE-2018-16852 dcerpc dnsserver: refactor common properties handling dnsserver_common.c and dnsutils.c both share similar code to process zone properties. This patch extracts the common code and moves it to dnsserver_common.c. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13669 Signed-off-by: Gary Lockyer <g...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 2b00f8fa9fdcecbd6951f09d528531c5585b9778 Author: Gary Lockyer <g...@catalyst.net.nz> Date: Tue Nov 6 12:16:30 2018 +1300 CVE-2018-16852 dcerpc dnsserver: Ensure properties are handled correctly Fixes for Bug 13669 - (CVE-2018-16852) NULL pointer de-reference in Samba AD DC DNS management The presence of the ZONE_MASTER_SERVERS property or the ZONE_SCAVENGING_SERVERS property in a zone record causes the server to follow a null pointer and terminate. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13669 Signed-off-by: Gary Lockyer <g...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit c1d4033e09acd5f7edfbafaf04b3b410a5b8e574 Author: Gary Lockyer <g...@catalyst.net.nz> Date: Tue Nov 6 12:10:07 2018 +1300 CVE-2018-16852 dcerpc dnsserver: Verification tests Tests to verify Bug 13669 - (CVE-2018-16852) NULL pointer de-reference in Samba AD DC DNS management The presence of the ZONE_MASTER_SERVERS property or the ZONE_SCAVENGING_SERVERS property in a zone record causes the server to follow a null pointer and terminate. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13669 Signed-off-by: Gary Lockyer <g...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit d2c98abde12d11d64cc62697f633fc5db75502ef Author: Garming Sam <garm...@catalyst.net.nz> Date: Mon Nov 5 16:18:18 2018 +1300 CVE-2018-16851 ldap_server: Check ret before manipulating blob In the case of hitting the talloc ~256MB limit, this causes a crash in the server. Note that you would actually need to load >256MB of data into the LDAP. Although there is some generated/hidden data which would help you reach that limit (descriptors and RMD blobs). BUG: https://bugzilla.samba.org/show_bug.cgi?id=13674 Signed-off-by: Garming Sam <garm...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit c835e27a998fa6bfb49a48581c65224c4c02880e Author: Andrew Bartlett <abart...@samba.org> Date: Wed Oct 24 15:41:28 2018 +1300 CVE-2018-16841 selftest: Check for mismatching principal in certficate compared with principal in AS-REQ BUG: https://bugzilla.samba.org/show_bug.cgi?id=13628 Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Gary Lockyer <g...@catalyst.net.nz> commit b6e9c4b8bbd63fbf29f576d98ee7ff1154a90565 Author: Andrew Bartlett <abart...@samba.org> Date: Tue Oct 23 17:33:46 2018 +1300 CVE-2018-16841 heimdal: Fix segfault on PKINIT with mis-matching principal In Heimdal KRB5_KDC_ERR_CLIENT_NAME_MISMATCH is an enum, so we tried to double-free mem_ctx. This was introduced in 9a0263a7c316112caf0265237bfb2cfb3a3d370d for the MIT KDC effort. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13628 Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Gary Lockyer <g...@catalyst.net.nz> commit 97b426babaa2a812946c77bd841a33c1a9399ab5 Author: Aaron Haslett <aaronhasl...@catalyst.net.nz> Date: Tue Oct 23 17:25:51 2018 +1300 CVE-2018-14629 dns: CNAME loop prevention using counter Count number of answers generated by internal DNS query routine and stop at 20 to match Microsoft's loop prevention mechanism. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13600 Signed-off-by: Aaron Haslett <aaronhasl...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Garming Sam <garm...@catalyst.net.nz> commit c3f6085991938488b9e48611b4beb5bdc9cbfb04 Author: Aaron Haslett <aaronhasl...@catalyst.net.nz> Date: Tue Oct 23 11:52:07 2018 +1300 dns: prevent self-referencing CNAME Stops the user from adding a self-referencing CNAME over RPC, which is an easy mistake to make with samba-tool. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13600 Signed-off-by: Aaron Haslett <aaronhasl...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Garming Sam <garm...@catalyst.net.nz> ----------------------------------------------------------------------- Summary of changes: WHATSNEW.txt | 11 + python/samba/tests/dns.py | 66 +++++ selftest/knownfail.d/dns | 7 + source4/dns_server/dns_query.c | 6 + source4/dns_server/dnsserver_common.c | 129 ++++++--- source4/dns_server/dnsserver_common.h | 3 + source4/dsdb/common/util.c | 20 +- source4/dsdb/tests/python/password_lockout.py | 30 ++ source4/dsdb/tests/python/password_lockout_base.py | 6 +- source4/kdc/db-glue.c | 6 +- source4/kdc/mit-kdb/kdb_samba_policies.c | 24 +- source4/kdc/mit_samba.c | 7 +- source4/ldap_server/ldap_server.c | 4 +- source4/rpc_server/dnsserver/dcerpc_dnsserver.c | 39 +++ source4/rpc_server/dnsserver/dnsutils.c | 59 +--- .../tests/rpc_dns_server_dnsutils_test.c | 304 +++++++++++++++++++++ source4/rpc_server/wscript_build | 17 +- source4/selftest/tests.py | 2 + testprogs/blackbox/test_kinit_mit.sh | 20 +- testprogs/blackbox/test_pkinit_heimdal.sh | 8 + wscript | 17 ++ 21 files changed, 673 insertions(+), 112 deletions(-) create mode 100644 source4/rpc_server/tests/rpc_dns_server_dnsutils_test.c Changeset truncated at 500 lines: diff --git a/WHATSNEW.txt b/WHATSNEW.txt index fc43edc8e86..23a88c295b5 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -78,6 +78,17 @@ Using the default sequence the restart delays (in seconds) are: REMOVED FEATURES ================ +MIT Kerberos build of the AD DC +------------------------------- + +While not removed, the MIT Kerberos build of the Samba AD DC is still +considered experimental. Because Samba will not issue security +patches for this configuration, such builds now require the explicit +configure option: --with-experimental-mit-ad-dc + +For further details see +https://wiki.samba.org/index.php/Running_a_Samba_AD_DC_with_MIT_Kerberos_KDC + samba_backup ------------ diff --git a/python/samba/tests/dns.py b/python/samba/tests/dns.py index 12cfb86c254..e35cded7b8c 100644 --- a/python/samba/tests/dns.py +++ b/python/samba/tests/dns.py @@ -846,6 +846,28 @@ class TestComplexQueries(DNSTest): self.assertEquals(response.answers[1].name, name2) self.assertEquals(response.answers[1].rdata, name0) + def test_cname_loop(self): + cname1 = "cnamelooptestrec." + self.get_dns_domain() + cname2 = "cnamelooptestrec2." + self.get_dns_domain() + cname3 = "cnamelooptestrec3." + self.get_dns_domain() + self.make_dns_update(cname1, cname2, dnsp.DNS_TYPE_CNAME) + self.make_dns_update(cname2, cname3, dnsp.DNS_TYPE_CNAME) + self.make_dns_update(cname3, cname1, dnsp.DNS_TYPE_CNAME) + + p = self.make_name_packet(dns.DNS_OPCODE_QUERY) + questions = [] + + q = self.make_name_question(cname1, + dns.DNS_QTYPE_A, + dns.DNS_QCLASS_IN) + questions.append(q) + self.finish_name_packet(p, questions) + + (response, response_packet) =\ + self.dns_transaction_udp(p, host=self.server_ip) + + max_recursion_depth = 20 + self.assertEquals(len(response.answers), max_recursion_depth) class TestInvalidQueries(DNSTest): def setUp(self): @@ -1481,6 +1503,50 @@ class TestRPCRoundtrip(DNSTest): def tearDown(self): super(TestRPCRoundtrip, self).tearDown() + def rpc_update(self, fqn=None, data=None, wType=None, delete=False): + fqn = fqn or ("rpctestrec." + self.get_dns_domain()) + + rec = data_to_dns_record(wType, data) + add_rec_buf = dnsserver.DNS_RPC_RECORD_BUF() + add_rec_buf.rec = rec + + add_arg = add_rec_buf + del_arg = None + if delete: + add_arg = None + del_arg = add_rec_buf + + self.rpc_conn.DnssrvUpdateRecord2( + dnsserver.DNS_CLIENT_VERSION_LONGHORN, + 0, + self.server_ip, + self.get_dns_domain(), + fqn, + add_arg, + del_arg) + + def test_rpc_self_referencing_cname(self): + cname = "cnametest2_unqual_rec_loop" + cname_fqn = "%s.%s" % (cname, self.get_dns_domain()) + + try: + self.rpc_update(fqn=cname, data=cname_fqn, + wType=dnsp.DNS_TYPE_CNAME, delete=True) + except WERRORError as e: + if e.args[0] != werror.WERR_DNS_ERROR_RECORD_DOES_NOT_EXIST: + self.fail("RPC DNS gaven wrong error on pre-test cleanup " + "for self referencing CNAME: %s" % e.args[0]) + + try: + self.rpc_update(fqn=cname, wType=dnsp.DNS_TYPE_CNAME, data=cname_fqn) + except WERRORError as e: + if e.args[0] != werror.WERR_DNS_ERROR_CNAME_LOOP: + self.fail("RPC DNS gaven wrong error on insertion of " + "self referencing CNAME: %s" % e.args[0]) + return + + self.fail("RPC DNS allowed insertion of self referencing CNAME") + def test_update_add_txt_rpc_to_dns(self): prefix, txt = 'rpctextrec', ['"This is a test"'] diff --git a/selftest/knownfail.d/dns b/selftest/knownfail.d/dns index ca18b4334c1..39b337ed6bb 100644 --- a/selftest/knownfail.d/dns +++ b/selftest/knownfail.d/dns @@ -13,6 +13,7 @@ samba.tests.dns.__main__.TestRPCRoundtrip.test_update_add_null_char_txt_record\( samba.tests.dns.__main__.TestRPCRoundtrip.test_update_add_null_padded_txt_record\(rodc:local\) samba.tests.dns.__main__.TestRPCRoundtrip.test_update_add_slash_txt_record\(rodc:local\) samba.tests.dns.__main__.TestRPCRoundtrip.test_update_add_two_txt_records\(rodc:local\) +samba.tests.dns.__main__.TestRPCRoundtrip.test_rpc_self_referencing_cname\(rodc:local\) samba.tests.dns.__main__.TestDNSUpdates.test_delete_record\(vampire_dc:local\) samba.tests.dns.__main__.TestDNSUpdates.test_readd_record\(vampire_dc:local\) samba.tests.dns.__main__.TestDNSUpdates.test_update_add_mx_record\(vampire_dc:local\) @@ -70,3 +71,9 @@ samba.tests.dns.__main__.TestSimpleQueries.test_qtype_all_query\(rodc:local\) # The SOA override should not pass against the RODC, it must not overstamp samba.tests.dns.__main__.TestSimpleQueries.test_one_SOA_query\(rodc:local\) + +# +# rodc and vampire_dc require signed dns updates, so the test setup +# fails, but the test does run on fl2003dc +^samba.tests.dns.__main__.TestComplexQueries.test_cname_loop\(rodc:local\) +^samba.tests.dns.__main__.TestComplexQueries.test_cname_loop\(vampire_dc:local\) diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c index 923f7233eb9..65faeac3b6a 100644 --- a/source4/dns_server/dns_query.c +++ b/source4/dns_server/dns_query.c @@ -40,6 +40,7 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_DNS +#define MAX_Q_RECURSION_DEPTH 20 struct forwarder_string { const char *forwarder; @@ -419,6 +420,11 @@ static struct tevent_req *handle_dnsrpcrec_send( state->answers = answers; state->nsrecs = nsrecs; + if (talloc_array_length(*answers) >= MAX_Q_RECURSION_DEPTH) { + tevent_req_done(req); + return tevent_req_post(req, ev); + } + resolve_cname = ((rec->wType == DNS_TYPE_CNAME) && ((question->question_type == DNS_QTYPE_A) || (question->question_type == DNS_QTYPE_AAAA))); diff --git a/source4/dns_server/dnsserver_common.c b/source4/dns_server/dnsserver_common.c index 1a032b4aa9f..656d7ca6bff 100644 --- a/source4/dns_server/dnsserver_common.c +++ b/source4/dns_server/dnsserver_common.c @@ -742,6 +742,94 @@ bool dns_name_is_static(struct dnsp_DnssrvRpcRecord *records, return false; } +/* + * Helper function to copy a dnsp_ip4_array struct to an IP4_ARRAY struct. + * The new structure and it's data are allocated on the supplied talloc context + */ +static struct IP4_ARRAY *copy_ip4_array(TALLOC_CTX *ctx, + const char *name, + struct dnsp_ip4_array array) +{ + + struct IP4_ARRAY *ip4_array = NULL; + unsigned int i; + + ip4_array = talloc_zero(ctx, struct IP4_ARRAY); + if (ip4_array == NULL) { + DBG_ERR("Out of memory copying property [%s]\n", name); + return NULL; + } + + ip4_array->AddrCount = array.addrCount; + if (ip4_array->AddrCount == 0) { + return ip4_array; + } + + ip4_array->AddrArray = + talloc_array(ip4_array, uint32_t, ip4_array->AddrCount); + if (ip4_array->AddrArray == NULL) { + TALLOC_FREE(ip4_array); + DBG_ERR("Out of memory copying property [%s] values\n", name); + return NULL; + } + + for (i = 0; i < ip4_array->AddrCount; i++) { + ip4_array->AddrArray[i] = array.addr[i]; + } + + return ip4_array; +} + +bool dns_zoneinfo_load_zone_property(struct dnsserver_zoneinfo *zoneinfo, + struct dnsp_DnsProperty *prop) +{ + switch (prop->id) { + case DSPROPERTY_ZONE_TYPE: + zoneinfo->dwZoneType = prop->data.zone_type; + break; + case DSPROPERTY_ZONE_ALLOW_UPDATE: + zoneinfo->fAllowUpdate = prop->data.allow_update_flag; + break; + case DSPROPERTY_ZONE_NOREFRESH_INTERVAL: + zoneinfo->dwNoRefreshInterval = prop->data.norefresh_hours; + break; + case DSPROPERTY_ZONE_REFRESH_INTERVAL: + zoneinfo->dwRefreshInterval = prop->data.refresh_hours; + break; + case DSPROPERTY_ZONE_AGING_STATE: + zoneinfo->fAging = prop->data.aging_enabled; + break; + case DSPROPERTY_ZONE_SCAVENGING_SERVERS: + zoneinfo->aipScavengeServers = copy_ip4_array( + zoneinfo, "ZONE_SCAVENGING_SERVERS", prop->data.servers); + if (zoneinfo->aipScavengeServers == NULL) { + return false; + } + break; + case DSPROPERTY_ZONE_AGING_ENABLED_TIME: + zoneinfo->dwAvailForScavengeTime = + prop->data.next_scavenging_cycle_hours; + break; + case DSPROPERTY_ZONE_MASTER_SERVERS: + zoneinfo->aipLocalMasters = copy_ip4_array( + zoneinfo, "ZONE_MASTER_SERVERS", prop->data.master_servers); + if (zoneinfo->aipLocalMasters == NULL) { + return false; + } + break; + case DSPROPERTY_ZONE_EMPTY: + case DSPROPERTY_ZONE_SECURE_TIME: + case DSPROPERTY_ZONE_DELETED_FROM_HOSTNAME: + case DSPROPERTY_ZONE_AUTO_NS_SERVERS: + case DSPROPERTY_ZONE_DCPROMO_CONVERT: + case DSPROPERTY_ZONE_SCAVENGING_SERVERS_DA: + case DSPROPERTY_ZONE_MASTER_SERVERS_DA: + case DSPROPERTY_ZONE_NS_SERVERS_DA: + case DSPROPERTY_ZONE_NODE_DBFLAGS: + break; + } + return true; +} WERROR dns_get_zone_properties(struct ldb_context *samdb, TALLOC_CTX *mem_ctx, struct ldb_dn *zone_dn, @@ -774,6 +862,7 @@ WERROR dns_get_zone_properties(struct ldb_context *samdb, } for (i = 0; i < element->num_values; i++) { + bool valid_property; prop = talloc_zero(mem_ctx, struct dnsp_DnsProperty); if (prop == NULL) { return WERR_NOT_ENOUGH_MEMORY; @@ -787,42 +876,10 @@ WERROR dns_get_zone_properties(struct ldb_context *samdb, return DNS_ERR(SERVER_FAILURE); } - switch (prop->id) { - case DSPROPERTY_ZONE_AGING_STATE: - zoneinfo->fAging = prop->data.aging_enabled; - break; - case DSPROPERTY_ZONE_NOREFRESH_INTERVAL: - zoneinfo->dwNoRefreshInterval = - prop->data.norefresh_hours; - break; - case DSPROPERTY_ZONE_REFRESH_INTERVAL: - zoneinfo->dwRefreshInterval = prop->data.refresh_hours; - break; - case DSPROPERTY_ZONE_ALLOW_UPDATE: - zoneinfo->fAllowUpdate = prop->data.allow_update_flag; - break; - case DSPROPERTY_ZONE_AGING_ENABLED_TIME: - zoneinfo->dwAvailForScavengeTime = - prop->data.next_scavenging_cycle_hours; - break; - case DSPROPERTY_ZONE_SCAVENGING_SERVERS: - zoneinfo->aipScavengeServers->AddrCount = - prop->data.servers.addrCount; - zoneinfo->aipScavengeServers->AddrArray = - prop->data.servers.addr; - break; - case DSPROPERTY_ZONE_EMPTY: - case DSPROPERTY_ZONE_TYPE: - case DSPROPERTY_ZONE_SECURE_TIME: - case DSPROPERTY_ZONE_DELETED_FROM_HOSTNAME: - case DSPROPERTY_ZONE_MASTER_SERVERS: - case DSPROPERTY_ZONE_AUTO_NS_SERVERS: - case DSPROPERTY_ZONE_DCPROMO_CONVERT: - case DSPROPERTY_ZONE_SCAVENGING_SERVERS_DA: - case DSPROPERTY_ZONE_MASTER_SERVERS_DA: - case DSPROPERTY_ZONE_NS_SERVERS_DA: - case DSPROPERTY_ZONE_NODE_DBFLAGS: - break; + valid_property = + dns_zoneinfo_load_zone_property(zoneinfo, prop); + if (!valid_property) { + return DNS_ERR(SERVER_FAILURE); } } diff --git a/source4/dns_server/dnsserver_common.h b/source4/dns_server/dnsserver_common.h index 380f61b8dbc..60ecde4fa91 100644 --- a/source4/dns_server/dnsserver_common.h +++ b/source4/dns_server/dnsserver_common.h @@ -87,4 +87,7 @@ NTSTATUS dns_common_zones(struct ldb_context *samdb, TALLOC_CTX *mem_ctx, struct ldb_dn *base_dn, struct dns_server_zone **zones_ret); + +bool dns_zoneinfo_load_zone_property(struct dnsserver_zoneinfo *zoneinfo, + struct dnsp_DnsProperty *prop); #endif /* __DNSSERVER_COMMON_H__ */ diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index 7ce5168c6c7..dd9a5dcadf5 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -56,6 +56,9 @@ */ #include "dsdb/samdb/ldb_modules/util.h" +/* default is 30 minutes: -1e7 * 30 * 60 */ +#define DEFAULT_OBSERVATION_WINDOW -18000000000 + /* search the sam for the specified attributes in a specific domain, filter on objectSid being in domain_sid. @@ -5368,9 +5371,9 @@ int samdb_result_effective_badPwdCount(struct ldb_context *sam_ldb, if (res != NULL) { lockOutObservationWindow = - ldb_msg_find_attr_as_int(res->msgs[0], - "msDS-LockoutObservationWindow", - 0); + ldb_msg_find_attr_as_int64(res->msgs[0], + "msDS-LockoutObservationWindow", + DEFAULT_OBSERVATION_WINDOW); talloc_free(res); } else { @@ -5407,12 +5410,13 @@ static int64_t get_lockout_observation_window(struct ldb_message *domain_msg, struct ldb_message *pso_msg) { if (pso_msg != NULL) { - return ldb_msg_find_attr_as_int(pso_msg, - "msDS-LockoutObservationWindow", - 0); + return ldb_msg_find_attr_as_int64(pso_msg, + "msDS-LockoutObservationWindow", + DEFAULT_OBSERVATION_WINDOW); } else { - return ldb_msg_find_attr_as_int(domain_msg, - "lockOutObservationWindow", 0); + return ldb_msg_find_attr_as_int64(domain_msg, + "lockOutObservationWindow", + DEFAULT_OBSERVATION_WINDOW); } } diff --git a/source4/dsdb/tests/python/password_lockout.py b/source4/dsdb/tests/python/password_lockout.py index 14cf00adb90..bc0613b71b1 100755 --- a/source4/dsdb/tests/python/password_lockout.py +++ b/source4/dsdb/tests/python/password_lockout.py @@ -1371,6 +1371,36 @@ userPassword: """ + userpass + """ self._testing_add_user(lockout4ntlm_creds, lockOutObservationWindow=self.lockout_observation_window) +class PasswordTestsWithDefaults(PasswordTests): + def setUp(self): + # The tests in this class do not sleep, so we can use the default + # timeout windows here + self.account_lockout_duration = 30 * 60 + self.lockout_observation_window = 30 * 60 + super(PasswordTestsWithDefaults, self).setUp() + + # sanity-check that user lockout works with the default settings (we just + # check the user is locked out - we don't wait for the lockout to expire) + def test_login_lockout_krb5(self): + self._test_login_lockout(self.lockout1krb5_creds, + wait_lockout_duration=False) + + def test_login_lockout_ntlm(self): + self._test_login_lockout(self.lockout1ntlm_creds, + wait_lockout_duration=False) + + # Repeat the login lockout tests using PSOs + def test_pso_login_lockout_krb5(self): + """Check the PSO lockout settings get applied to the user correctly""" + self.use_pso_lockout_settings(self.lockout1krb5_creds) + self._test_login_lockout(self.lockout1krb5_creds, + wait_lockout_duration=False) + + def test_pso_login_lockout_ntlm(self): + """Check the PSO lockout settings get applied to the user correctly""" + self.use_pso_lockout_settings(self.lockout1ntlm_creds) + self._test_login_lockout(self.lockout1ntlm_creds, + wait_lockout_duration=False) host_url = "ldap://%s" % host diff --git a/source4/dsdb/tests/python/password_lockout_base.py b/source4/dsdb/tests/python/password_lockout_base.py index c2664e9adba..24b066c188d 100644 --- a/source4/dsdb/tests/python/password_lockout_base.py +++ b/source4/dsdb/tests/python/password_lockout_base.py @@ -364,7 +364,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """ def tearDown(self): super(BasePasswordTestCase, self).tearDown() - def _test_login_lockout(self, creds): + def _test_login_lockout(self, creds, wait_lockout_duration=True): username = creds.get_username() userpass = creds.get_password() userdn = "cn=%s,cn=users,%s" % (username, self.base_dn) @@ -561,6 +561,10 @@ lockoutThreshold: """ + str(lockoutThreshold) + """ userAccountControl=dsdb.UF_NORMAL_ACCOUNT, msDSUserAccountControlComputed=dsdb.UF_LOCKOUT) + # if we're just checking the user gets locked out, we can stop here + if not wait_lockout_duration: + return + # wait for the lockout to end time.sleep(self.account_lockout_duration + 1) print(self.account_lockout_duration + 1) diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c index acd24ec0c83..969f4f6b556 100644 --- a/source4/kdc/db-glue.c +++ b/source4/kdc/db-glue.c @@ -2610,10 +2610,10 @@ samba_kdc_check_pkinit_ms_upn_match(krb5_context context, * comparison */ if (!(orig_sid && target_sid && dom_sid_equal(orig_sid, target_sid))) { talloc_free(mem_ctx); -#ifdef KRB5_KDC_ERR_CLIENT_NAME_MISMATCH /* Heimdal */ - return KRB5_KDC_ERR_CLIENT_NAME_MISMATCH; -#elif defined(KRB5KDC_ERR_CLIENT_NAME_MISMATCH) /* MIT */ +#if defined(KRB5KDC_ERR_CLIENT_NAME_MISMATCH) /* MIT */ return KRB5KDC_ERR_CLIENT_NAME_MISMATCH; +#else /* Heimdal (where this is an enum) */ + return KRB5_KDC_ERR_CLIENT_NAME_MISMATCH; #endif } diff --git a/source4/kdc/mit-kdb/kdb_samba_policies.c b/source4/kdc/mit-kdb/kdb_samba_policies.c index de5813bde2f..fc80329f221 100644 --- a/source4/kdc/mit-kdb/kdb_samba_policies.c +++ b/source4/kdc/mit-kdb/kdb_samba_policies.c @@ -81,6 +81,7 @@ krb5_error_code kdb_samba_db_check_policy_as(krb5_context context, char *netbios_name = NULL; char *realm = NULL; bool password_change = false; + krb5_const_principal client_princ; DATA_BLOB int_data = { NULL, 0 }; krb5_data d; krb5_pa_data **e_data; @@ -90,7 +91,10 @@ krb5_error_code kdb_samba_db_check_policy_as(krb5_context context, return KRB5_KDB_DBNOTINITED; } - if (ks_is_kadmin(context, kdcreq->client)) { + /* Prefer canonicalised name from client entry */ + client_princ = client ? client->princ : kdcreq->client; + + if (client_princ == NULL || ks_is_kadmin(context, client_princ)) { return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; } @@ -111,7 +115,7 @@ krb5_error_code kdb_samba_db_check_policy_as(krb5_context context, goto done; } - code = krb5_unparse_name(context, kdcreq->client, &client_name); + code = krb5_unparse_name(context, client_princ, &client_name); if (code) { goto done; } @@ -457,6 +461,14 @@ void kdb_samba_db_audit_as_req(krb5_context context, krb5_timestamp authtime, krb5_error_code error_code) { + /* + * FIXME: This segfaulted with a FAST test + * FIND_FAST: <unknown client> for <unknown server>, Unknown FAST armor type 0 + */ + if (client == NULL) { + return; + } + samba_bad_password_count(client, error_code); /* TODO: perform proper audit logging for addresses */ @@ -469,6 +481,14 @@ void kdb_samba_db_audit_as_req(krb5_context context, krb5_timestamp authtime, krb5_error_code error_code) { + /* -- Samba Shared Repository