sssd/0062-SDAP-Add-return-code-E...

120 lines
5.2 KiB
Diff

From 4f1dec56127c91c02908f40161cde42313ff93e4 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Fri, 5 Feb 2016 07:27:38 -0500
Subject: [PATCH 62/86] SDAP: Add return code ERR_ACCOUNT_LOCKED
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add code to distinquish state when account is locked in Active
Directory server.
Tested against Windows Server 2012
This patch is best effort only as decision whether account is actually
locked is based on parsing error message returned by AD. The format and
content of this error message might be subject of change in future
releases and also can be modified by AD administrators.
If account is locked bind operation is expected to return following
error message:
-----------------------------------------------------------------------
Invalid credentials(49), 80090308: LdapErr: DSID-0C0903C5, comment:
AcceptSecurityContext error, data 775, v23f0
-----------------------------------------------------------------------
Where sub string 'data 775' implies that account is locked
(ERROR_ACCOUNT_LOCKED_OUT) [1]. However the 80090308 (error code
0x80090308, SEC_E_INVALID_TOKEN) is the only guaranteed part of error
string [2].
Error message is described in further detail as [3]:
-----------------------------------------------------------------------
When the server fails an LDAP operation with an error, and the server
has sufficient resources to compute a string value for the errorMessage
field of the LDAPResult, it includes a string in the errorMessage field
of the LDAPResult (see [RFC2251] section 4.1.10). The string contains
further information about the error.
The first eight characters of the errorMessage string are a 32-bit
integer, expressed in hexadecimal. Where protocol specifies the extended
error code "<unrestricted>" there is no restriction on the value of the
32-bit integer. It is recommended that implementations use a Windows
error code for the 32-bit integer in this case in order to improve
usability of the directory for clients. Where protocol specifies an
extended error code which is a Windows error code, the 32-bit integer is
the specified Windows error code. Any data after the eighth character
is strictly informational and used only for debugging. Conformant
implementations need not put any value beyond the eighth character of
the errorMessage field.
-----------------------------------------------------------------------
[1] https://msdn.microsoft.com/en-us/library/windows/desktop/ms681386%28v=vs.85%29.aspx
[2] https://social.msdn.microsoft.com/Forums/en-US/e1d600c8-60b7-4ed0-94cb-20ddd6c1a1c6/msadts-user-locking-password-policies?forum=os_windowsprotocols
[3] MS-ADTS 3.1.1.3.1.9
https://msdn.microsoft.com/en-us/library/cc223253.aspx
Resolves:
https://fedorahosted.org/sssd/ticket/2839
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
Reviewed-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit ff275f4c0b8cc1a098dbd0c5f6d52d6a93cda597)
(cherry picked from commit 81cb4057920c6296b7f7e6b7c651fdb601ff0338)
---
src/providers/data_provider.h | 2 ++
src/providers/ldap/ldap_auth.c | 4 ++++
src/providers/ldap/sdap_async_connection.c | 6 ++++++
3 files changed, 12 insertions(+)
diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h
index 39051b90c3aad96f62dcbb86a20bcfd8c954879b..7332b677d19f70f4736e4d0b68d55cdd3c67a4af 100644
--- a/src/providers/data_provider.h
+++ b/src/providers/data_provider.h
@@ -182,6 +182,8 @@ struct pam_data {
bool offline_auth;
bool last_auth_saved;
int priv;
+ int account_locked;
+
#ifdef USE_KEYRING
key_serial_t key_serial;
#endif
diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c
index 217e80fd07abc41f2594d19397783683d44600cd..2fab92e5d22a4dae870c5e9dde7ef162fc36cbe2 100644
--- a/src/providers/ldap/ldap_auth.c
+++ b/src/providers/ldap/ldap_auth.c
@@ -1302,6 +1302,10 @@ static void sdap_pam_auth_done(struct tevent_req *req)
case ERR_PASSWORD_EXPIRED:
state->pd->pam_status = PAM_NEW_AUTHTOK_REQD;
break;
+ case ERR_ACCOUNT_LOCKED:
+ state->pd->account_locked = true;
+ state->pd->pam_status = PAM_PERM_DENIED;
+ break;
default:
state->pd->pam_status = PAM_SYSTEM_ERR;
dp_err = DP_ERR_FATAL;
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
index 85b7aaa5bf5acedf3511ffe6f8636be007d5a136..40256de99006815c97ee9390dfd2e997cf6fc072 100644
--- a/src/providers/ldap/sdap_async_connection.c
+++ b/src/providers/ldap/sdap_async_connection.c
@@ -754,6 +754,12 @@ static void simple_bind_done(struct sdap_op *op,
if (result == LDAP_SUCCESS) {
ret = EOK;
+ } else if (result == LDAP_INVALID_CREDENTIALS
+ && errmsg != NULL && strstr(errmsg, "data 775,") != NULL) {
+ /* Value 775 is described in
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/ms681386%28v=vs.85%29.aspx
+ * for more details please see commit message. */
+ ret = ERR_ACCOUNT_LOCKED;
} else {
ret = ERR_AUTH_FAILED;
}
--
2.5.0