URL: https://github.com/freeipa/freeipa/pull/5734
Author: rcritten
 Title: #5734: Design doc to allow LDAP bind using the RADIUS auth type
Action: opened

PR body:
"""
The RADIUS auth type is only supported with Kerberos currently.
This design proposes a way to make it work with LDAP binds
as well without relying ok workarounds.

Signed-off-by: Rob Crittenden <rcrit...@redhat.com>
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/5734/head:pr5734
git checkout pr5734
From 2d465549a8821a56831aa3a289b10f6ae4eed3eb Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcrit...@redhat.com>
Date: Fri, 23 Apr 2021 16:46:40 -0400
Subject: [PATCH] Design doc to allow LDAP bind using the RADIUS auth type

The RADIUS auth type is only supported with Kerberos currently.
This design proposes a way to make it work with LDAP binds
as well without relying ok workarounds.

Signed-off-by: Rob Crittenden <rcrit...@redhat.com>
---
 doc/designs/index.rst               |   1 +
 doc/designs/ldap_pam_passthrough.md | 180 ++++++++++++++++++++++++++++
 2 files changed, 181 insertions(+)
 create mode 100644 doc/designs/ldap_pam_passthrough.md

diff --git a/doc/designs/index.rst b/doc/designs/index.rst
index cbec1096c36..f353efa1cd4 100644
--- a/doc/designs/index.rst
+++ b/doc/designs/index.rst
@@ -13,6 +13,7 @@ FreeIPA design documentation
    krb-ticket-policy.md
    extdom-plugin-protocol.md
    expiring-password-notification.md
+   ldap_pam_passthrough.md
    libpwquality.md
    membermanager.md
    hidden-replicas.md
diff --git a/doc/designs/ldap_pam_passthrough.md b/doc/designs/ldap_pam_passthrough.md
new file mode 100644
index 00000000000..9eb473cf99f
--- /dev/null
+++ b/doc/designs/ldap_pam_passthrough.md
@@ -0,0 +1,180 @@
+# LDAP PAM Passthrough support
+
+## Overview
+
+Many organizations have authentication mechanisms already in place.
+They may not want to have the LDAP server be the central repository for
+authentication. In 2005 389-ds provided a plugin that does authentication
+using a PAM service, https://directory.fedoraproject.org/docs/389ds/howto/howto-pam-pass-through.html
+
+In current IPA (<= 4.9.3) there is no support for configuring this plugin
+in order to outsource some authentication. The use-case for this is
+a 3rd party RADIUS service.
+
+In particular cases (enable otp and radius authentication indicators) it
+can work but its use is unsupported and configuration is tricky and
+confusing.
+
+The basic workflow is:
+
+ - IPA is installed
+
+ - The PAM pass-through plugin is enabled 389-ds to a PAM service that
+   relies on pam_sss.so.
+
+ - A RADIUS proxy configuration in IPA
+
+ - A RADIUS proxy link is configured for some users
+
+ - set default authentication method in IPA to 'radius, otp'
+
+ - No password or principal key is set for the user
+
+ - The user has no tokens set
+
+When that is done, the following should happen (hats off to Alexander
+for the bulk of this):
+
+ - on LDAP BIND with uid=user,cn=users,cn=accounts,$SUFFIX, the BIND
+   request will get processed. Inside the IPA password plugin
+   preop if both radius and otp are set and there are no tokens
+   the plugin will return 0, allowing further authentication to happen
+
+ - If the user DN is in the allowed configuration for PAM pass-through
+   then the PAM stack is loaded and processed
+
+ - pam_sss.so is called and attempts to perform a
+   password-based authentication for 'user' account
+
+ - since 'user' account matches IPA domain, it will be Kerberos
+   authentication against IPA KDC (running on the same host, as we are
+   authenticating on IPA master)
+
+ - IPA KDB driver in KDC will notice that the 'user@IPA' principal has
+   'radius' pre-authentication method configured with TL data
+   "otp\0[{\"indicators\": [\"radius\"]}]" meaning it should advertise
+   OTP pre-auth mechanism to the Kerberos client
+
+ - the client (SSSD) would notice availability of OTP pre-auth mechanism
+   and would use host principal's TGT as its FAST channel wrapper to
+   proceed with OTP pre-auth
+
+ - OTP pre-auth mechanism will talk between KDC and the client to ask
+   for additional details (OTP value) via prompting mechanism it has
+
+ - Kerberos client (SSSD) will return the OTP value and KDC then will
+   issue a RADIUS request "Accept-Request" to a RADIUS server configured
+   in the KDC configuration. The OTP value in this case is the
+   credentials the user provided.
+
+ - We don't have explicit configuration for KDC and a compiled-in
+   default is to talk to UNIX domain socket /run/krb5kdc/DEFAULT.socket
+
+ - systemd listens to this socket as configured by ipa-otpd.socket
+   definition and on any access to it would launch ipa-otpd daemon
+
+ - ipa-otpd will connect to LDAP (LDAP URI is passed as part of
+   ipa-otpd@.service definition from /etc/ipa/default.conf, so it'll be
+   LDAPI access). It will parse RADIUS packet and look up requested user
+   principal entry from LDAP.
+
+ - if user principal entry has 'radius' authentication indicator
+   configured (or it is default for IPA deployment) and there is a
+   RADIUS proxy link in the user entry (there is no default so it must
+   be set per user), it will send the same RADIUS packet to the RADIUS
+   server configured as a proxy link with the credentials provided by
+   KDC
+
+ - If the RADIUS server answers with 'Accept-Response' message with
+   'Access-Accept' code, ipa-otpd will respond to KDC with
+   'Accept-Response' message with 'Access-Accept' code. If not, it will
+   respond with 'Access-Reject' code in 'Accept-Response' message.
+
+ - For native OTP setup where user has 'otp' authentication indicator a
+   process is about the same: instead of sending a RADIUS proxy request,
+   ipa-otpd will bind to LDAP with a user DN and pass the credentials
+   provided by KDC
+
+So yes, this is a complicated path.
+
+And unsuppported.
+
+## It would be confusing to users
+
+Strictly speaking, a user can have this configuration and still have
+a userPassword and krbPrincipalKey set. But it doesn't do much in LDAP.
+Regardless of whether the provided password is valid or not authentication
+will proceed to the RADIUS server for the final word.
+
+This is similar behavior if a user tries a raw kinit without armor:
+there may be a password/key but it isn't used.
+
+This could lead to "I can't log in" calls and an admin resetting their
+password in IPA with no real effect.
+
+## Why is otp required?
+
+This scheme works because RADIUS isn't considered at all in the
+password plugin.
+
+In prepost.c::ipapwd_pre_bind_otp() the user is checked to see if
+they have OTP auth enabled. If they do then the tokens are examined
+and if there aren't any, the function exits in a way that allows
+subsequent authentication. This will then fall out and return a 0
+to 389-ds to allow PAM Passthrough to execute.
+
+If the user does not have OTP auth enabled then that code will be
+skipped and return a 1 because the auth_type is not
+OTP_CONFIG_AUTH_TYPE_PASSWORD.
+
+## Proposal on how it should work
+
+So passthrough authentication basically works by accident and by
+working around the lack of direct handling of RADIUS in the password
+plugin.
+
+This proposal may break existing installations.
+
+The flow:
+
+RADIUS will be evaluated first.
+
+If RADIUS authtype is set:
+  - require no userPassword and krbPrincipalKey
+  - require radius proxy setting
+
+If auth request comes in and these conditions are not set then
+LOG_FATAL() and end the authentication attempt.
+
+The logging is because the authentication is so opaque users won't
+know why it failed.
+
+It would be nice to check that PAM passthrough is enabled but there
+is is no way to validate the configuration so skip it.
+
+OTP is evaluated next
+
+Is OTP enabled? If yes then do existing token evaluation.
+
+If No then fall through.
+
+OTP checking is done in ipapwd_pre_bind_otp() which is called unless
+there is a sync request. Authenticaiton type handling needs to be
+better centralized here. There are two paths that can return different
+results as outlined before (assuming otpreq = False).
+
+1. User has otp auth type and has no tokens it will return 0.
+2. User does not have otp auth type it will only return 0 if the
+   user has OTP_CONFIG_AUTH_TYPE_PASSWORD.
+
+This loophole needs to be closed. Perhaps change to return false if
+auth type is OTP_CONFIG_AUTH_TYPE_NONE. This would likely be more
+future-proof.
+
+If OTP doesn't return an error then the password will be authenticted,
+if there is one.
+
+If the password plugin returns 0 then subsequent authentication
+will happen. For the case of RADIUS we need to enforce the requirements
+because with PAM passthrough enable it becomes a defacto default
+method.
_______________________________________________
FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org
To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/freeipa-devel@lists.fedorahosted.org
Do not reply to spam on the list, report it: 
https://pagure.io/fedora-infrastructure

Reply via email to