The patch attached fixes issues reported in tickets #565 and 567.

Eugene
>From 31dbfd30116902cd4fdf6d848a942302cdd655f7 Mon Sep 17 00:00:00 2001
From: eindenbom <einden...@gmail.com>
Date: Wed, 21 Jul 2010 16:35:35 +0400
Subject: [PATCH] IPA access backend:
  - Fix removal of obsolete HBAC host, rules and service records from sysdb.
  - When no HBAC host record is found return PAM_PERM_DENIED instead of 
PAM_SYSTEM_ERROR.
 Tickets #565, 567

---
 src/providers/ipa/ipa_access.c |   77 +++++++++++++++++++++++++++++++++++-----
 1 files changed, 68 insertions(+), 9 deletions(-)

diff --git a/src/providers/ipa/ipa_access.c b/src/providers/ipa/ipa_access.c
index 42731f2..28bf8ca 100644
--- a/src/providers/ipa/ipa_access.c
+++ b/src/providers/ipa/ipa_access.c
@@ -326,7 +326,7 @@ static void hbac_services_get_done(struct tevent_req 
*subreq)
         return;
     }
 
-    if (state->services_reply_count == 0 || state->offline) {
+    if (state->offline) {
         tevent_req_done(req);
         return;
     }
@@ -687,23 +687,39 @@ static void hbac_get_host_memberof_done(struct tevent_req 
*subreq)
     hbac_get_host_memberof(req, false);
 }
 
+static bool hbac_is_known_host(struct hbac_host_info **hhi, const char *fqdn)
+{
+    if (!hhi || !fqdn) {
+        return false;
+    }
+
+    int i;
+    for (i = 0; hhi[i] != NULL; i++) {
+        if(strcmp(hhi[i]->fqdn, fqdn) == 0) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 static void hbac_get_host_memberof(struct tevent_req *req, bool offline)
 {
     struct hbac_get_host_info_state *state =
                     tevent_req_data(req, struct hbac_get_host_info_state);
     struct sysdb_ctx *sysdb;
+    struct sss_domain_info *domain;
     bool in_transaction = false;
     int ret;
     int i;
     struct ldb_message_element *el;
     struct hbac_host_info **hhi;
     char *object_name;
+    const char *fqdn_attrs[] = { IPA_HOST_FQDN, NULL };
+    const char *fqdn;
 
-    if (state->host_reply_count == 0) {
-        DEBUG(1, ("No hosts not found in IPA server.\n"));
-        ret = ENOENT;
-        goto fail;
-    }
+    size_t cached_count;
+    struct ldb_message **cached_entries = 0;
 
     hhi = talloc_array(state, struct hbac_host_info *, state->host_reply_count 
+ 1);
     if (hhi == NULL) {
@@ -714,6 +730,10 @@ static void hbac_get_host_memberof(struct tevent_req *req, 
bool offline)
     memset(hhi, 0,
            sizeof(struct hbac_host_info *) * (state->host_reply_count + 1));
 
+    if (state->host_reply_count == 0) {
+        DEBUG(1, ("No hosts not found in IPA server.\n"));
+    }
+
     for (i = 0; i < state->host_reply_count; i++) {
         hhi[i] = talloc_zero(hhi, struct hbac_host_info);
         if (hhi[i] == NULL) {
@@ -805,6 +825,7 @@ static void hbac_get_host_memberof(struct tevent_req *req, 
bool offline)
     }
 
     sysdb = hbac_ctx_sysdb(state->hbac_ctx);
+    domain = hbac_ctx_be(state->hbac_ctx)->domain;
 
     ret = sysdb_transaction_start(sysdb);
     if (ret != EOK) {
@@ -813,6 +834,41 @@ static void hbac_get_host_memberof(struct tevent_req *req, 
bool offline)
     }
     in_transaction = true;
 
+    ret = sysdb_search_custom(state, sysdb, domain,
+                              state->host_filter, HBAC_HOSTS_SUBDIR,
+                              fqdn_attrs,
+                              &cached_count,
+                              &cached_entries);
+
+    if (ret == ENOENT) {
+        cached_count = 0;
+        ret = EOK;
+    }
+
+    if (ret) {
+        DEBUG(1, ("sysdb_search_custom failed: [%d](%s)\n", ret, 
strerror(ret)));
+        goto fail;
+    }
+
+    for (i = 0; i < cached_count; i++) {
+        fqdn = ldb_msg_find_attr_as_string(cached_entries[i], IPA_HOST_FQDN, 
NULL);
+        if (!fqdn) {
+            DEBUG(1, ("missing FQDN in cached HBAC host record\n"));
+        } else if (hbac_is_known_host(hhi, fqdn)) {
+            continue;
+        } else {
+            DEBUG(9, ("deleting obsolete HBAC host record for %s\n", fqdn));
+        }
+
+        ret = sysdb_delete_recursive(state, sysdb, cached_entries[i]->dn, 
true);
+        if (ret) {
+            DEBUG(1, ("sysdb_delete_recursive failed: [%d](%s)\n", ret, 
strerror(ret)));
+            goto fail;
+        }
+    }
+
+    talloc_zfree(cached_entries);
+
     for (i = 0; i < state->host_reply_count; i++) {
 
         ret = sysdb_attrs_get_el(state->host_reply_list[i],
@@ -834,7 +890,7 @@ static void hbac_get_host_memberof(struct tevent_req *req, 
bool offline)
         DEBUG(9, ("Fqdn [%s].\n", object_name));
 
         ret = sysdb_store_custom(state, sysdb,
-                                 hbac_ctx_be(state->hbac_ctx)->domain,
+                                 domain,
                                  object_name,
                                  HBAC_HOSTS_SUBDIR,
                                  state->host_reply_list[i]);
@@ -856,6 +912,8 @@ static void hbac_get_host_memberof(struct tevent_req *req, 
bool offline)
     return;
 
 fail:
+    talloc_zfree(cached_entries);
+
     if (in_transaction) {
         sysdb_transaction_cancel(sysdb);
     }
@@ -1080,7 +1138,7 @@ static void hbac_rule_get(struct tevent_req *req, bool 
offline)
         DEBUG(9, ("OriginalDN: [%s].\n", (const char *)el->values[0].data));
     }
 
-    if (state->hbac_reply_count == 0 || offline) {
+    if (offline) {
         tevent_req_done(req);
         return;
     }
@@ -1886,7 +1944,8 @@ static void hbac_get_host_info_done(struct tevent_req 
*req)
     }
     if (local_hhi == NULL) {
         DEBUG(1, ("Missing host info for [%s].\n", ipa_hostname));
-        ret = EINVAL;
+        ret = EOK;
+        pam_status = PAM_PERM_DENIED;
         goto fail;
     }
     req = hbac_get_rules_send(hbac_ctx, hbac_ctx,
-- 
1.6.6.1

_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to