Skip to content
Commits on Source (20)
samba (2:4.9.2+dfsg-2) unstable; urgency=high
* New upstream security release
- CVE-2018-14629 Unprivileged adding of CNAME record causing loop in AD
Internal DNS server
- CVE-2018-16841 Double-free in Samba AD DC KDC with PKINIT
- CVE-2018-16851 NULL pointer de-reference in Samba AD DC LDAP server
- CVE-2018-16852 NULL pointer de-reference in Samba AD DC DNS servers
- because of CVE-2018-16853 (Samba AD DC S4U2Self Crash in experimental
MIT Kerberos configuration (unsupported)), mark the MIT Kerberos build of
the Samba AD DC as experimental (not used in Debian package)
- CVE-2018-16857 Bad password count in AD DC not always effective
* Prepend 1.5.1+really to ldb version
-- Mathieu Parent <sathieu@debian.org> Sat, 24 Nov 2018 23:21:27 +0100
samba (2:4.9.2+dfsg-1) unstable; urgency=medium
* New upstream release
......
......@@ -33,7 +33,7 @@ Build-Depends: bison,
libgpgme11-dev,
libjansson-dev,
libldap2-dev,
libldb-dev (>= 2:1.4.3),
libldb-dev (>= 2:1.5.1+really1.4.3),
libncurses5-dev,
libpam0g-dev,
libparse-yapp-perl,
......@@ -49,8 +49,8 @@ Build-Depends: bison,
po-debconf,
python-all-dev (>= 2.6.6-3),
python-dnspython,
python-ldb (>= 2:1.4.3),
python-ldb-dev (>= 2:1.4.3),
python-ldb (>= 2:1.5.1+really1.4.3),
python-ldb-dev (>= 2:1.5.1+really1.4.3),
python-talloc-dev (>= 2.1.14~),
python-tdb (>= 1.3.16~),
python-testtools,
......
From 63afa9e07ccc0b6f7ae095de2b566e81b5be69b7 Mon Sep 17 00:00:00 2001
From: Aaron Haslett <aaronhaslett@catalyst.net.nz>
Date: Tue, 23 Oct 2018 17:25:51 +1300
Subject: [PATCH] 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 <aaronhaslett@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
---
python/samba/tests/dns.py | 22 ++++++++++++++++++++++
selftest/knownfail.d/dns | 6 ++++++
source4/dns_server/dns_query.c | 6 ++++++
3 files changed, 34 insertions(+)
diff --git a/python/samba/tests/dns.py b/python/samba/tests/dns.py
index 6771e3bb8c4..3e6306e2be8 100644
--- a/python/samba/tests/dns.py
+++ b/python/samba/tests/dns.py
@@ -844,6 +844,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):
diff --git a/selftest/knownfail.d/dns b/selftest/knownfail.d/dns
index a5176654cc2..a248432aafa 100644
--- a/selftest/knownfail.d/dns
+++ b/selftest/knownfail.d/dns
@@ -69,3 +69,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)));
--
2.11.0
From 55d782d3b63f04124efa99c56a53aa57efa1a4b7 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Tue, 23 Oct 2018 17:33:46 +1300
Subject: [PATCH 1/2] 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 <abartlet@samba.org>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
---
source4/kdc/db-glue.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
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
}
--
2.11.0
From 574caed5a3e2e600696f2b2f28743b08d1ff7e9c Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Wed, 24 Oct 2018 15:41:28 +1300
Subject: [PATCH 2/2] 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 <abartlet@samba.org>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
---
testprogs/blackbox/test_pkinit_heimdal.sh | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/testprogs/blackbox/test_pkinit_heimdal.sh b/testprogs/blackbox/test_pkinit_heimdal.sh
index 0a13aa293e7..0912e0dbfe8 100755
--- a/testprogs/blackbox/test_pkinit_heimdal.sh
+++ b/testprogs/blackbox/test_pkinit_heimdal.sh
@@ -75,10 +75,18 @@ testit "STEP1 kinit with pkinit (name specified) " $samba4kinit $enctype --reque
testit "STEP1 kinit renew ticket (name specified)" $samba4kinit --request-pac -R || failed=`expr $failed + 1`
test_smbclient "STEP1 Test login with kerberos ccache (name specified)" 'ls' "$unc" -k yes || failed=`expr $failed + 1`
+testit_expect_failure "STEP1 kinit with pkinit (wrong name specified) " $samba4kinit $enctype --request-pac --renewable $PKUSER not$USERNAME@$REALM || failed=`expr $failed + 1`
+
+testit_expect_failure "STEP1 kinit with pkinit (wrong name specified 2) " $samba4kinit $enctype --request-pac --renewable $PKUSER $SERVER@$REALM || failed=`expr $failed + 1`
+
testit "STEP1 kinit with pkinit (enterprise name specified)" $samba4kinit $enctype --request-pac --renewable $PKUSER --enterprise $USERNAME@$REALM || failed=`expr $failed + 1`
testit "STEP1 kinit renew ticket (enterprise name specified)" $samba4kinit --request-pac -R || failed=`expr $failed + 1`
test_smbclient "STEP1 Test login with kerberos ccache (enterprise name specified)" 'ls' "$unc" -k yes || failed=`expr $failed + 1`
+testit_expect_failure "STEP1 kinit with pkinit (wrong enterprise name specified) " $samba4kinit $enctype --request-pac --renewable $PKUSER --enterprise not$USERNAME@$REALM || failed=`expr $failed + 1`
+
+testit_expect_failure "STEP1 kinit with pkinit (wrong enterprise name specified 2) " $samba4kinit $enctype --request-pac --renewable $PKUSER --enterprise $SERVER$@$REALM || failed=`expr $failed + 1`
+
testit "STEP1 kinit with pkinit (enterprise name in cert)" $samba4kinit $enctype --request-pac --renewable $PKUSER --pk-enterprise || failed=`expr $failed + 1`
testit "STEP1 kinit renew ticket (enterprise name in cert)" $samba4kinit --request-pac -R || failed=`expr $failed + 1`
test_smbclient "STEP1 Test login with kerberos ccache (enterprise name in cert)" 'ls' "$unc" -k yes || failed=`expr $failed + 1`
--
2.11.0
From 90c319ec77d27b7d9eeae9e5c7a41407f00caf23 Mon Sep 17 00:00:00 2001
From: Garming Sam <garming@catalyst.net.nz>
Date: Mon, 5 Nov 2018 16:18:18 +1300
Subject: [PATCH] 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 <garming@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
---
source4/ldap_server/ldap_server.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c
index b5251e3623e..bc2f54bc146 100644
--- a/source4/ldap_server/ldap_server.c
+++ b/source4/ldap_server/ldap_server.c
@@ -690,13 +690,13 @@ static void ldapsrv_call_writev_start(struct ldapsrv_call *call)
ret = data_blob_append(call, &blob, b.data, b.length);
data_blob_free(&b);
- talloc_set_name_const(blob.data, "Outgoing, encoded LDAP packet");
-
if (!ret) {
ldapsrv_terminate_connection(conn, "data_blob_append failed");
return;
}
+ talloc_set_name_const(blob.data, "Outgoing, encoded LDAP packet");
+
DLIST_REMOVE(call->replies, call->replies);
}
--
2.11.0
This diff is collapsed.
This diff is collapsed.
From d3b52c8a1866a63a54497da9931fa606b77d089a Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet@samba.org>
Date: Tue, 6 Nov 2018 13:32:05 +1300
Subject: [PATCH] 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 <abartlet@samba.org>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
---
wscript | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/wscript b/wscript
index 542a60cf819..c9a4de4982b 100644
--- a/wscript
+++ b/wscript
@@ -52,6 +52,14 @@ def set_options(opt):
help='build Samba with system MIT Kerberos. ' +
'You may specify list of paths where Kerberos is installed (e.g. /usr/local /usr/kerberos) to search krb5-config',
action='callback', callback=system_mitkrb5_callback, dest='with_system_mitkrb5', default=False)
+
+ opt.add_option('--with-experimental-mit-ad-dc',
+ help='Enable the experimental MIT Kerberos-backed AD DC. ' +
+ 'Note that security patches are not issued for this configuration',
+ action='store_true',
+ dest='with_experimental_mit_ad_dc',
+ default=False)
+
opt.add_option('--with-system-mitkdc',
help=('Specify the path to the krb5kdc binary from MIT Kerberos'),
type="string",
@@ -165,7 +173,16 @@ def configure(conf):
conf.DEFINE('AD_DC_BUILD_IS_ENABLED', 1)
if Options.options.with_system_mitkrb5:
+ if not Options.options.with_experimental_mit_ad_dc and \
+ not Options.options.without_ad_dc:
+ raise Utils.WafError('The MIT Kerberos build of Samba as an AD DC ' +
+ 'is experimental. Therefore '
+ '--with-system-mitkrb5 requires either ' +
+ '--with-experimental-mit-ad-dc or ' +
+ '--without-ad-dc')
+
conf.PROCESS_SEPARATE_RULE('system_mitkrb5')
+
if not (Options.options.without_ad_dc or Options.options.with_system_mitkrb5):
conf.DEFINE('AD_DC_BUILD_IS_ENABLED', 1)
--
2.11.0
......@@ -7,3 +7,9 @@ VERSION.patch
add-so-version-to-private-libraries
heimdal-rfc3454.txt
nsswitch-Add-try_authtok-option-to-pam_winbind.patch
CVE-2018-14629-v4-9.patch
CVE-2018-16841-master.patch
CVE-2018-16851-master.patch
CVE-2018-16852-v4-9-v2.patch
mit-kdc-experimental-v4-7.patch
CVE-2018-16857-v4-9.patch
......@@ -20,7 +20,7 @@ LDB_NEXT_VERSION = $(shell python -c "x = '$(LDB_VERSION)'.split('.'); x[-1] = s
# samba ships ldb modules, which are specific to the ldb version, so we need a
# strict dependency on the upstream ldb version
# this also mean samba needs a rebuild when the upstream ldb version changes
LDB_DEPENDS = "libldb1 (<< $(LDB_EPOCH):$(LDB_NEXT_VERSION)~), libldb1 (>> $(LDB_EPOCH):$(LDB_VERSION)~)"
LDB_DEPENDS = "libldb1 (<< $(LDB_EPOCH):1.5.1+really$(LDB_NEXT_VERSION)~), libldb1 (>> $(LDB_EPOCH):1.5.1+really$(LDB_VERSION)~)"
export PYSHORT=$(shell pyversions -d)
export PYTHON=$(shell which $(PYSHORT))
export PYTHON_CONFIG="$(PYTHON)-config"
......
......@@ -844,6 +844,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):
......
......@@ -69,3 +69,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\)
......@@ -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)));
......
......@@ -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);
}
}
......
......@@ -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__ */
......@@ -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.
......@@ -5361,9 +5364,9 @@ int samdb_result_effective_badPwdCount(struct ldb_context *sam_ldb,
if (res != NULL) {
lockOutObservationWindow =
ldb_msg_find_attr_as_int(res->msgs[0],
ldb_msg_find_attr_as_int64(res->msgs[0],
"msDS-LockoutObservationWindow",
0);
DEFAULT_OBSERVATION_WINDOW);
talloc_free(res);
} else {
......@@ -5400,12 +5403,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,
return ldb_msg_find_attr_as_int64(pso_msg,
"msDS-LockoutObservationWindow",
0);
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);
}
}
......
......@@ -88,6 +88,42 @@ class PasswordTests(password_lockout_base.BasePasswordTestCase):
self.lockout2ntlm_ldb = self._readd_user(self.lockout2ntlm_creds,
lockOutObservationWindow=self.lockout_observation_window)
def use_pso_lockout_settings(self, creds):
# create a PSO with the lockout settings the test cases normally expect
#
# Some test cases sleep() for self.account_lockout_duration
pso = PasswordSettings("lockout-PSO", self.ldb, lockout_attempts=3,
lockout_duration=self.account_lockout_duration)
self.addCleanup(self.ldb.delete, pso.dn)
userdn = "cn=%s,cn=users,%s" % (creds.get_username(), self.base_dn)
pso.apply_to(userdn)
# update the global lockout settings to be wildly different to what
# the test cases normally expect
self.update_lockout_settings(threshold=10, duration=600,
observation_window=600)
def _reset_samr(self, res):
# Now reset the lockout, by removing ACB_AUTOLOCK (which removes the lock, despite being a generated attribute)
samr_user = self._open_samr_user(res)
acb_info = self.samr.QueryUserInfo(samr_user, 16)
acb_info.acct_flags &= ~samr.ACB_AUTOLOCK
self.samr.SetUserInfo(samr_user, 16, acb_info)
self.samr.Close(samr_user)
class PasswordTestsWithoutSleep(PasswordTests):
def setUp(self):
# The tests in this class do not sleep, so we can have a
# longer window and not flap on slower hosts
self.account_lockout_duration = 30
self.lockout_observation_window = 30
super(PasswordTestsWithoutSleep, self).setUp()
def _reset_ldap_lockoutTime(self, res):
self.ldb.modify_ldif("""
dn: """ + str(res[0].dn) + """
......@@ -615,23 +651,130 @@ userPassword: thatsAcomplPASS2XYZ
"samr",
initial_lastlogon_relation='greater')
def use_pso_lockout_settings(self, creds):
# create a PSO with the lockout settings the test cases normally expect
pso = PasswordSettings("lockout-PSO", self.ldb, lockout_attempts=3,
lockout_duration=3)
self.addCleanup(self.ldb.delete, pso.dn)
def test_multiple_logon_krb5(self):
self._test_multiple_logon(self.lockout1krb5_creds)
# the test cases should sleep() for the PSO's lockoutDuration/obsvWindow
self.account_lockout_duration = 3
self.lockout_observation_window = 3
def test_multiple_logon_ntlm(self):
self._test_multiple_logon(self.lockout1ntlm_creds)
userdn = "cn=%s,cn=users,%s" % (creds.get_username(), self.base_dn)
pso.apply_to(userdn)
def _test_samr_password_change(self, creds, other_creds, lockout_threshold=3):
"""Tests user lockout by using bad password in SAMR password_change"""
# create a connection for SAMR using another user's credentials
lp = self.get_loadparm()
net = Net(other_creds, lp, server=self.host)
# work out the initial account values for this user
username = creds.get_username()
userdn = "cn=%s,cn=users,%s" % (username, self.base_dn)
res = self._check_account(userdn,
badPwdCount=0,
badPasswordTime=("greater", 0),
badPwdCountOnly=True)
badPasswordTime = int(res[0]["badPasswordTime"][0])
logonCount = int(res[0]["logonCount"][0])
lastLogon = int(res[0]["lastLogon"][0])
lastLogonTimestamp = int(res[0]["lastLogonTimestamp"][0])
# prove we can change the user password (using the correct password)
new_password = "thatsAcomplPASS2"
net.change_password(newpassword=new_password.encode('utf-8'),
username=username,
oldpassword=creds.get_password())
creds.set_password(new_password)
# try entering 'x' many bad passwords in a row to lock the user out
new_password = "thatsAcomplPASS3"
for i in range(lockout_threshold):
badPwdCount = i + 1
try:
print("Trying bad password, attempt #%u" % badPwdCount)
net.change_password(newpassword=new_password.encode('utf-8'),
username=creds.get_username(),
oldpassword="bad-password")
self.fail("Invalid SAMR change_password accepted")
except NTSTATUSError as e:
enum = ctypes.c_uint32(e[0]).value
self.assertEquals(enum, ntstatus.NT_STATUS_WRONG_PASSWORD)
# check the status of the account is updated after each bad attempt
account_flags = 0
lockoutTime = None
if badPwdCount >= lockout_threshold:
account_flags = dsdb.UF_LOCKOUT
lockoutTime = ("greater", badPasswordTime)
res = self._check_account(userdn,
badPwdCount=badPwdCount,
badPasswordTime=("greater", badPasswordTime),
logonCount=logonCount,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=lockoutTime,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=account_flags)
badPasswordTime = int(res[0]["badPasswordTime"][0])
# the user is now locked out
lockoutTime = int(res[0]["lockoutTime"][0])
# check the user remains locked out regardless of whether they use a
# good or a bad password now
for password in (creds.get_password(), "bad-password"):
try:
print("Trying password %s" % password)
net.change_password(newpassword=new_password.encode('utf-8'),
username=creds.get_username(),
oldpassword=password)
self.fail("Invalid SAMR change_password accepted")
except NTSTATUSError as e:
enum = ctypes.c_uint32(e[0]).value
self.assertEquals(enum, ntstatus.NT_STATUS_ACCOUNT_LOCKED_OUT)
res = self._check_account(userdn,
badPwdCount=lockout_threshold,
badPasswordTime=badPasswordTime,
logonCount=logonCount,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=lockoutTime,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
# reset the user account lockout
self._reset_samr(res)
# check bad password counts are reset
res = self._check_account(userdn,
badPwdCount=0,
badPasswordTime=badPasswordTime,
logonCount=logonCount,
lockoutTime=0,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
# check we can change the user password successfully now
net.change_password(newpassword=new_password.encode('utf-8'),
username=username,
oldpassword=creds.get_password())
creds.set_password(new_password)
def test_samr_change_password(self):
self._test_samr_password_change(self.lockout1ntlm_creds,
other_creds=self.lockout2ntlm_creds)
# same as above, but use a PSO to enforce the lockout
def test_pso_samr_change_password(self):
self.use_pso_lockout_settings(self.lockout1ntlm_creds)
self._test_samr_password_change(self.lockout1ntlm_creds,
other_creds=self.lockout2ntlm_creds)
# update the global lockout settings to be wildly different to what
# the test cases normally expect
self.update_lockout_settings(threshold=10, duration=600,
observation_window=600)
class PasswordTestsWithSleep(PasswordTests):
def setUp(self):
super(PasswordTestsWithSleep, self).setUp()
def _test_unicodePwd_lockout_with_clear_change(self, creds, other_ldb,
initial_logoncount_relation=None):
......@@ -1066,12 +1209,6 @@ unicodePwd:: """ + base64.b64encode(new_utf16).decode('utf8') + """
self.use_pso_lockout_settings(self.lockout1ntlm_creds)
self._test_login_lockout(self.lockout1ntlm_creds)
def test_multiple_logon_krb5(self):
self._test_multiple_logon(self.lockout1krb5_creds)
def test_multiple_logon_ntlm(self):
self._test_multiple_logon(self.lockout1ntlm_creds)
def _testing_add_user(self, creds, lockOutObservationWindow=0):
username = creds.get_username()
userpass = creds.get_password()
......@@ -1252,15 +1389,6 @@ userPassword: """ + userpass + """
msDSUserAccountControlComputed=0)
return ldb
def _reset_samr(self, res):
# Now reset the lockout, by removing ACB_AUTOLOCK (which removes the lock, despite being a generated attribute)
samr_user = self._open_samr_user(res)
acb_info = self.samr.QueryUserInfo(samr_user, 16)
acb_info.acct_flags &= ~samr.ACB_AUTOLOCK
self.samr.SetUserInfo(samr_user, 16, acb_info)
self.samr.Close(samr_user)
def test_lockout_observation_window(self):
lockout3krb5_creds = self.insta_creds(self.template_creds,
username="lockout3krb5",
......@@ -1287,119 +1415,36 @@ userPassword: """ + userpass + """
self._testing_add_user(lockout4ntlm_creds,
lockOutObservationWindow=self.lockout_observation_window)
def _test_samr_password_change(self, creds, other_creds, lockout_threshold=3):
"""Tests user lockout by using bad password in SAMR password_change"""
# create a connection for SAMR using another user's credentials
lp = self.get_loadparm()
net = Net(other_creds, lp, server=self.host)
# work out the initial account values for this user
username = creds.get_username()
userdn = "cn=%s,cn=users,%s" % (username, self.base_dn)
res = self._check_account(userdn,
badPwdCount=0,
badPasswordTime=("greater", 0),
badPwdCountOnly=True)
badPasswordTime = int(res[0]["badPasswordTime"][0])
logonCount = int(res[0]["logonCount"][0])
lastLogon = int(res[0]["lastLogon"][0])
lastLogonTimestamp = int(res[0]["lastLogonTimestamp"][0])
# prove we can change the user password (using the correct password)
new_password = "thatsAcomplPASS2"
net.change_password(newpassword=new_password.encode('utf-8'),
username=username,
oldpassword=creds.get_password())
creds.set_password(new_password)
# try entering 'x' many bad passwords in a row to lock the user out
new_password = "thatsAcomplPASS3"
for i in range(lockout_threshold):
badPwdCount = i + 1
try:
print("Trying bad password, attempt #%u" % badPwdCount)
net.change_password(newpassword=new_password.encode('utf-8'),
username=creds.get_username(),
oldpassword="bad-password")
self.fail("Invalid SAMR change_password accepted")
except NTSTATUSError as e:
enum = ctypes.c_uint32(e[0]).value
self.assertEquals(enum, ntstatus.NT_STATUS_WRONG_PASSWORD)
# check the status of the account is updated after each bad attempt
account_flags = 0
lockoutTime = None
if badPwdCount >= lockout_threshold:
account_flags = dsdb.UF_LOCKOUT
lockoutTime = ("greater", badPasswordTime)
res = self._check_account(userdn,
badPwdCount=badPwdCount,
badPasswordTime=("greater", badPasswordTime),
logonCount=logonCount,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=lockoutTime,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=account_flags)
badPasswordTime = int(res[0]["badPasswordTime"][0])
# the user is now locked out
lockoutTime = int(res[0]["lockoutTime"][0])
# check the user remains locked out regardless of whether they use a
# good or a bad password now
for password in (creds.get_password(), "bad-password"):
try:
print("Trying password %s" % password)
net.change_password(newpassword=new_password.encode('utf-8'),
username=creds.get_username(),
oldpassword=password)
self.fail("Invalid SAMR change_password accepted")
except NTSTATUSError as e:
enum = ctypes.c_uint32(e[0]).value
self.assertEquals(enum, ntstatus.NT_STATUS_ACCOUNT_LOCKED_OUT)
res = self._check_account(userdn,
badPwdCount=lockout_threshold,
badPasswordTime=badPasswordTime,
logonCount=logonCount,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=lockoutTime,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
# reset the user account lockout
self._reset_samr(res)
# check bad password counts are reset
res = self._check_account(userdn,
badPwdCount=0,
badPasswordTime=badPasswordTime,
logonCount=logonCount,
lockoutTime=0,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
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)
# check we can change the user password successfully now
net.change_password(newpassword=new_password.encode('utf-8'),
username=username,
oldpassword=creds.get_password())
creds.set_password(new_password)
def test_login_lockout_ntlm(self):
self._test_login_lockout(self.lockout1ntlm_creds,
wait_lockout_duration=False)
def test_samr_change_password(self):
self._test_samr_password_change(self.lockout1ntlm_creds,
other_creds=self.lockout2ntlm_creds)
# 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)
# same as above, but use a PSO to enforce the lockout
def test_pso_samr_change_password(self):
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_samr_password_change(self.lockout1ntlm_creds,
other_creds=self.lockout2ntlm_creds)
self._test_login_lockout(self.lockout1ntlm_creds,
wait_lockout_duration=False)
host_url = "ldap://%s" % host
......
......@@ -93,8 +93,7 @@ class BasePasswordTestCase(PasswordTestCase):
logonCount=0,
lastLogon=0,
lastLogonTimestamp=("absent", None),
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
def _check_account(self, dn,
......@@ -323,7 +322,14 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
""")
self.base_dn = self.ldb.domain_dn()
#
# Some test cases sleep() for self.account_lockout_duration
# so allow it to be controlled via the subclass
#
if not hasattr(self, 'account_lockout_duration'):
self.account_lockout_duration = 3
if not hasattr(self, 'lockout_observation_window'):
self.lockout_observation_window = 3
self.update_lockout_settings(threshold=3,
duration=self.account_lockout_duration,
......@@ -359,7 +365,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)
......@@ -382,8 +388,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
logonCount=(logoncount_relation, 0),
lastLogon=("greater", 0),
lastLogonTimestamp=("greater", 0),
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
logonCount = int(res[0]["logonCount"][0])
......@@ -413,8 +418,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
logonCount=logonCount,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0,
msg='lastlogontimestamp with wrong password')
badPasswordTime = int(res[0]["badPasswordTime"][0])
......@@ -432,8 +436,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
logonCount=(logoncount_relation, logonCount),
lastLogon=('greater', lastLogon),
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0,
msg='LLTimestamp is updated to lastlogon')
......@@ -453,8 +456,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
logonCount=logonCount,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
......@@ -475,8 +477,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
logonCount=logonCount,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
......@@ -500,8 +501,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=("greater", badPasswordTime),
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
badPasswordTime = int(res[0]["badPasswordTime"][0])
lockoutTime = int(res[0]["lockoutTime"][0])
......@@ -522,8 +522,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=lockoutTime,
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
# The wrong password
......@@ -542,8 +541,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=lockoutTime,
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=dsdb.UF_LOCKOUT)
# The correct password, but we are locked out
......@@ -562,10 +560,13 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=lockoutTime,
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
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)
......@@ -577,8 +578,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lockoutTime=lockoutTime,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
# The correct password after letting the timeout expire
......@@ -597,8 +597,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lastLogon=(lastlogon_relation, lastLogon),
lastLogonTimestamp=lastLogonTimestamp,
lockoutTime=0,
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0,
msg="lastLogon is way off")
......@@ -621,8 +620,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lockoutTime=0,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
......@@ -642,8 +640,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lockoutTime=0,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
......@@ -656,8 +653,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lockoutTime=0,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
# The wrong password
......@@ -676,8 +672,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lockoutTime=0,
lastLogon=lastLogon,
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
......@@ -692,8 +687,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
lockoutTime=0,
lastLogon=("greater", lastLogon),
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
def _test_multiple_logon(self, creds):
......@@ -726,8 +720,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
logonCount=(logoncount_relation, 0),
lastLogon=("greater", 0),
lastLogonTimestamp=("greater", 0),
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
badPasswordTime = int(res[0]["badPasswordTime"][0])
logonCount = int(res[0]["logonCount"][0])
......@@ -747,8 +740,7 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
logonCount=(logoncount_relation, logonCount),
lastLogon=(lastlogon_relation, lastLogon),
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0,
msg=("second logon, firstlogon was %s" %
firstLogon))
......@@ -766,6 +758,5 @@ lockoutThreshold: """ + str(lockoutThreshold) + """
logonCount=(logoncount_relation, logonCount),
lastLogon=(lastlogon_relation, lastLogon),
lastLogonTimestamp=lastLogonTimestamp,
userAccountControl=
dsdb.UF_NORMAL_ACCOUNT,
userAccountControl=dsdb.UF_NORMAL_ACCOUNT,
msDSUserAccountControlComputed=0)
......@@ -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
}
......
......@@ -690,13 +690,13 @@ static void ldapsrv_call_writev_start(struct ldapsrv_call *call)
ret = data_blob_append(call, &blob, b.data, b.length);
data_blob_free(&b);
talloc_set_name_const(blob.data, "Outgoing, encoded LDAP packet");
if (!ret) {
ldapsrv_terminate_connection(conn, "data_blob_append failed");
return;
}
talloc_set_name_const(blob.data, "Outgoing, encoded LDAP packet");
DLIST_REMOVE(call->replies, call->replies);
}
......