b58328
From 85d71239bb974c8d8988c753f63ec12d1b735da3 Mon Sep 17 00:00:00 2001
b58328
From: Sumit Bose <sbose@redhat.com>
b58328
Date: Fri, 14 Jun 2019 11:13:54 +0200
b58328
Subject: [PATCH] extdom: unify error code handling especially
b58328
 LDAP_NO_SUCH_OBJECT
b58328
b58328
A return code LDAP_NO_SUCH_OBJECT will tell SSSD on the IPA client to
b58328
remove the searched object from the cache. As a consequence
b58328
LDAP_NO_SUCH_OBJECT should only be returned if the object really does
b58328
not exists otherwise the data of existing objects might be removed form
b58328
the cache of the clients causing unexpected behaviour like
b58328
authentication errors.
b58328
b58328
Currently some code-paths use LDAP_NO_SUCH_OBJECT as default error code.
b58328
With this patch LDAP_NO_SUCH_OBJECT is only returned if the related
b58328
lookup functions return ENOENT. Timeout related error code will lead to
b58328
LDAP_TIMELIMIT_EXCEEDED and LDAP_OPERATIONS_ERROR is used as default
b58328
error code.
b58328
b58328
Fixes: https://pagure.io/freeipa/issue/8044
b58328
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
b58328
---
b58328
 .../ipa-extdom-extop/back_extdom_sss_idmap.c  |  4 +-
b58328
 .../ipa-extdom-extop/ipa_extdom_common.c      | 77 ++++++++++++++-----
b58328
 .../ipa-extdom-extop/ipa_extdom_extop.c       |  2 +
b58328
 3 files changed, 61 insertions(+), 22 deletions(-)
b58328
b58328
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_sss_idmap.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_sss_idmap.c
b58328
index 89c58ca2de333b26954d916836b57aed5d7e18fb..64b90e3ae8abc40edaaed91601cdded30db35294 100644
b58328
--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_sss_idmap.c
b58328
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_sss_idmap.c
b58328
@@ -47,10 +47,10 @@ static enum nss_status __convert_sss_nss2nss_status(int errcode) {
b58328
         return NSS_STATUS_SUCCESS;
b58328
     case ENOENT:
b58328
         return NSS_STATUS_NOTFOUND;
b58328
-    case ETIME:
b58328
-        /* fall-through */
b58328
     case ERANGE:
b58328
         return NSS_STATUS_TRYAGAIN;
b58328
+    case ETIME:
b58328
+        /* fall-through */
b58328
     case ETIMEDOUT:
b58328
         /* fall-through */
b58328
     default:
b58328
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
b58328
index 1b93dce18671756fe9019378ce61e556697ad902..134b623773df418dc47edaf67045e5f4cfff9782 100644
b58328
--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
b58328
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
b58328
@@ -523,7 +523,7 @@ int pack_ber_user(struct ipa_extdom_ctx *ctx,
b58328
         if (strcasecmp(locat+1, domain_name) == 0  ) {
b58328
             locat[0] = '\0';
b58328
         } else {
b58328
-            ret = LDAP_NO_SUCH_OBJECT;
b58328
+            ret = LDAP_INVALID_SYNTAX;
b58328
             goto done;
b58328
         }
b58328
     }
b58328
@@ -568,10 +568,12 @@ int pack_ber_user(struct ipa_extdom_ctx *ctx,
b58328
             ret = getgrgid_r_wrapper(ctx,
b58328
                                      groups[c], &grp, &buf, &buf_len);
b58328
             if (ret != 0) {
b58328
-                if (ret == ENOMEM || ret == ERANGE) {
b58328
-                    ret = LDAP_OPERATIONS_ERROR;
b58328
-                } else {
b58328
+                if (ret == ENOENT) {
b58328
                     ret = LDAP_NO_SUCH_OBJECT;
b58328
+                } else if (ret == ETIMEDOUT) {
b58328
+                    ret = LDAP_TIMELIMIT_EXCEEDED;
b58328
+                } else {
b58328
+                    ret = LDAP_OPERATIONS_ERROR;
b58328
                 }
b58328
                 goto done;
b58328
             }
b58328
@@ -634,7 +636,7 @@ int pack_ber_group(enum response_types response_type,
b58328
         if (strcasecmp(locat+1, domain_name) == 0  ) {
b58328
             locat[0] = '\0';
b58328
         } else {
b58328
-            ret = LDAP_NO_SUCH_OBJECT;
b58328
+            ret = LDAP_INVALID_SYNTAX;
b58328
             goto done;
b58328
         }
b58328
     }
b58328
@@ -836,6 +838,8 @@ static int handle_uid_request(struct ipa_extdom_ctx *ctx,
b58328
                             || id_type == SSS_ID_TYPE_BOTH)) {
b58328
             if (ret == ENOENT) {
b58328
                 ret = LDAP_NO_SUCH_OBJECT;
b58328
+            } else if (ret == ETIMEDOUT || ret == ETIME) {
b58328
+                ret = LDAP_TIMELIMIT_EXCEEDED;
b58328
             } else {
b58328
                 set_err_msg(req, "Failed to lookup SID by UID");
b58328
                 ret = LDAP_OPERATIONS_ERROR;
b58328
@@ -847,10 +851,12 @@ static int handle_uid_request(struct ipa_extdom_ctx *ctx,
b58328
     } else {
b58328
         ret = getpwuid_r_wrapper(ctx, uid, &pwd, &buf, &buf_len);
b58328
         if (ret != 0) {
b58328
-            if (ret == ENOMEM || ret == ERANGE) {
b58328
-                ret = LDAP_OPERATIONS_ERROR;
b58328
-            } else {
b58328
+            if (ret == ENOENT) {
b58328
                 ret = LDAP_NO_SUCH_OBJECT;
b58328
+            } else if (ret == ETIMEDOUT) {
b58328
+                ret = LDAP_TIMELIMIT_EXCEEDED;
b58328
+            } else {
b58328
+                ret = LDAP_OPERATIONS_ERROR;
b58328
             }
b58328
             goto done;
b58328
         }
b58328
@@ -862,6 +868,8 @@ static int handle_uid_request(struct ipa_extdom_ctx *ctx,
b58328
                 set_err_msg(req, "Failed to read original data");
b58328
                 if (ret == ENOENT) {
b58328
                     ret = LDAP_NO_SUCH_OBJECT;
b58328
+                } else if (ret == ETIMEDOUT || ret == ETIME) {
b58328
+                    ret = LDAP_TIMELIMIT_EXCEEDED;
b58328
                 } else {
b58328
                     ret = LDAP_OPERATIONS_ERROR;
b58328
                 }
b58328
@@ -907,6 +915,8 @@ static int handle_gid_request(struct ipa_extdom_ctx *ctx,
b58328
         if (ret != 0 || id_type != SSS_ID_TYPE_GID) {
b58328
             if (ret == ENOENT) {
b58328
                 ret = LDAP_NO_SUCH_OBJECT;
b58328
+            } else if (ret == ETIMEDOUT || ret == ETIME) {
b58328
+                ret = LDAP_TIMELIMIT_EXCEEDED;
b58328
             } else {
b58328
                 set_err_msg(req, "Failed to lookup SID by GID");
b58328
                 ret = LDAP_OPERATIONS_ERROR;
b58328
@@ -918,10 +928,12 @@ static int handle_gid_request(struct ipa_extdom_ctx *ctx,
b58328
     } else {
b58328
         ret = getgrgid_r_wrapper(ctx, gid, &grp, &buf, &buf_len);
b58328
         if (ret != 0) {
b58328
-            if (ret == ENOMEM || ret == ERANGE) {
b58328
-                ret = LDAP_OPERATIONS_ERROR;
b58328
-            } else {
b58328
+            if (ret == ENOENT) {
b58328
                 ret = LDAP_NO_SUCH_OBJECT;
b58328
+            } else if (ret == ETIMEDOUT) {
b58328
+                ret = LDAP_TIMELIMIT_EXCEEDED;
b58328
+            } else {
b58328
+                ret = LDAP_OPERATIONS_ERROR;
b58328
             }
b58328
             goto done;
b58328
         }
b58328
@@ -933,6 +945,8 @@ static int handle_gid_request(struct ipa_extdom_ctx *ctx,
b58328
                 set_err_msg(req, "Failed to read original data");
b58328
                 if (ret == ENOENT) {
b58328
                     ret = LDAP_NO_SUCH_OBJECT;
b58328
+                } else if (ret == ETIMEDOUT || ret == ETIME) {
b58328
+                    ret = LDAP_TIMELIMIT_EXCEEDED;
b58328
                 } else {
b58328
                     ret = LDAP_OPERATIONS_ERROR;
b58328
                 }
b58328
@@ -976,6 +990,8 @@ static int handle_cert_request(struct ipa_extdom_ctx *ctx,
b58328
     if (ret != 0) {
b58328
         if (ret == ENOENT) {
b58328
             ret = LDAP_NO_SUCH_OBJECT;
b58328
+        } else if (ret == ETIMEDOUT || ret == ETIME) {
b58328
+            ret = LDAP_TIMELIMIT_EXCEEDED;
b58328
         } else {
b58328
             set_err_msg(req, "Failed to lookup name by certificate");
b58328
             ret = LDAP_OPERATIONS_ERROR;
b58328
@@ -1020,6 +1036,8 @@ static int handle_sid_request(struct ipa_extdom_ctx *ctx,
b58328
     if (ret != 0) {
b58328
         if (ret == ENOENT) {
b58328
             ret = LDAP_NO_SUCH_OBJECT;
b58328
+        } else if (ret == ETIMEDOUT || ret == ETIME) {
b58328
+            ret = LDAP_TIMELIMIT_EXCEEDED;
b58328
         } else {
b58328
             set_err_msg(req, "Failed to lookup name by SID");
b58328
             ret = LDAP_OPERATIONS_ERROR;
b58328
@@ -1057,10 +1075,12 @@ static int handle_sid_request(struct ipa_extdom_ctx *ctx,
b58328
     case SSS_ID_TYPE_BOTH:
b58328
         ret = getpwnam_r_wrapper(ctx, fq_name, &pwd, &buf, &buf_len);
b58328
         if (ret != 0) {
b58328
-            if (ret == ENOMEM || ret == ERANGE) {
b58328
-                ret = LDAP_OPERATIONS_ERROR;
b58328
-            } else {
b58328
+            if (ret == ENOENT) {
b58328
                 ret = LDAP_NO_SUCH_OBJECT;
b58328
+            } else if (ret == ETIMEDOUT) {
b58328
+                ret = LDAP_TIMELIMIT_EXCEEDED;
b58328
+            } else {
b58328
+                ret = LDAP_OPERATIONS_ERROR;
b58328
             }
b58328
             goto done;
b58328
         }
b58328
@@ -1072,6 +1092,8 @@ static int handle_sid_request(struct ipa_extdom_ctx *ctx,
b58328
                 set_err_msg(req, "Failed to read original data");
b58328
                 if (ret == ENOENT) {
b58328
                     ret = LDAP_NO_SUCH_OBJECT;
b58328
+                } else if (ret == ETIMEDOUT || ret == ETIME) {
b58328
+                    ret = LDAP_TIMELIMIT_EXCEEDED;
b58328
                 } else {
b58328
                     ret = LDAP_OPERATIONS_ERROR;
b58328
                 }
b58328
@@ -1089,10 +1111,12 @@ static int handle_sid_request(struct ipa_extdom_ctx *ctx,
b58328
     case SSS_ID_TYPE_GID:
b58328
         ret = getgrnam_r_wrapper(ctx, fq_name, &grp, &buf, &buf_len);
b58328
         if (ret != 0) {
b58328
-            if (ret == ENOMEM || ret == ERANGE) {
b58328
-                ret = LDAP_OPERATIONS_ERROR;
b58328
-            } else {
b58328
+            if (ret == ENOENT) {
b58328
                 ret = LDAP_NO_SUCH_OBJECT;
b58328
+            } else if (ret == ETIMEDOUT) {
b58328
+                ret = LDAP_TIMELIMIT_EXCEEDED;
b58328
+            } else {
b58328
+                ret = LDAP_OPERATIONS_ERROR;
b58328
             }
b58328
             goto done;
b58328
         }
b58328
@@ -1104,6 +1128,8 @@ static int handle_sid_request(struct ipa_extdom_ctx *ctx,
b58328
                 set_err_msg(req, "Failed to read original data");
b58328
                 if (ret == ENOENT) {
b58328
                     ret = LDAP_NO_SUCH_OBJECT;
b58328
+                } else if (ret == ETIMEDOUT || ret == ETIME) {
b58328
+                    ret = LDAP_TIMELIMIT_EXCEEDED;
b58328
                 } else {
b58328
                     ret = LDAP_OPERATIONS_ERROR;
b58328
                 }
b58328
@@ -1167,6 +1193,8 @@ static int handle_name_request(struct ipa_extdom_ctx *ctx,
b58328
         if (ret != 0) {
b58328
             if (ret == ENOENT) {
b58328
                 ret = LDAP_NO_SUCH_OBJECT;
b58328
+            } else if (ret == ETIMEDOUT || ret == ETIME) {
b58328
+                ret = LDAP_TIMELIMIT_EXCEEDED;
b58328
             } else {
b58328
                 set_err_msg(req, "Failed to lookup SID by name");
b58328
                 ret = LDAP_OPERATIONS_ERROR;
b58328
@@ -1190,6 +1218,8 @@ static int handle_name_request(struct ipa_extdom_ctx *ctx,
b58328
                     set_err_msg(req, "Failed to read original data");
b58328
                     if (ret == ENOENT) {
b58328
                         ret = LDAP_NO_SUCH_OBJECT;
b58328
+                    } else if (ret == ETIMEDOUT || ret == ETIME) {
b58328
+                        ret = LDAP_TIMELIMIT_EXCEEDED;
b58328
                     } else {
b58328
                         ret = LDAP_OPERATIONS_ERROR;
b58328
                     }
b58328
@@ -1205,6 +1235,9 @@ static int handle_name_request(struct ipa_extdom_ctx *ctx,
b58328
         } else if (ret == ENOMEM || ret == ERANGE) {
b58328
             ret = LDAP_OPERATIONS_ERROR;
b58328
             goto done;
b58328
+        } else if (ret == ETIMEDOUT) {
b58328
+            ret = LDAP_TIMELIMIT_EXCEEDED;
b58328
+            goto done;
b58328
         } else { /* no user entry found */
b58328
             /* according to the getpwnam() man page there are a couple of
b58328
              * error codes which can indicate that the user was not found. To
b58328
@@ -1212,10 +1245,12 @@ static int handle_name_request(struct ipa_extdom_ctx *ctx,
b58328
              * errors. */
b58328
             ret = getgrnam_r_wrapper(ctx, fq_name, &grp, &buf, &buf_len);
b58328
             if (ret != 0) {
b58328
-                if (ret == ENOMEM || ret == ERANGE) {
b58328
-                    ret = LDAP_OPERATIONS_ERROR;
b58328
-                } else {
b58328
+                if (ret == ENOENT) {
b58328
                     ret = LDAP_NO_SUCH_OBJECT;
b58328
+                } else if (ret == ETIMEDOUT) {
b58328
+                    ret = LDAP_TIMELIMIT_EXCEEDED;
b58328
+                } else {
b58328
+                    ret = LDAP_OPERATIONS_ERROR;
b58328
                 }
b58328
                 goto done;
b58328
             }
b58328
@@ -1226,6 +1261,8 @@ static int handle_name_request(struct ipa_extdom_ctx *ctx,
b58328
                                     || id_type == SSS_ID_TYPE_BOTH)) {
b58328
                     if (ret == ENOENT) {
b58328
                         ret = LDAP_NO_SUCH_OBJECT;
b58328
+                    } else if (ret == ETIMEDOUT || ret == ETIME) {
b58328
+                        ret = LDAP_TIMELIMIT_EXCEEDED;
b58328
                     } else {
b58328
                         set_err_msg(req, "Failed to read original data");
b58328
                         ret = LDAP_OPERATIONS_ERROR;
b58328
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c
b58328
index 10d3f86ebad920fb9c051aa428cbd675b682f14a..48fcecc1eeb8f2ad6a3bc8791fe94f4ed54fe74d 100644
b58328
--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c
b58328
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c
b58328
@@ -242,6 +242,8 @@ static int ipa_extdom_extop(Slapi_PBlock *pb)
b58328
     if (ret != LDAP_SUCCESS) {
b58328
         if (ret == LDAP_NO_SUCH_OBJECT) {
b58328
             rc = LDAP_NO_SUCH_OBJECT;
b58328
+        } else if (ret == LDAP_TIMELIMIT_EXCEEDED) {
b58328
+            rc = LDAP_TIMELIMIT_EXCEEDED;
b58328
         } else {
b58328
             rc = LDAP_OPERATIONS_ERROR;
b58328
             err_msg = "Failed to handle the request.\n";
b58328
-- 
b58328
2.23.0
b58328