From 25441e67d9a17f5d1b2b7e17ac7bbea160112ae9 Mon Sep 17 00:00:00 2001
From: Stanislav Levin <slev@altlinux.org>
Date: Tue, 26 Oct 2021 17:18:53 +0300
Subject: [PATCH] pam_sss: Allow offline authentication against
 non-ipa-desktopprofiles aware DC

IPA domain controller may not support desktop profiles since this
functionality is optional and distributed as the IPA plugin:

- in case of online authentication ipa_session detects such DC properly
  and returns PAM_SUCCESS for ENOENT, nothing is cached on sysdb (see
  ipa_deskprofile_get_config_send/ipa_deskprofile_get_config_done and
  ipa_pam_session_handler_done for details).

- in case of offline authentication ipa_session falls back to cache and
  receives ENOENT (since nothing was cached previously). But *any* error
  is treated as actual error and overall result is PAM_SESSION_ERR (see
  ipa_pam_session_handler_save_deskprofile_rules and
  ipa_pam_session_handler_done for details).  Note: actually, only
  deskprofile_get_cached_priority breaks PAM session since
  ipa_common_get_cached_rules successfully handles ENOENT.

- in either case sssd tries to send dbus notification to fleet
  commander even if there are no desktop profile rules to apply.

With this change ENOENT result of cache query is treated similarly
to ENOENT result of actual backend query (PAM_SUCCESS).

Resolves: https://github.com/SSSD/sssd/issues/5846
Signed-off-by: Stanislav Levin <slev@altlinux.org>
---
 src/providers/ipa/ipa_session.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/providers/ipa/ipa_session.c b/src/providers/ipa/ipa_session.c
index 267c978afe..cd43031cec 100644
--- a/src/providers/ipa/ipa_session.c
+++ b/src/providers/ipa/ipa_session.c
@@ -596,7 +596,11 @@ ipa_pam_session_handler_done(struct tevent_req *subreq)
                                                          state->uid,
                                                          state->gid);
 
-    state->pd->pam_status = (ret == EOK) ? PAM_SUCCESS : PAM_SESSION_ERR;
+    if (ret == EOK || ret == ENOENT) {
+        state->pd->pam_status = PAM_SUCCESS;
+    } else {
+        state->pd->pam_status = PAM_SESSION_ERR;
+    }
 
 done:
     /* TODO For backward compatibility we always return EOK to DP now. */
@@ -721,7 +725,10 @@ ipa_pam_session_handler_save_deskprofile_rules(
 
     /* Get Desktop Profile priority from sysdb */
     ret = deskprofile_get_cached_priority(be_ctx->domain, &priority);
-    if (ret != EOK) {
+    if (ret == ENOENT) {
+        DEBUG(SSSDBG_FUNC_DATA, "No Desktop Profile priority found in sysdb\n");
+        goto done;
+    } else if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE,
               "deskprofile_get_cached_priority() failed [%d]: %s\n",
               ret, sss_strerror(ret));
@@ -749,6 +756,13 @@ ipa_pam_session_handler_save_deskprofile_rules(
         goto done;
     }
 
+    /* nothing to do for FC */
+    if (!rule_count) {
+        DEBUG(SSSDBG_FUNC_DATA, "No Desktop Profile rules found in sysdb\n");
+        ret = ENOENT;
+        goto done;
+    }
+
     /* Create the user directory where the rules are going to be stored */
     ret = ipa_deskprofile_rules_create_user_dir(username, uid, gid);
     if (ret != EOK) {
