>From 644b45cfb7db4617059d3d4ad2ad1779d850db9c Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Sun, 3 Mar 2013 18:06:13 -0500
Subject: [PATCH] Convert sdap_access to new error codes

Also simplify sdap_access_send to avoid completely fake _send() routines.
---
 src/providers/ad/ad_access.c     |  32 +-
 src/providers/ipa/ipa_access.c   |  21 +-
 src/providers/ldap/ldap_access.c |  14 +-
 src/providers/ldap/sdap_access.c | 622 +++++++++++----------------------------
 src/providers/ldap/sdap_access.h |   3 +-
 src/util/util_errors.c           |   1 +
 src/util/util_errors.h           |   1 +
 7 files changed, 214 insertions(+), 480 deletions(-)

diff --git a/src/providers/ad/ad_access.c b/src/providers/ad/ad_access.c
index 0fa7d6d3afab4599a847bb0b319c31c09f52bda3..ef1775d7f7fac78fae5f13d3664ec49847d74864 100644
--- a/src/providers/ad/ad_access.c
+++ b/src/providers/ad/ad_access.c
@@ -69,30 +69,28 @@ static void
 ad_access_done(struct tevent_req *req)
 {
     errno_t ret;
-    int pam_status;
     struct be_req *breq =
             tevent_req_callback_data(req, struct be_req);
     struct pam_data *pd =
                     talloc_get_type(be_req_get_data(breq), struct pam_data);
 
-    ret = sdap_access_recv(req, &pam_status);
+    ret = sdap_access_recv(req);
     talloc_zfree(req);
-    if (ret != EOK) {
-        be_req_terminate(breq, DP_ERR_FATAL, PAM_SYSTEM_ERR, strerror(ret));
+    switch (ret) {
+    case EOK:
+        pd->pam_status = PAM_SUCCESS;
+        be_req_terminate(breq, DP_ERR_OK, PAM_SUCCESS, NULL);
         return;
-    }
-
-    pd->pam_status = pam_status;
-
-    if (pam_status == PAM_SUCCESS || pam_status == PAM_PERM_DENIED) {
-        /* We got the proper approval or denial */
-        be_req_terminate(breq, DP_ERR_OK, pam_status, NULL);
+    case ERR_ACCESS_DENIED:
+        /* We got the proper denial */
+        pd->pam_status = PAM_PERM_DENIED;
+        be_req_terminate(breq, DP_ERR_OK, PAM_PERM_DENIED, NULL);
+        return;
+    default:
+        /* Something went wrong */
+        pd->pam_status = PAM_SYSTEM_ERR;
+        be_req_terminate(breq, DP_ERR_FATAL,
+                         PAM_SYSTEM_ERR, sss_strerror(ret));
         return;
     }
-
-    /* Something went wrong */
-    pd->pam_status = PAM_SYSTEM_ERR;
-    be_req_terminate(breq, DP_ERR_FATAL, pam_status,
-                     pam_strerror(NULL, pam_status));
-    return;
 }
diff --git a/src/providers/ipa/ipa_access.c b/src/providers/ipa/ipa_access.c
index 430b2f7a9b349f695ac5165b04129c2473eec01c..c43974e3c208fdd89930e67ca4c7052108c09d7b 100644
--- a/src/providers/ipa/ipa_access.c
+++ b/src/providers/ipa/ipa_access.c
@@ -106,7 +106,6 @@ static void ipa_hbac_check(struct tevent_req *req)
     struct pam_data *pd;
     struct hbac_ctx *hbac_ctx = NULL;
     const char *deny_method;
-    int pam_status = PAM_SYSTEM_ERR;
     struct ipa_access_ctx *ipa_access_ctx;
     int ret;
 
@@ -114,33 +113,34 @@ static void ipa_hbac_check(struct tevent_req *req)
     be_ctx = be_req_get_be_ctx(be_req);
     pd = talloc_get_type(be_req_get_data(be_req), struct pam_data);
 
-    ret = sdap_access_recv(req, &pam_status);
+    ret = sdap_access_recv(req);
     talloc_zfree(req);
-    if (ret != EOK) goto fail;
 
-    switch(pam_status) {
-    case PAM_SUCCESS:
+    switch(ret) {
+    case EOK:
         /* Account wasn't locked. Continue below
          * to HBAC processing.
          */
         break;
-    case PAM_PERM_DENIED:
+    case ERR_ACCESS_DENIED:
         /* Account was locked. Return permission denied
          * here.
          */
         pd->pam_status = PAM_PERM_DENIED;
-        be_req_terminate(be_req, DP_ERR_OK, PAM_PERM_DENIED, NULL);
+        be_req_terminate(be_req, DP_ERR_OK, pd->pam_status, NULL);
         return;
     default:
         /* We got an unexpected error. Return it as-is */
         pd->pam_status = PAM_SYSTEM_ERR;
-        be_req_terminate(be_req, DP_ERR_FATAL, pam_status, NULL);
+        be_req_terminate(be_req, DP_ERR_FATAL, pd->pam_status,
+                         sss_strerror(ret));
         return;
     }
 
     hbac_ctx = talloc_zero(be_req, struct hbac_ctx);
     if (hbac_ctx == NULL) {
         DEBUG(1, ("talloc failed.\n"));
+        ret = ENOMEM;
         goto fail;
     }
 
@@ -155,6 +155,7 @@ static void ipa_hbac_check(struct tevent_req *req)
     hbac_ctx->search_bases = ipa_access_ctx->hbac_search_bases;
     if (hbac_ctx->search_bases == NULL) {
         DEBUG(1, ("No HBAC search base found.\n"));
+        ret = EINVAL;
         goto fail;
     }
 
@@ -176,9 +177,9 @@ static void ipa_hbac_check(struct tevent_req *req)
 fail:
     if (hbac_ctx) {
         /* Return an proper error */
-        ipa_access_reply(hbac_ctx, pam_status);
+        ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR);
     } else {
-        be_req_terminate(be_req, DP_ERR_FATAL, pam_status, NULL);
+        be_req_terminate(be_req, DP_ERR_FATAL, PAM_SYSTEM_ERR, NULL);
     }
 }
 
diff --git a/src/providers/ldap/ldap_access.c b/src/providers/ldap/ldap_access.c
index 5a8e12f05845fb6d59281d6a2ef162d64e0074ca..4a06e66bb2a82ec7fc03922c911d3ffadb507771 100644
--- a/src/providers/ldap/ldap_access.c
+++ b/src/providers/ldap/ldap_access.c
@@ -69,15 +69,23 @@ void sdap_pam_access_handler(struct be_req *breq)
 static void sdap_access_done(struct tevent_req *req)
 {
     errno_t ret;
-    int pam_status = PAM_SYSTEM_ERR;
+    int pam_status;
     struct be_req *breq =
             tevent_req_callback_data(req, struct be_req);
 
-    ret = sdap_access_recv(req, &pam_status);
+    ret = sdap_access_recv(req);
     talloc_zfree(req);
-    if (ret != EOK) {
+    switch (ret) {
+    case EOK:
+        pam_status = PAM_SUCCESS;
+        break;
+    case ERR_ACCESS_DENIED:
+        pam_status = PAM_PERM_DENIED;
+        break;
+    default:
         DEBUG(SSSDBG_CRIT_FAILURE, ("Error retrieving access check result.\n"));
         pam_status = PAM_SYSTEM_ERR;
+        break;
     }
 
     sdap_access_reply(breq, pam_status);
diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c
index aebf45240810b322bab636870adbbff376a0e0cb..6343456c42903459faf3e216e789fffd8ae8fceb 100644
--- a/src/providers/ldap/sdap_access.c
+++ b/src/providers/ldap/sdap_access.c
@@ -47,33 +47,16 @@ static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx,
                                              struct sdap_access_ctx *access_ctx,
                                              const char *username,
                                              struct ldb_message *user_entry);
-static void sdap_access_filter_done(struct tevent_req *subreq);
+static errno_t sdap_access_filter_recv(struct tevent_req *req);
 
-static struct tevent_req *sdap_account_expired_send(TALLOC_CTX *mem_ctx,
-                                             struct tevent_context *ev,
-                                             struct sdap_access_ctx *access_ctx,
-                                             struct pam_data *pd,
-                                             struct ldb_message *user_entry);
-static errno_t sdap_access_service_recv(struct tevent_req *req,
-                                        int *pam_status);
-static void sdap_access_service_done(struct tevent_req *subreq);
+static errno_t sdap_account_expired(struct sdap_access_ctx *access_ctx,
+                                    struct pam_data *pd,
+                                    struct ldb_message *user_entry);
 
-static struct tevent_req *sdap_access_service_send(
-        TALLOC_CTX *mem_ctx,
-        struct tevent_context *ev,
-        struct pam_data *pd,
-        struct ldb_message *user_entry);
+static  errno_t sdap_access_service(struct pam_data *pd,
+                                    struct ldb_message *user_entry);
 
-static void sdap_account_expired_done(struct tevent_req *subreq);
-
-static errno_t sdap_access_host_recv(struct tevent_req *req,
-                                        int *pam_status);
-static void sdap_access_host_done(struct tevent_req *subreq);
-
-static struct tevent_req *sdap_access_host_send(
-        TALLOC_CTX *mem_ctx,
-        struct tevent_context *ev,
-        struct ldb_message *user_entry);
+static errno_t sdap_access_host(struct ldb_message *user_entry);
 
 struct sdap_access_req_ctx {
     struct pam_data *pd;
@@ -81,12 +64,14 @@ struct sdap_access_req_ctx {
     struct sdap_access_ctx *access_ctx;
     struct be_ctx *be_ctx;
     struct sss_domain_info *domain;
-    int pam_status;
     struct ldb_message *user_entry;
     size_t current_rule;
 };
 
-static errno_t select_next_rule(struct tevent_req *req);
+static errno_t check_next_rule(struct sdap_access_req_ctx *state,
+                               struct tevent_req *req);
+static void sdap_access_filter_done(struct tevent_req *subreq);
+
 struct tevent_req *
 sdap_access_send(TALLOC_CTX *mem_ctx,
                  struct tevent_context *ev,
@@ -111,7 +96,6 @@ sdap_access_send(TALLOC_CTX *mem_ctx,
     state->be_ctx = be_ctx;
     state->domain = domain;
     state->pd = pd;
-    state->pam_status = PAM_SYSTEM_ERR;
     state->ev = ev;
     state->access_ctx = access_ctx;
     state->current_rule = 0;
@@ -120,8 +104,7 @@ sdap_access_send(TALLOC_CTX *mem_ctx,
 
     if (access_ctx->access_rule[0] == LDAP_ACCESS_EMPTY) {
         DEBUG(3, ("No access rules defined, access denied.\n"));
-        state->pam_status = PAM_PERM_DENIED;
-        ret = EOK;
+        ret = ERR_ACCESS_DENIED;
         goto done;
     }
 
@@ -142,18 +125,16 @@ sdap_access_send(TALLOC_CTX *mem_ctx,
     }
     if (ret != EOK) {
         if (ret == ENOENT) {
-            /* If we can't find the user, return permission denied */
-            state->pam_status = PAM_PERM_DENIED;
-            ret = EOK;
+            /* If we can't find the user, return access denied */
+            ret = ERR_ACCESS_DENIED;
             goto done;
         }
         goto done;
     }
     else {
         if (res->count == 0) {
-            /* If we can't find the user, return permission denied */
-            state->pam_status = PAM_PERM_DENIED;
-            ret = EOK;
+            /* If we can't find the user, return access denied */
+            ret = ERR_ACCESS_DENIED;
             goto done;
         }
 
@@ -166,19 +147,11 @@ sdap_access_send(TALLOC_CTX *mem_ctx,
 
     state->user_entry = res->msgs[0];
 
-    ret = select_next_rule(req);
-    if (ret != EOK) {
-        if (ret == EACCES) {
-            state->pam_status = PAM_PERM_DENIED;
-            ret = EOK;
-            goto done;
-        }
-        DEBUG(1, ("select_next_rule failed.\n"));
-        goto done;
+    ret = check_next_rule(state, req);
+    if (ret == EAGAIN) {
+        return req;
     }
 
-    return req;
-
 done:
     if (ret == EOK) {
         tevent_req_done(req);
@@ -189,16 +162,17 @@ done:
     return req;
 }
 
-static errno_t select_next_rule(struct tevent_req *req)
+static errno_t check_next_rule(struct sdap_access_req_ctx *state,
+                               struct tevent_req *req)
 {
-    struct sdap_access_req_ctx *state =
-            tevent_req_data(req, struct sdap_access_req_ctx);
     struct tevent_req *subreq;
+    int ret = EOK;
 
-    switch (state->access_ctx->access_rule[state->current_rule]) {
+    while (ret == EOK) {
+        switch (state->access_ctx->access_rule[state->current_rule]) {
         case LDAP_ACCESS_EMPTY:
-            return ENOENT;
-            break;
+            /* we are done with no errors */
+            return EOK;
 
         case LDAP_ACCESS_FILTER:
             subreq = sdap_access_filter_send(state, state->ev, state->be_ctx,
@@ -212,85 +186,74 @@ static errno_t select_next_rule(struct tevent_req *req)
             }
 
             tevent_req_set_callback(subreq, sdap_access_filter_done, req);
-            return EOK;
+            return EAGAIN;
 
         case LDAP_ACCESS_EXPIRE:
-            subreq = sdap_account_expired_send(state, state->ev,
-                                               state->access_ctx,
-                                               state->pd,
-                                               state->user_entry);
-            if (subreq == NULL) {
-                DEBUG(1, ("sdap_account_expired_send failed.\n"));
-                return ENOMEM;
-            }
-
-            tevent_req_set_callback(subreq, sdap_account_expired_done, req);
-            return EOK;
+            ret = sdap_account_expired(state->access_ctx,
+                                       state->pd, state->user_entry);
+            break;
 
         case LDAP_ACCESS_SERVICE:
-            subreq = sdap_access_service_send(state, state->ev,
-                                              state->pd,
-                                              state->user_entry);
-            if (subreq == NULL) {
-                DEBUG(1, ("sdap_access_service_send failed.\n"));
-                return ENOMEM;
-            }
-            tevent_req_set_callback(subreq, sdap_access_service_done, req);
-            return EOK;
+            ret = sdap_access_service( state->pd, state->user_entry);
+            break;
 
         case LDAP_ACCESS_HOST:
-            subreq = sdap_access_host_send(state, state->ev,
-                                           state->user_entry);
-            if (subreq == NULL) {
-                DEBUG(1, ("sdap_access_host_send failed.\n"));
-                return ENOMEM;
-            }
-            tevent_req_set_callback(subreq, sdap_access_host_done, req);
-            return EOK;
+            ret = sdap_access_host(state->user_entry);
+            break;
 
         default:
             DEBUG(1, ("Unexpected access rule type. Access denied.\n"));
+            ret = ERR_ACCESS_DENIED;
+        }
+
+        state->current_rule++;
     }
 
-    return EACCES;
+    return ret;
 }
 
-static void next_access_rule(struct tevent_req *req)
+static void sdap_access_filter_done(struct tevent_req *subreq)
 {
+    errno_t ret;
+    struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
     struct sdap_access_req_ctx *state =
             tevent_req_data(req, struct sdap_access_req_ctx);
-    int ret;
 
-    if (state->pam_status == PAM_PERM_DENIED ||
-        state->pam_status == PAM_ACCT_EXPIRED) {
-        tevent_req_done(req);
+    ret = sdap_access_filter_recv(subreq);
+    talloc_zfree(subreq);
+    if (ret != EOK) {
+        DEBUG(1, ("Error retrieving access check result.\n"));
+        tevent_req_error(req, ret);
         return;
     }
 
     state->current_rule++;
 
-    ret = select_next_rule(req);
-    if (ret != EOK) {
-        if (ret == ENOENT) {
-            state->pam_status = PAM_SUCCESS;
-            tevent_req_done(req);
-            return;
-        } else if (ret == EACCES) {
-            state->pam_status = PAM_PERM_DENIED;
-            tevent_req_done(req);
-        } else {
-            tevent_req_error(req, ret);
-        }
+    ret = check_next_rule(state, req);
+    switch (ret) {
+    case EAGAIN:
+        return;
+    case EOK:
+        tevent_req_done(req);
+        return;
+    default:
+        tevent_req_error(req, ret);
+        return;
     }
+}
+
+errno_t sdap_access_recv(struct tevent_req *req)
+{
+    TEVENT_REQ_RETURN_ON_ERROR(req);
 
-    return;
+    return EOK;
 }
 
+
 #define SHADOW_EXPIRE_MSG "Account expired according to shadow attributes"
 
 static errno_t sdap_account_expired_shadow(struct pam_data *pd,
-                                           struct ldb_message *user_entry,
-                                           int *pam_status)
+                                           struct ldb_message *user_entry)
 {
     int ret;
     const char *val;
@@ -303,7 +266,6 @@ static errno_t sdap_account_expired_shadow(struct pam_data *pd,
     if (val == NULL) {
         DEBUG(3, ("Shadow expire attribute not found. "
                   "Access will be granted.\n"));
-        *pam_status = PAM_SUCCESS;
         return EOK;
     }
     ret = string_to_shadowpw_days(val, &sp_expire);
@@ -314,7 +276,6 @@ static errno_t sdap_account_expired_shadow(struct pam_data *pd,
 
     today = (long) (time(NULL) / (60 * 60 * 24));
     if (sp_expire > 0 && today > sp_expire) {
-        *pam_status = PAM_ACCT_EXPIRED;
 
         ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
                                sizeof(SHADOW_EXPIRE_MSG),
@@ -322,8 +283,8 @@ static errno_t sdap_account_expired_shadow(struct pam_data *pd,
         if (ret != EOK) {
             DEBUG(1, ("pam_add_response failed.\n"));
         }
-    } else {
-        *pam_status = PAM_SUCCESS;
+
+        return ERR_ACCOUNT_EXPIRED;
     }
 
     return EOK;
@@ -363,8 +324,7 @@ static bool ad_account_expired(uint64_t expiration_time)
 }
 
 static errno_t sdap_account_expired_ad(struct pam_data *pd,
-                                       struct ldb_message *user_entry,
-                                       int *pam_status)
+                                       struct ldb_message *user_entry)
 {
     uint32_t uac;
     uint64_t expiration_time;
@@ -383,7 +343,6 @@ static errno_t sdap_account_expired_ad(struct pam_data *pd,
               pd->user, expiration_time));
 
     if (uac & UAC_ACCOUNTDISABLE) {
-        *pam_status = PAM_PERM_DENIED;
 
         ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
                                sizeof(AD_DISABLE_MESSAGE),
@@ -391,8 +350,10 @@ static errno_t sdap_account_expired_ad(struct pam_data *pd,
         if (ret != EOK) {
             DEBUG(1, ("pam_add_response failed.\n"));
         }
+
+        return ERR_ACCESS_DENIED;
+
     } else if (ad_account_expired(expiration_time)) {
-        *pam_status = PAM_ACCT_EXPIRED;
 
         ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
                                sizeof(AD_EXPIRED_MESSAGE),
@@ -400,8 +361,8 @@ static errno_t sdap_account_expired_ad(struct pam_data *pd,
         if (ret != EOK) {
             DEBUG(1, ("pam_add_response failed.\n"));
         }
-    } else {
-        *pam_status = PAM_SUCCESS;
+
+        return ERR_ACCOUNT_EXPIRED;
     }
 
     return EOK;
@@ -410,8 +371,7 @@ static errno_t sdap_account_expired_ad(struct pam_data *pd,
 #define RHDS_LOCK_MSG "The user account is locked on the server"
 
 static errno_t sdap_account_expired_rhds(struct pam_data *pd,
-                                         struct ldb_message *user_entry,
-                                         int *pam_status)
+                                         struct ldb_message *user_entry)
 {
     bool locked;
     int ret;
@@ -429,9 +389,9 @@ static errno_t sdap_account_expired_rhds(struct pam_data *pd,
         if (ret != EOK) {
             DEBUG(1, ("pam_add_response failed.\n"));
         }
-    }
 
-    *pam_status = locked ? PAM_PERM_DENIED : PAM_SUCCESS;
+        return ERR_ACCESS_DENIED;
+    }
 
     return EOK;
 }
@@ -541,8 +501,7 @@ static bool nds_check_time_map(const struct ldb_val *time_map)
 }
 
 static errno_t sdap_account_expired_nds(struct pam_data *pd,
-                                         struct ldb_message *user_entry,
-                                         int *pam_status)
+                                         struct ldb_message *user_entry)
 {
     bool locked = true;
     int ret;
@@ -563,6 +522,9 @@ static errno_t sdap_account_expired_nds(struct pam_data *pd,
         if (ret != EOK) {
             DEBUG(1, ("pam_add_response failed.\n"));
         }
+
+        return ERR_ACCESS_DENIED;
+
     } else {
         exp_time_str = ldb_msg_find_attr_as_string(user_entry,
                                                 SYSDB_NDS_LOGIN_EXPIRATION_TIME,
@@ -579,6 +541,9 @@ static errno_t sdap_account_expired_nds(struct pam_data *pd,
             if (ret != EOK) {
                 DEBUG(1, ("pam_add_response failed.\n"));
             }
+
+            return ERR_ACCESS_DENIED;
+
         } else {
             time_map = ldb_msg_find_ldb_val(user_entry,
                                             SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP);
@@ -595,132 +560,61 @@ static errno_t sdap_account_expired_nds(struct pam_data *pd,
                 if (ret != EOK) {
                     DEBUG(1, ("pam_add_response failed.\n"));
                 }
+
+                return ERR_ACCESS_DENIED;
             }
         }
     }
 
-    *pam_status = locked ? PAM_PERM_DENIED : PAM_SUCCESS;
-
     return EOK;
 }
 
-struct sdap_account_expired_req_ctx {
-    int pam_status;
-};
 
-static struct tevent_req *sdap_account_expired_send(TALLOC_CTX *mem_ctx,
-                                             struct tevent_context *ev,
-                                             struct sdap_access_ctx *access_ctx,
-                                             struct pam_data *pd,
-                                             struct ldb_message *user_entry)
+static errno_t sdap_account_expired(struct sdap_access_ctx *access_ctx,
+                                    struct pam_data *pd,
+                                    struct ldb_message *user_entry)
 {
-    struct tevent_req *req;
-    struct sdap_account_expired_req_ctx *state;
-    int ret;
     const char *expire;
-
-    req = tevent_req_create(mem_ctx, &state, struct sdap_account_expired_req_ctx);
-    if (req == NULL) {
-        DEBUG(1, ("tevent_req_create failed.\n"));
-        return NULL;
-    }
-
-    state->pam_status = PAM_SYSTEM_ERR;
+    int ret;
 
     expire = dp_opt_get_cstring(access_ctx->id_ctx->opts->basic,
                                 SDAP_ACCOUNT_EXPIRE_POLICY);
     if (expire == NULL) {
         DEBUG(1, ("Missing account expire policy. Access denied\n"));
-        state->pam_status = PAM_PERM_DENIED;
-        ret = EOK;
-        goto done;
+        return ERR_ACCESS_DENIED;
     } else {
         if (strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_SHADOW) == 0) {
-            ret = sdap_account_expired_shadow(pd, user_entry,
-                                              &state->pam_status);
+            ret = sdap_account_expired_shadow(pd, user_entry);
             if (ret != EOK) {
                 DEBUG(1, ("sdap_account_expired_shadow failed.\n"));
-                goto done;
             }
         } else if (strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_AD) == 0) {
-            ret = sdap_account_expired_ad(pd, user_entry,
-                                          &state->pam_status);
+            ret = sdap_account_expired_ad(pd, user_entry);
             if (ret != EOK) {
                 DEBUG(1, ("sdap_account_expired_ad failed.\n"));
-                goto done;
             }
         } else if (strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_RHDS) == 0 ||
                    strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_IPA) == 0 ||
                    strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_389DS) == 0) {
-            ret = sdap_account_expired_rhds(pd, user_entry,
-                                            &state->pam_status);
+            ret = sdap_account_expired_rhds(pd, user_entry);
             if (ret != EOK) {
                 DEBUG(1, ("sdap_account_expired_rhds failed.\n"));
-                goto done;
             }
         } else if (strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_NDS) == 0) {
-            ret = sdap_account_expired_nds(pd, user_entry, &state->pam_status);
+            ret = sdap_account_expired_nds(pd, user_entry);
             if (ret != EOK) {
                 DEBUG(1, ("sdap_account_expired_nds failed.\n"));
-                goto done;
             }
         } else {
             DEBUG(1, ("Unsupported LDAP account expire policy [%s]. "
                       "Access denied.\n", expire));
-            state->pam_status = PAM_PERM_DENIED;
-            ret = EOK;
-            goto done;
+            ret = ERR_ACCESS_DENIED;
         }
     }
 
-    ret = EOK;
-
-done:
-    if (ret == EOK) {
-        tevent_req_done(req);
-    } else {
-        tevent_req_error(req, ret);
-    }
-    tevent_req_post(req, ev);
-
-    return req;
+    return ret;
 }
 
-static errno_t sdap_account_expired_recv(struct tevent_req *req, int *pam_status)
-{
-    struct sdap_account_expired_req_ctx *state =
-            tevent_req_data(req, struct sdap_account_expired_req_ctx);
-
-    TEVENT_REQ_RETURN_ON_ERROR(req);
-
-    *pam_status = state->pam_status;
-
-    return EOK;
-}
-
-static void sdap_account_expired_done(struct tevent_req *subreq)
-{
-    errno_t ret;
-    struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
-    struct sdap_access_req_ctx *state =
-            tevent_req_data(req, struct sdap_access_req_ctx);
-
-    ret = sdap_account_expired_recv(subreq, &state->pam_status);
-    talloc_zfree(subreq);
-    if (ret != EOK) {
-        DEBUG(1, ("Error retrieving access check result.\n"));
-        state->pam_status = PAM_SYSTEM_ERR;
-        tevent_req_error(req, ret);
-        return;
-    }
-
-    next_access_rule(req);
-
-    return;
-}
-
-
-
 struct sdap_access_filter_req_ctx {
     const char *username;
     const char *filter;
@@ -730,12 +624,11 @@ struct sdap_access_filter_req_ctx {
     struct sdap_id_op *sdap_op;
     struct sysdb_handle *handle;
     struct sss_domain_info *domain;
-    int pam_status;
     bool cached_access;
     char *basedn;
 };
 
-static void sdap_access_filter_decide_offline(struct tevent_req *req);
+static errno_t sdap_access_filter_decide_offline(struct tevent_req *req);
 static int sdap_access_filter_retry(struct tevent_req *req);
 static void sdap_access_filter_connect_done(struct tevent_req *subreq);
 static void sdap_access_filter_get_access_done(struct tevent_req *req);
@@ -747,11 +640,11 @@ static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx,
                                              const char *username,
                                              struct ldb_message *user_entry)
 {
-    errno_t ret;
     struct sdap_access_filter_req_ctx *state;
     struct tevent_req *req;
     const char *basedn;
     char *clean_username;
+    errno_t ret = ERR_INTERNAL;
 
     req = tevent_req_create(mem_ctx, &state, struct sdap_access_filter_req_ctx);
     if (req == NULL) {
@@ -761,15 +654,12 @@ static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx,
     if (access_ctx->filter == NULL || *access_ctx->filter == '\0') {
         /* If no filter is set, default to restrictive */
         DEBUG(6, ("No filter set. Access is denied.\n"));
-        state->pam_status = PAM_PERM_DENIED;
-        tevent_req_done(req);
-        tevent_req_post(req, ev);
-        return req;
+        ret = ERR_ACCESS_DENIED;
+        goto done;
     }
 
     state->filter = NULL;
     state->username = username;
-    state->pam_status = PAM_SYSTEM_ERR;
     state->sdap_ctx = access_ctx->id_ctx;
     state->ev = ev;
     state->access_ctx = access_ctx;
@@ -783,31 +673,31 @@ static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx,
     /* Ok, we have one result, check if we are online or offline */
     if (be_is_offline(be_ctx)) {
         /* Ok, we're offline. Return from the cache */
-        sdap_access_filter_decide_offline(req);
-        goto finished;
+        ret = sdap_access_filter_decide_offline(req);
+        goto done;
     }
 
     /* Perform online operation */
-    basedn = ldb_msg_find_attr_as_string(user_entry,
-                                         SYSDB_ORIG_DN,
-                                         NULL);
-    if(basedn == NULL) {
+    basedn = ldb_msg_find_attr_as_string(user_entry, SYSDB_ORIG_DN, NULL);
+    if (basedn == NULL) {
         DEBUG(1,("Could not find originalDN for user [%s]\n",
                  state->username));
-        goto failed;
+        ret = EINVAL;
+        goto done;
     }
 
     state->basedn = talloc_strdup(state, basedn);
     if (state->basedn == NULL) {
         DEBUG(1, ("Could not allocate memory for originalDN\n"));
-        goto failed;
+        ret = ENOMEM;
+        goto done;
     }
 
     /* Construct the filter */
 
     ret = sss_filter_sanitize(state, state->username, &clean_username);
     if (ret != EOK) {
-        goto failed;
+        goto done;
     }
 
     state->filter = talloc_asprintf(
@@ -819,7 +709,8 @@ static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx,
         state->access_ctx->filter);
     if (state->filter == NULL) {
         DEBUG(0, ("Could not construct access filter\n"));
-        goto failed;
+        ret = ENOMEM;
+        goto done;
     }
     talloc_zfree(clean_username);
 
@@ -828,37 +719,38 @@ static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx,
     state->sdap_op = sdap_id_op_create(state, state->sdap_ctx->conn_cache);
     if (!state->sdap_op) {
         DEBUG(2, ("sdap_id_op_create failed\n"));
-        goto failed;
+        ret = ENOMEM;
+        goto done;
     }
 
     ret = sdap_access_filter_retry(req);
     if (ret != EOK) {
-        goto failed;
+        goto done;
     }
 
     return req;
 
-failed:
-    talloc_free(req);
-    return NULL;
-
-finished:
-    tevent_req_done(req);
+done:
+    if (ret == EOK) {
+        tevent_req_done(req);
+    } else {
+        tevent_req_error(req, ret);
+    }
     tevent_req_post(req, ev);
     return req;
 }
 
-static void sdap_access_filter_decide_offline(struct tevent_req *req)
+static errno_t sdap_access_filter_decide_offline(struct tevent_req *req)
 {
     struct sdap_access_filter_req_ctx *state =
             tevent_req_data(req, struct sdap_access_filter_req_ctx);
 
     if (state->cached_access) {
         DEBUG(6, ("Access granted by cached credentials\n"));
-        state->pam_status = PAM_SUCCESS;
+        return EOK;
     } else {
         DEBUG(6, ("Access denied by cached credentials\n"));
-        state->pam_status = PAM_PERM_DENIED;
+        return ERR_ACCESS_DENIED;
     }
 }
 
@@ -892,9 +784,11 @@ static void sdap_access_filter_connect_done(struct tevent_req *subreq)
 
     if (ret != EOK) {
         if (dp_error == DP_ERR_OFFLINE) {
-            sdap_access_filter_decide_offline(req);
-            tevent_req_done(req);
-            return;
+            ret = sdap_access_filter_decide_offline(req);
+            if (ret == EOK) {
+                tevent_req_done(req);
+                return;
+            }
         }
 
         tevent_req_error(req, ret);
@@ -917,7 +811,6 @@ static void sdap_access_filter_connect_done(struct tevent_req *subreq)
                                    false);
     if (subreq == NULL) {
         DEBUG(1, ("Could not start LDAP communication\n"));
-        state->pam_status = PAM_SYSTEM_ERR;
         tevent_req_error(req, EIO);
         return;
     }
@@ -927,7 +820,7 @@ static void sdap_access_filter_connect_done(struct tevent_req *subreq)
 
 static void sdap_access_filter_get_access_done(struct tevent_req *subreq)
 {
-    int ret, dp_error;
+    int ret, tret, dp_error;
     size_t num_results;
     bool found = false;
     struct sysdb_attrs *attrs;
@@ -936,6 +829,7 @@ static void sdap_access_filter_get_access_done(struct tevent_req *subreq)
             tevent_req_callback_data(subreq, struct tevent_req);
     struct sdap_access_filter_req_ctx *state =
             tevent_req_data(req, struct sdap_access_filter_req_ctx);
+
     ret = sdap_get_generic_recv(subreq, state,
                                 &num_results, &results);
     talloc_zfree(subreq);
@@ -944,17 +838,15 @@ static void sdap_access_filter_get_access_done(struct tevent_req *subreq)
     if (ret != EOK) {
         if (dp_error == DP_ERR_OK) {
             /* retry */
-            ret = sdap_access_filter_retry(req);
-            if (ret == EOK) {
+            tret = sdap_access_filter_retry(req);
+            if (tret == EOK) {
                 return;
             }
-            state->pam_status = PAM_SYSTEM_ERR;
         } else if (dp_error == DP_ERR_OFFLINE) {
-            sdap_access_filter_decide_offline(req);
+            ret = sdap_access_filter_decide_offline(req);
         } else {
             DEBUG(1, ("sdap_get_generic_send() returned error [%d][%s]\n",
                       ret, strerror(ret)));
-            state->pam_status = PAM_SYSTEM_ERR;
         }
 
         goto done;
@@ -972,8 +864,7 @@ static void sdap_access_filter_get_access_done(struct tevent_req *subreq)
     }
     else if (results == NULL) {
         DEBUG(1, ("num_results > 0, but results is NULL\n"));
-        ret = EIO;
-        state->pam_status = PAM_SYSTEM_ERR;
+        ret = ERR_INTERNAL;
         goto done;
     }
     else if (num_results > 1) {
@@ -981,8 +872,7 @@ static void sdap_access_filter_get_access_done(struct tevent_req *subreq)
          * here, since we're doing a base-scoped search
          */
         DEBUG(1, ("Received multiple replies\n"));
-        ret = EIO;
-        state->pam_status = PAM_SYSTEM_ERR;
+        ret = ERR_INTERNAL;
         goto done;
     }
     else { /* Ok, we got a single reply */
@@ -991,17 +881,17 @@ static void sdap_access_filter_get_access_done(struct tevent_req *subreq)
 
     if (found) {
         /* Save "allow" to the cache for future offline
-         * access checks.
+         :q* access checks.
          */
         DEBUG(6, ("Access granted by online lookup\n"));
-        state->pam_status = PAM_SUCCESS;
+        ret = EOK;
     }
     else {
         /* Save "disallow" to the cache for future offline
          * access checks.
          */
         DEBUG(6, ("Access denied by online lookup\n"));
-        state->pam_status = PAM_PERM_DENIED;
+        ret = ERR_ACCESS_DENIED;
     }
 
     attrs = sysdb_new_attrs(state);
@@ -1011,28 +901,22 @@ static void sdap_access_filter_get_access_done(struct tevent_req *subreq)
         goto done;
     }
 
-    ret = sysdb_attrs_add_bool(attrs, SYSDB_LDAP_ACCESS_FILTER,
-                               state->pam_status == PAM_SUCCESS ?
-                                                    true :
-                                                    false);
-    if (ret != EOK) {
+    tret = sysdb_attrs_add_bool(attrs, SYSDB_LDAP_ACCESS_FILTER,
+                                ret == EOK ?  true : false);
+    if (tret != EOK) {
         /* Failing to save to the cache is non-fatal.
          * Just return the result.
          */
-        ret = EOK;
         DEBUG(1, ("Could not set up attrs\n"));
         goto done;
     }
 
-    ret = sysdb_set_user_attr(state->domain->sysdb,
-                              state->domain,
-                              state->username,
-                              attrs, SYSDB_MOD_REP);
-    if (ret != EOK) {
+    tret = sysdb_set_user_attr(state->domain->sysdb, state->domain,
+                               state->username, attrs, SYSDB_MOD_REP);
+    if (tret != EOK) {
         /* Failing to save to the cache is non-fatal.
          * Just return the result.
          */
-        ret = EOK;
         DEBUG(1, ("Failed to set user access attribute\n"));
         goto done;
     }
@@ -1046,43 +930,13 @@ done:
     }
 }
 
-static errno_t sdap_access_filter_recv(struct tevent_req *req, int *pam_status)
+static errno_t sdap_access_filter_recv(struct tevent_req *req)
 {
-    struct sdap_access_filter_req_ctx *state =
-            tevent_req_data(req, struct sdap_access_filter_req_ctx);
-
     TEVENT_REQ_RETURN_ON_ERROR(req);
 
-    *pam_status = state->pam_status;
-
     return EOK;
 }
 
-static void sdap_access_filter_done(struct tevent_req *subreq)
-{
-    errno_t ret;
-    struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
-    struct sdap_access_req_ctx *state =
-            tevent_req_data(req, struct sdap_access_req_ctx);
-
-    ret = sdap_access_filter_recv(subreq, &state->pam_status);
-    talloc_zfree(subreq);
-    if (ret != EOK) {
-        DEBUG(1, ("Error retrieving access check result.\n"));
-        state->pam_status = PAM_SYSTEM_ERR;
-        tevent_req_error(req, ret);
-        return;
-    }
-
-    next_access_rule(req);
-
-    return;
-}
-
-
-struct sdap_access_service_ctx {
-    int pam_status;
-};
 
 #define AUTHR_SRV_MISSING_MSG "Authorized service attribute missing, " \
                               "access denied"
@@ -1090,170 +944,97 @@ struct sdap_access_service_ctx {
 #define AUTHR_SRV_NO_MATCH_MSG "Authorized service attribute has " \
                                "no matching rule, access denied"
 
-static struct tevent_req *sdap_access_service_send(
-        TALLOC_CTX *mem_ctx,
-        struct tevent_context *ev,
-        struct pam_data *pd,
-        struct ldb_message *user_entry)
+static errno_t sdap_access_service(struct pam_data *pd,
+                                   struct ldb_message *user_entry)
 {
-    errno_t ret;
-    struct tevent_req *req;
-    struct sdap_access_service_ctx *state;
+    errno_t ret, tret;
     struct ldb_message_element *el;
     unsigned int i;
     char *service;
 
-    req = tevent_req_create(mem_ctx, &state, struct sdap_access_service_ctx);
-    if (!req) {
-        return NULL;
-    }
-
-    state->pam_status = PAM_PERM_DENIED;
-
     el = ldb_msg_find_element(user_entry, SYSDB_AUTHORIZED_SERVICE);
     if (!el || el->num_values == 0) {
         DEBUG(1, ("Missing authorized services. Access denied\n"));
 
-        ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
+        tret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
                                sizeof(AUTHR_SRV_MISSING_MSG),
                                (const uint8_t *) AUTHR_SRV_MISSING_MSG);
-        if (ret != EOK) {
+        if (tret != EOK) {
             DEBUG(1, ("pam_add_response failed.\n"));
         }
 
-        ret = EOK;
-        goto done;
+        return ERR_ACCESS_DENIED;
     }
 
+    ret = ENOENT;
+
     for (i = 0; i < el->num_values; i++) {
         service = (char *)el->values[i].data;
         if (service[0] == '!' &&
                 strcasecmp(pd->service, service+1) == 0) {
             /* This service is explicitly denied */
-            state->pam_status = PAM_PERM_DENIED;
             DEBUG(4, ("Access denied by [%s]\n", service));
 
-            ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
+            tret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
                                    sizeof(AUTHR_SRV_DENY_MSG),
                                    (const uint8_t *) AUTHR_SRV_DENY_MSG);
-            if (ret != EOK) {
+            if (tret != EOK) {
                 DEBUG(1, ("pam_add_response failed.\n"));
             }
 
             /* A denial trumps all. Break here */
-            ret = EOK;
-            goto done;
+            return ERR_ACCESS_DENIED;
 
         } else if (strcasecmp(pd->service, service) == 0) {
             /* This service is explicitly allowed */
-            state->pam_status = PAM_SUCCESS;
             DEBUG(4, ("Access granted for [%s]\n", service));
             /* We still need to loop through to make sure
              * that it's not also explicitly denied
              */
+            ret = EOK;
         } else if (strcmp("*", service) == 0) {
             /* This user has access to all services */
-            state->pam_status = PAM_SUCCESS;
             DEBUG(4, ("Access granted to all services\n"));
             /* We still need to loop through to make sure
              * that it's not also explicitly denied
              */
+            ret = EOK;
         }
     }
 
-    if (state->pam_status != PAM_SUCCESS) {
+    if (ret == ENOENT) {
         DEBUG(4, ("No matching service rule found\n"));
 
-        ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
+        tret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
                                sizeof(AUTHR_SRV_NO_MATCH_MSG),
                                (const uint8_t *) AUTHR_SRV_NO_MATCH_MSG);
-        if (ret != EOK) {
+        if (tret != EOK) {
             DEBUG(1, ("pam_add_response failed.\n"));
         }
-    }
-
-    ret = EOK;
 
-done:
-    if (ret == EOK) {
-        tevent_req_done(req);
-    } else {
-        tevent_req_error(req, ret);
+        ret = ERR_ACCESS_DENIED;
     }
-    tevent_req_post(req, ev);
 
-    return req;
+    return ret;
 }
 
-static errno_t sdap_access_service_recv(struct tevent_req *req,
-                                        int *pam_status)
-{
-    struct sdap_access_service_ctx *state =
-            tevent_req_data(req, struct sdap_access_service_ctx);
-
-    TEVENT_REQ_RETURN_ON_ERROR(req);
-
-    *pam_status = state->pam_status;
-
-    return EOK;
-}
-
-static void sdap_access_service_done(struct tevent_req *subreq)
-{
-    errno_t ret;
-    struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
-    struct sdap_access_req_ctx *state =
-            tevent_req_data(req, struct sdap_access_req_ctx);
-
-    ret = sdap_access_service_recv(subreq, &state->pam_status);
-    talloc_zfree(subreq);
-    if (ret != EOK) {
-        DEBUG(1, ("Error retrieving access check result.\n"));
-        state->pam_status = PAM_SYSTEM_ERR;
-        tevent_req_error(req, ret);
-        return;
-    }
-
-    next_access_rule(req);
-
-    return;
-}
-
-struct sdap_access_host_ctx {
-    int pam_status;
-};
-
-static struct tevent_req *sdap_access_host_send(
-        TALLOC_CTX *mem_ctx,
-        struct tevent_context *ev,
-        struct ldb_message *user_entry)
+static errno_t sdap_access_host(struct ldb_message *user_entry)
 {
     errno_t ret;
-    struct tevent_req *req;
-    struct sdap_access_host_ctx *state;
     struct ldb_message_element *el;
     unsigned int i;
     char *host;
     char hostname[HOST_NAME_MAX+1];
 
-    req = tevent_req_create(mem_ctx, &state, struct sdap_access_host_ctx);
-    if (!req) {
-        return NULL;
-    }
-
-    state->pam_status = PAM_PERM_DENIED;
-
     el = ldb_msg_find_element(user_entry, SYSDB_AUTHORIZED_HOST);
     if (!el || el->num_values == 0) {
         DEBUG(1, ("Missing hosts. Access denied\n"));
-        ret = EOK;
-        goto done;
+        return ERR_ACCESS_DENIED;
     }
 
     if (gethostname(hostname, sizeof(hostname)) == -1) {
         DEBUG(1, ("Unable to get system hostname. Access denied\n"));
-        ret = EOK;
-        goto done;
+        return ERR_ACCESS_DENIED;
     }
 
     /* FIXME: PADL's pam_ldap also calls gethostbyname() on the hostname
@@ -1262,93 +1043,38 @@ static struct tevent_req *sdap_access_host_send(
      *        order to be compatible...
      */
 
+    ret = ENOENT;
+
     for (i = 0; i < el->num_values; i++) {
         host = (char *)el->values[i].data;
         if (host[0] == '!' &&
                 strcasecmp(hostname, host+1) == 0) {
             /* This host is explicitly denied */
-            state->pam_status = PAM_PERM_DENIED;
             DEBUG(4, ("Access denied by [%s]\n", host));
             /* A denial trumps all. Break here */
-            break;
+            return ERR_ACCESS_DENIED;
 
         } else if (strcasecmp(hostname, host) == 0) {
             /* This host is explicitly allowed */
-            state->pam_status = PAM_SUCCESS;
             DEBUG(4, ("Access granted for [%s]\n", host));
             /* We still need to loop through to make sure
              * that it's not also explicitly denied
              */
+            ret = EOK;
         } else if (strcmp("*", host) == 0) {
             /* This user has access to all hosts */
-            state->pam_status = PAM_SUCCESS;
             DEBUG(4, ("Access granted to all hosts\n"));
             /* We still need to loop through to make sure
              * that it's not also explicitly denied
              */
+            ret = EOK;
         }
     }
 
-    if (state->pam_status != PAM_SUCCESS) {
+    if (ret == ENOENT) {
         DEBUG(4, ("No matching host rule found\n"));
+        ret = ERR_ACCESS_DENIED;
     }
 
-    ret = EOK;
-
-done:
-    if (ret == EOK) {
-        tevent_req_done(req);
-    } else {
-        tevent_req_error(req, ret);
-    }
-    tevent_req_post(req, ev);
-
-    return req;
-}
-
-static errno_t sdap_access_host_recv(struct tevent_req *req,
-                                        int *pam_status)
-{
-    struct sdap_access_host_ctx *state =
-            tevent_req_data(req, struct sdap_access_host_ctx);
-
-    TEVENT_REQ_RETURN_ON_ERROR(req);
-
-    *pam_status = state->pam_status;
-
-    return EOK;
-}
-
-static void sdap_access_host_done(struct tevent_req *subreq)
-{
-    errno_t ret;
-    struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
-    struct sdap_access_req_ctx *state =
-            tevent_req_data(req, struct sdap_access_req_ctx);
-
-    ret = sdap_access_host_recv(subreq, &state->pam_status);
-    talloc_zfree(subreq);
-    if (ret != EOK) {
-        DEBUG(1, ("Error retrieving access check result.\n"));
-        state->pam_status = PAM_SYSTEM_ERR;
-        tevent_req_error(req, ret);
-        return;
-    }
-
-    next_access_rule(req);
-
-    return;
-}
-
-errno_t
-sdap_access_recv(struct tevent_req *req, int *pam_status)
-{
-    struct sdap_access_req_ctx *state =
-            tevent_req_data(req, struct sdap_access_req_ctx);
-
-    TEVENT_REQ_RETURN_ON_ERROR(req);
-
-    *pam_status = state->pam_status;
-
-    return EOK;
+    return ret;
 }
diff --git a/src/providers/ldap/sdap_access.h b/src/providers/ldap/sdap_access.h
index 4f5f72010bd8ff3f45e8e471ef691d5a39f45795..cda078688b19182112d27e605008f6406a604daa 100644
--- a/src/providers/ldap/sdap_access.h
+++ b/src/providers/ldap/sdap_access.h
@@ -63,7 +63,6 @@ sdap_access_send(TALLOC_CTX *mem_ctx,
                  struct sss_domain_info *domain,
                  struct sdap_access_ctx *access_ctx,
                  struct pam_data *pd);
-errno_t
-sdap_access_recv(struct tevent_req *req, int *pam_status);
+errno_t sdap_access_recv(struct tevent_req *req);
 
 #endif /* SDAP_ACCESS_H_ */
diff --git a/src/util/util_errors.c b/src/util/util_errors.c
index 88806f531ed90699438deed060d192b7ac029920..a292fa6b19f38943228bd221c09cfe0a21604448 100644
--- a/src/util/util_errors.c
+++ b/src/util/util_errors.c
@@ -39,6 +39,7 @@ struct err_string error_to_str[] = {
     { "Password Change Failed" }, /* ERR_CHPASS_FAILED */
     { "Network I/O Error" }, /* ERR_NETWORK_IO */
     { "Account Expired" }, /* ERR_ACCOUNT_EXPIRED */
+    { "Host Access Denied" }, /* ERR_ACEESS_DENIED */
     { "Password Expired" }, /* ERR_PASSWORD_EXPIRED */
 };
 
diff --git a/src/util/util_errors.h b/src/util/util_errors.h
index bc69dc37f871e66a6854cd65597fad4e5992fe41..f809dee51880883dc665591519e30d1a5f4a35a1 100644
--- a/src/util/util_errors.h
+++ b/src/util/util_errors.h
@@ -62,6 +62,7 @@ enum sssd_errors {
     ERR_NETWORK_IO,
     ERR_ACCOUNT_EXPIRED,
     ERR_PASSWORD_EXPIRED,
+    ERR_ACCESS_DENIED,
     ERR_LAST            /* ALWAYS LAST */
 };
 
-- 
1.8.1.2

