From 8aff845db8aa30cbd2f6a49f0195d35fc3f48209 Mon Sep 17 00:00:00 2001 From: Gary Lockyer Date: Thu, 23 Mar 2017 12:39:25 +1300 Subject: [PATCH] ldap_server: Log failures to find a valid user in the simple bind Signed-off-by: Andrew Bartlett --- python/samba/tests/auth_log.py | 80 +++++++++++++++++++++++++++++++++ source4/auth/ntlm/auth_simple.c | 35 ++++++++++----- 2 files changed, 103 insertions(+), 12 deletions(-) diff --git a/python/samba/tests/auth_log.py b/python/samba/tests/auth_log.py index abd2952fbb0..a2bddd488e8 100644 --- a/python/samba/tests/auth_log.py +++ b/python/samba/tests/auth_log.py @@ -32,6 +32,7 @@ import samba.tests.auth_log_base from samba.credentials import Credentials, DONT_USE_KERBEROS, MUST_USE_KERBEROS from samba import NTSTATUSError from subprocess import call +from ldb import LdbError class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): @@ -485,6 +486,85 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase): self.assertEquals("simple bind", msg["Authentication"]["authDescription"]) + def test_ldap_simple_bind_bad_password(self): + def isLastExpectedMessage( msg): + return (msg["type"] == "Authentication" and + msg["Authentication"]["serviceDescription"] == "LDAP" and + msg["Authentication"]["status"] + == "NT_STATUS_WRONG_PASSWORD" and + msg["Authentication"]["authDescription"] == "simple bind") + + creds = self.insta_creds(template=self.get_credentials()) + creds.set_password( "badPassword") + creds.set_bind_dn("%s\\%s" % (creds.get_domain(), + creds.get_username())) + + thrown = False + try: + self.samdb = SamDB(url="ldaps://%s" % os.environ["SERVER"], + lp = self.get_loadparm(), + credentials=creds) + except LdbError: + thrown = True + self.assertEquals( thrown, True) + + messages = self.waitForMessages( isLastExpectedMessage) + self.assertEquals(1, + len(messages), + "Did not receive the expected number of messages") + + + def test_ldap_simple_bind_bad_user(self): + def isLastExpectedMessage( msg): + return (msg["type"] == "Authentication" and + msg["Authentication"]["serviceDescription"] == "LDAP" and + msg["Authentication"]["status"] + == "NT_STATUS_NO_SUCH_USER" and + msg["Authentication"]["authDescription"] == "simple bind") + + creds = self.insta_creds(template=self.get_credentials()) + creds.set_bind_dn("%s\\%s" % (creds.get_domain(), "badUser")) + + thrown = False + try: + self.samdb = SamDB(url="ldaps://%s" % os.environ["SERVER"], + lp = self.get_loadparm(), + credentials=creds) + except LdbError: + thrown = True + self.assertEquals( thrown, True) + + messages = self.waitForMessages( isLastExpectedMessage) + self.assertEquals(1, + len(messages), + "Did not receive the expected number of messages") + + + def test_ldap_simple_bind_unparseable_user(self): + def isLastExpectedMessage( msg): + return (msg["type"] == "Authentication" and + msg["Authentication"]["serviceDescription"] == "LDAP" and + msg["Authentication"]["status"] + == "NT_STATUS_NO_SUCH_USER" and + msg["Authentication"]["authDescription"] == "simple bind") + + creds = self.insta_creds(template=self.get_credentials()) + creds.set_bind_dn("%s\\%s" % (creds.get_domain(), "abdcef")) + + thrown = False + try: + self.samdb = SamDB(url="ldaps://%s" % os.environ["SERVER"], + lp = self.get_loadparm(), + credentials=creds) + except LdbError: + thrown = True + self.assertEquals( thrown, True) + + messages = self.waitForMessages( isLastExpectedMessage) + self.assertEquals(1, + len(messages), + "Did not receive the expected number of messages") + def test_smb(self): def isLastExpectedMessage( msg): return (msg["type"] == "Authorization" and diff --git a/source4/auth/ntlm/auth_simple.c b/source4/auth/ntlm/auth_simple.c index 7e434d7d3c2..cd96113ca03 100644 --- a/source4/auth/ntlm/auth_simple.c +++ b/source4/auth/ntlm/auth_simple.c @@ -42,8 +42,8 @@ _PUBLIC_ NTSTATUS authenticate_ldap_simple_bind(TALLOC_CTX *mem_ctx, NTSTATUS nt_status; uint8_t authoritative = 0; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - const char *nt4_domain; - const char *nt4_username; + const char *nt4_domain = NULL; + const char *nt4_username = NULL; uint32_t flags = 0; const char *transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE; if (using_tls) { @@ -54,15 +54,7 @@ _PUBLIC_ NTSTATUS authenticate_ldap_simple_bind(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - nt_status = crack_auto_name_to_nt4_name(tmp_ctx, ev, lp_ctx, dn, - &nt4_domain, &nt4_username); - - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(tmp_ctx); - return nt_status; - } - - nt_status = auth_context_create(tmp_ctx, + nt_status = auth_context_create(tmp_ctx, ev, msg, lp_ctx, &auth_context); @@ -71,13 +63,19 @@ _PUBLIC_ NTSTATUS authenticate_ldap_simple_bind(TALLOC_CTX *mem_ctx, return nt_status; } + /* + * We check the error after building the user_info so we can + * log a failure to find the user correctly + */ + nt_status = crack_auto_name_to_nt4_name(tmp_ctx, ev, lp_ctx, dn, + &nt4_domain, &nt4_username); + user_info = talloc_zero(tmp_ctx, struct auth_usersupplied_info); if (!user_info) { talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } - user_info->mapped_state = true; user_info->client.account_name = dn; /* No client.domain_name, use account_name instead */ user_info->mapped.account_name = nt4_username; @@ -108,6 +106,19 @@ _PUBLIC_ NTSTATUS authenticate_ldap_simple_bind(TALLOC_CTX *mem_ctx, MSV1_0_CLEARTEXT_PASSWORD_ALLOWED | MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED; + /* This is a check for the crack names call above */ + if (!NT_STATUS_IS_OK(nt_status)) { + log_authentication_event(auth_context->msg_ctx, + auth_context->lp_ctx, + user_info, nt_status, + NULL, NULL, NULL, NULL); + talloc_free(tmp_ctx); + return nt_status; + } + + /* Now that we have checked if the crack names worked, set mapped_state */ + user_info->mapped_state = true; + nt_status = auth_check_password(auth_context, tmp_ctx, user_info, &user_info_dc, &authoritative); if (!NT_STATUS_IS_OK(nt_status)) { -- 2.34.1