diff options
author | Andrew Bartlett <abartlet@samba.org> | 2018-07-30 14:00:18 +1200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2018-08-14 17:42:14 +0200 |
commit | 7ed470b1ad90174166ab561ab95751ffc6e240d9 (patch) | |
tree | 930f20b3335f3d51f8e94c6d65b977d9e5b7af91 | |
parent | 4a2880b670b261ca9fbc70b4665aa86ee2a2c07a (diff) | |
download | samba-7ed470b1ad90174166ab561ab95751ffc6e240d9.tar.gz |
cracknames: Fix DoS (NULL pointer de-ref) when not servicePrincipalName is set on a user
This regression was introduced in Samba 4.7 by bug 12842 and in
master git commit eb2e77970e41c1cb62c041877565e939c78ff52d.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13552
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
-rw-r--r-- | source4/dsdb/samdb/cracknames.c | 8 | ||||
-rw-r--r-- | source4/torture/drs/python/cracknames.py | 38 |
2 files changed, 45 insertions, 1 deletions
diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c index d8fe0975d15..1f8cad75579 100644 --- a/source4/dsdb/samdb/cracknames.c +++ b/source4/dsdb/samdb/cracknames.c @@ -1253,7 +1253,13 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ return WERR_OK; } case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL: { - if (result->elements[0].num_values > 1) { + struct ldb_message_element *el + = ldb_msg_find_element(result, + "servicePrincipalName"); + if (el == NULL) { + info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; + return WERR_OK; + } else if (el->num_values > 1) { info1->status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE; return WERR_OK; } diff --git a/source4/torture/drs/python/cracknames.py b/source4/torture/drs/python/cracknames.py index d8c8ae53d60..9bf90f9c997 100644 --- a/source4/torture/drs/python/cracknames.py +++ b/source4/torture/drs/python/cracknames.py @@ -149,6 +149,44 @@ class DrsCracknamesTestCase(drs_base.DrsBaseTestCase): self.ldb_dc1.delete(user) + def test_NoSPNAttribute(self): + """ + Verifies that, if we try and cracknames with the desired output + being an SPN, it returns + DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE. + """ + username = "Cracknames_no_SPN" + user = "cn=%s,%s" % (username, self.ou) + + user_record = { + "dn": user, + "objectclass": "user", + "sAMAccountName" : username, + "userPrincipalName" : "test4@test.com", + "displayName" : "test4"} + + self.ldb_dc1.add(user_record) + + (result, ctr) = self._do_cracknames(user, + drsuapi.DRSUAPI_DS_NAME_FORMAT_FQDN_1779, + drsuapi.DRSUAPI_DS_NAME_FORMAT_GUID) + + self.assertEquals(ctr.count, 1) + self.assertEquals(ctr.array[0].status, + drsuapi.DRSUAPI_DS_NAME_STATUS_OK) + + user_guid = ctr.array[0].result_name + + (result, ctr) = self._do_cracknames(user_guid, + drsuapi.DRSUAPI_DS_NAME_FORMAT_GUID, + drsuapi.DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL) + + self.assertEquals(ctr.count, 1) + self.assertEquals(ctr.array[0].status, + drsuapi.DRSUAPI_DS_NAME_STATUS_NOT_FOUND) + + self.ldb_dc1.delete(user) + def _do_cracknames(self, name, format_offered, format_desired): req = drsuapi.DsNameRequest1() names = drsuapi.DsNameString() |