>From 808a4b88621755e61efd1506f8f3877844f6a16d Mon Sep 17 00:00:00 2001
From: Simo Sorce <ssorce@redhat.com>
Date: Wed, 12 Aug 2009 14:03:26 -0400
Subject: [PATCH 4/7] Do not fail enumerations if a single store fails

Try as hard as possible to store as much data as we can.
---
 server/providers/ldap/sdap_async.c |   77 ++++++++++++++++++------------------
 1 files changed, 39 insertions(+), 38 deletions(-)

diff --git a/server/providers/ldap/sdap_async.c b/server/providers/ldap/sdap_async.c
index 7c6cd2c..a1db251 100644
--- a/server/providers/ldap/sdap_async.c
+++ b/server/providers/ldap/sdap_async.c
@@ -69,7 +69,7 @@ static int sdap_handle_destructor(void *mem)
     return 0;
 }
 
-static inline void sdap_handle_release(struct sdap_handle *sh)
+static void sdap_handle_release(struct sdap_handle *sh)
 {
     DEBUG(8, ("Trace: sh[%p], connected[%d], ops[%p], fde[%p], ldap[%p]\n",
               sh, (int)sh->connected, sh->ops, sh->fde, sh->ldap));
@@ -812,6 +812,7 @@ struct sdap_save_user_state {
 
     struct sss_domain_info *dom;
 
+    const char *name;
     struct sysdb_attrs *attrs;
 };
 
@@ -832,7 +833,6 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
     struct sdap_save_user_state *state;
     struct ldb_message_element *el;
     int ret;
-    const char *name;
     const char *pwd;
     const char *gecos;
     const char *homedir;
@@ -862,7 +862,7 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
         ret = EINVAL;
         goto fail;
     }
-    name = (const char *)el->values[0].data;
+    state->name = (const char *)el->values[0].data;
 
     ret = sysdb_attrs_get_el(state->attrs,
                              opts->user_map[SDAP_AT_USER_PWD].sys_name, &el);
@@ -892,8 +892,8 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
                              opts->user_map[SDAP_AT_USER_UID].sys_name, &el);
     if (ret) goto fail;
     if (el->num_values == 0) {
-        DEBUG(1, ("no uid provided for user [%s] in domain [%s].\n", name,
-                  dom->name));
+        DEBUG(1, ("no uid provided for [%s] in domain [%s].\n",
+                  state->name, dom->name));
         ret = EINVAL;
         goto fail;
     }
@@ -909,8 +909,8 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
                              opts->user_map[SDAP_AT_USER_GID].sys_name, &el);
     if (ret) goto fail;
     if (el->num_values == 0) {
-        DEBUG(1, ("no gid provided for user [%s] in domain [%s].\n", name,
-                  dom->name));
+        DEBUG(1, ("no gid provided for [%s] in domain [%s].\n",
+                  state->name, dom->name));
         ret = EINVAL;
         goto fail;
     }
@@ -933,10 +933,10 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
         goto fail;
     }
     if (el->num_values == 0) {
-        DEBUG(7, ("Original DN is not available for user [%s].\n", name));
+        DEBUG(7, ("Original DN is not available for [%s].\n", state->name));
     } else {
         DEBUG(7, ("Adding original DN [%s] to attributes of user [%s].\n",
-                  el->values[0].data, name));
+                  el->values[0].data, state->name));
         ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_DN,
                                      (const char *) el->values[0].data);
         if (ret) {
@@ -950,10 +950,10 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
         goto fail;
     }
     if (el->num_values == 0) {
-        DEBUG(7, ("User principle is not available for user [%s].\n", name));
+        DEBUG(7, ("User principle is not available for [%s].\n", state->name));
     } else {
         DEBUG(7, ("Adding user principle [%s] to attributes of user [%s].\n",
-                  el->values[0].data, name));
+                  el->values[0].data, state->name));
         ret = sysdb_attrs_add_string(user_attrs, SYSDB_UPN,
                                      (const char *) el->values[0].data);
         if (ret) {
@@ -961,11 +961,11 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
         }
     }
 
-    DEBUG(6, ("Storing info for user %s\n", name));
+    DEBUG(6, ("Storing info for user %s\n", state->name));
 
     subreq = sysdb_store_user_with_attrs_send(state, state->ev, state->handle,
-                                              state->dom, name, pwd, uid, gid,
-                                              gecos, homedir, shell,
+                                              state->dom, state->name, pwd,
+                                              uid, gid, gecos, homedir, shell,
                                               user_attrs);
     if (!subreq) {
         ret = ENOMEM;
@@ -985,11 +985,14 @@ static void sdap_save_user_done(struct tevent_req *subreq)
 {
     struct tevent_req *req = tevent_req_callback_data(subreq,
                                                       struct tevent_req);
+    struct sdap_save_user_state *state = tevent_req_data(req,
+                                            struct sdap_save_user_state);
     int ret;
 
     ret = sysdb_store_user_with_attrs_recv(subreq);
     talloc_zfree(subreq);
     if (ret) {
+        DEBUG(2, ("Failed to save user %s\n", state->name));
         tevent_req_error(req, ret);
         return;
     }
@@ -1021,6 +1024,7 @@ struct sdap_save_group_state {
 
     struct sss_domain_info *dom;
 
+    const char *name;
     struct sysdb_attrs *attrs;
 };
 
@@ -1041,7 +1045,6 @@ static struct tevent_req *sdap_save_group_send(TALLOC_CTX *memctx,
     struct sdap_save_group_state *state;
     struct ldb_message_element *el;
     int i, ret;
-    char *name;
     const char **members;
     long int l;
     gid_t gid;
@@ -1066,7 +1069,7 @@ static struct tevent_req *sdap_save_group_send(TALLOC_CTX *memctx,
         ret = EINVAL;
         goto fail;
     }
-    name = (char *)el->values[0].data;
+    state->name = (const char *)el->values[0].data;
 
     ret = sysdb_attrs_get_el(state->attrs,
                           opts->group_map[SDAP_AT_GROUP_MEMBER].sys_name, &el);
@@ -1095,10 +1098,10 @@ static struct tevent_req *sdap_save_group_send(TALLOC_CTX *memctx,
     }
     gid = l;
 
-    DEBUG(6, ("Storing info for group %s\n", name));
+    DEBUG(6, ("Storing info for group %s\n", state->name));
 
     subreq = sysdb_store_group_send(state, state->ev, state->handle,
-                                    state->dom, name, gid, members);
+                                    state->dom, state->name, gid, members);
     if (!subreq) {
         ret = ENOMEM;
         goto fail;
@@ -1117,11 +1120,14 @@ static void sdap_save_group_done(struct tevent_req *subreq)
 {
     struct tevent_req *req = tevent_req_callback_data(subreq,
                                                       struct tevent_req);
+    struct sdap_save_group_state *state = tevent_req_data(req,
+                                            struct sdap_save_group_state);
     int ret;
 
     ret = sysdb_store_group_recv(subreq);
     talloc_zfree(subreq);
     if (ret) {
+        DEBUG(2, ("Failed to save group %s\n", state->name));
         tevent_req_error(req, ret);
         return;
     }
@@ -1315,12 +1321,10 @@ static void sdap_get_users_save_done(struct tevent_req *subreq)
     ret = sdap_save_user_recv(subreq);
     talloc_zfree(subreq);
 
-    /* If the configuration has id ranges and the remote user is out
-     * of these ranges we will get back an ERANGE error. In this case
-     * we just ignore the error and go on with the next op */
-    if (ret && (ret != ERANGE)) {
-        tevent_req_error(req, ret);
-        return;
+    /* Do not fail completely on errors.
+     * Just report the failure to save and go on */
+    if (ret) {
+        DEBUG(2, ("Failed to store user. Ignoring.\n"));
     }
 
     /* unlock the operation so that we can proceed with the next result */
@@ -1457,8 +1461,8 @@ static void sdap_get_groups_done(struct sdap_op *op,
     case LDAP_RES_SEARCH_ENTRY:
 
         subreq = sdap_save_group_send(state, state->ev, state->handle,
-                                     state->opts, state->dom,
-                                     state->sh, reply);
+                                      state->opts, state->dom,
+                                      state->sh, reply);
         if (!subreq) {
             tevent_req_error(req, ENOMEM);
             return;
@@ -1512,12 +1516,11 @@ static void sdap_get_groups_save_done(struct tevent_req *subreq)
     ret = sdap_save_group_recv(subreq);
     talloc_zfree(subreq);
 
-    /* If the configuration has id ranges and the remote user is out
-     * of these ranges we will get back an ERANGE error. In this case
-     * we just ignore the error and go on with the next op */
-    if (ret && (ret != ERANGE)) {
-        tevent_req_error(req, ret);
-        return;
+    /* Do not fail completely on errors.
+     * Just report the failure to save and go on */
+
+    if (ret) {
+        DEBUG(2, ("Failed to store group. Ignoring.\n"));
     }
 
     /* unlock the operation so that we can proceed with the next result */
@@ -1820,12 +1823,10 @@ static void sdap_get_initgr_save_done(struct tevent_req *subreq)
     ret = sdap_save_group_recv(subreq);
     talloc_zfree(subreq);
 
-    /* If the configuration has id ranges and the remote user is out
-     * of these ranges we will get back an ERANGE error. In this case
-     * we just ignore the error and go on with the next op */
-    if (ret && (ret != ERANGE)) {
-        tevent_req_error(req, ret);
-        return;
+    /* Do not fail completely on errors.
+     * Just report the failure to save and go on */
+    if (ret) {
+        DEBUG(2, ("Failed to store group. Ignoring.\n"));
     }
 
     /* unlock the operation so that we can proceed with the next result */
-- 
1.6.2.5

