Author: mkhl
Date: 2006-06-24 22:58:04 +0000 (Sat, 24 Jun 2006)
New Revision: 16506

WebSVN: 
http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=16506

Log:
Add local search callback.

Martin

Modified:
   branches/SOC/mkhl/ldb-map/modules/ldb_map.c


Changeset:
Modified: branches/SOC/mkhl/ldb-map/modules/ldb_map.c
===================================================================
--- branches/SOC/mkhl/ldb-map/modules/ldb_map.c 2006-06-24 22:00:52 UTC (rev 
16505)
+++ branches/SOC/mkhl/ldb-map/modules/ldb_map.c 2006-06-24 22:58:04 UTC (rev 
16506)
@@ -1426,6 +1426,7 @@
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
+       /* extract remote DN */
        ac->search_res = talloc_steal(ac, ares);
        ac->remote_dn = ldb_dn_explode(ac,
                                       ldb_msg_find_string(ares->message,
@@ -1434,16 +1435,15 @@
        return LDB_SUCCESS;
 }
 
+
 /* create request that searches for DN */
 static
 struct ldb_request *
-search_self_req(struct map_async_context *ac,
-               const struct ldb_dn *dn)
+search_base_req(struct map_async_context *ac,
+               const struct ldb_dn *dn,
+               const char * const *attrs,
+               int (*callback)(struct ldb_context *, void *, struct 
ldb_async_result *))
 {
-       /* attrs[] is returned from this function in
-          ac->search_req->op.search.attrs, so it must be static, as
-          otherwise the compiler can put it on the stack */
-       static const char * const attrs[] = { IS_MAPPED, NULL };
        struct ldb_request *req;
 
        req = talloc_zero(ac, struct ldb_request);
@@ -1465,50 +1465,96 @@
 
        req->controls = NULL;
        req->async.context = ac;
-       req->async.callback = search_self_callback;
+       req->async.callback = callback;
        ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, req);
 
        return req;
 }
 
+/* create request that searches for 'IS_MAPPED' in DN */
 static
+struct ldb_request *
+search_self_req(struct map_async_context *ac,
+               const struct ldb_dn *dn)
+{
+       /* attrs[] is returned from this function in
+          ac->search_req->op.search.attrs, so it must be static, as
+          otherwise the compiler can put it on the stack */
+       static const char * const attrs[] = { IS_MAPPED, NULL };
+
+       return search_base_req(ac, dn, attrs, search_self_callback);
+}
+
+/* merge remote record with associated local record */
+static
 int
+remote_search_callback(struct ldb_context *ldb,
+                      void *context,
+                      struct ldb_async_result *ares)
+{
+       return LDB_SUCCESS;
+}
+
+/* for each result, search associated remote record */
+static
+int
 local_search_callback(struct ldb_context *ldb,
                      void *context,
                      struct ldb_async_result *ares)
 {
+       struct map_async_context *ac;
        struct map_async_search_context *sc;
+       struct ldb_request *req;
+       struct ldb_dn *dn;
 
        if (context == NULL || ares == NULL) {
                ldb_set_errstring(ldb, talloc_asprintf(ldb, "NULL Context or 
Result in callback"));
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
-       sc = talloc_get_type(context, struct map_async_search_context);
+       ac = talloc_get_type(context, struct map_async_context);
 
-       switch (ares->type) {
-       case LDB_REPLY_ENTRY:
-               /* we already have a local result */
-               if (sc->local_res != NULL) {
-                       ldb_set_errstring(ldb,
-                                         talloc_asprintf(ldb,
-                                                         "Too many results"));
-                       talloc_free(ares);
-                       return LDB_ERR_OPERATIONS_ERROR;
-               }
+       /* stop searching if it's not a record */
+       if (ares->type != LDB_REPLY_ENTRY)
+               return ac->orig_req->
+                       async.callback(ldb, ac->orig_req->async.context, ares);
 
-               sc->local_res = talloc_steal(sc, ares);
+       /* stop searching if it's not mapped */
+       if (!ldb_msg_find_element(ares->message, IS_MAPPED))
+               return ac->orig_req->
+                       async.callback(ldb, ac->orig_req->async.context, ares);
 
-               /* don't return the 'IS_MAPPED' attribute */
-               ldb_msg_remove_attr(ares->message, IS_MAPPED);
+       /* extract remote DN */
+       dn = ldb_dn_explode(ac, ldb_msg_find_string(ares->message,
+                                                   IS_MAPPED, NULL));
+       if (dn == NULL)
+               goto error;
+       ldb_msg_remove_attr(ares->message, IS_MAPPED);
+       ac->remote_dn = dn;
 
-               /* XXX: ... */
-               
-       default:
-               talloc_free(ares);
-               ldb_set_errstring(ldb, talloc_asprintf(ldb, "Unexpected result 
type in search for local record"));
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
+       /* prepare remote operation */
+       req = talloc_zero(ac, struct ldb_request);
+       if (req == NULL)
+               goto error;
+
+       sc = talloc(ac, struct map_async_search_context);
+       if (sc == NULL)
+               goto error;
+
+       sc->ac = ac;
+       sc->local_res = ares;   /* TODO: steal? */
+       sc->remote_res = NULL;
+
+       /* TODO: replace NULL with remote attrs! */
+       req = search_base_req(ac, dn, NULL, remote_search_callback);
+       if (req == NULL)
+               goto error;
+
+       return ldb_next_remote_request(ac->module, req);
+
+error:
+       talloc_free(ares);
+       return LDB_ERR_OPERATIONS_ERROR;
 }
 
 
@@ -1760,7 +1806,8 @@
        ac->local_req->async.context = ac;
        ac->local_req->async.callback = local_search_callback;
 
-       /* XXX: ... */
+       /* TODO: separate local and remote attrs
+          maybe even store them in context */
 
        ac->local_req->op.search.attrs = local_attrs;
 

Reply via email to