svn commit: samba r16505 - in branches/SOC/mkhl/ldb-map/modules: .
mkhl at samba.org
mkhl at samba.org
Sat Jun 24 22:00:53 GMT 2006
Author: mkhl
Date: 2006-06-24 22:00:52 +0000 (Sat, 24 Jun 2006)
New Revision: 16505
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=16505
Log:
Check incoming DN before performing mappings.
Add chunks of searching boilerplate.
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 20:38:38 UTC (rev 16504)
+++ branches/SOC/mkhl/ldb-map/modules/ldb_map.c 2006-06-24 22:00:52 UTC (rev 16505)
@@ -1,25 +1,25 @@
/*
- ldb database library - map backend
+ Mapping ldb module
Copyright (C) Jelmer Vernooij 2005
- ** NOTE! The following LGPL license applies to the ldb
- ** library. This does NOT imply that all of Samba is released
- ** under the LGPL
+ * NOTICE: this module is NOT released under the GNU LGPL license as
+ * other ldb code. This module is release under the GNU GPL v2 or
+ * later license.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
@@ -27,7 +27,7 @@
*
* Component: ldb ldb_map module
*
- * Description: ...
+ * Description: Map portions of data into a different format on a remote partition.
*
* Author: Jelmer Vernooij, Martin Kuehl
*/
@@ -57,7 +57,7 @@
#define map_oom(module) ldb_set_errstring(module->ldb, talloc_asprintf(module, "Out of Memory"));
-/* Private data */
+/* private data */
struct map_private {
struct ldb_map_context context;
};
@@ -73,9 +73,11 @@
}
-/* Async context data */
+/* async context data */
struct map_async_context {
enum map_step {
+ MAP_SEARCH_LOCAL,
+ MAP_SEARCH_REMOTE,
MAP_DO_ADD_REMOTE,
MAP_DO_ADD_LOCAL,
MAP_SEARCH_SELF_MODIFY,
@@ -87,7 +89,7 @@
MAP_SEARCH_SELF_RENAME,
MAP_DO_RENAME_REMOTE,
MAP_DO_RENAME_FIXUP,
- MAP_DO_RENAME_LOCAL,
+ MAP_DO_RENAME_LOCAL
} step;
struct ldb_module *module;
@@ -104,6 +106,13 @@
struct ldb_async_result *search_res;
};
+/* async context data for searches */
+struct map_async_search_context {
+ struct map_async_context *ac;
+ struct ldb_async_result *local_res;
+ struct ldb_async_result *remote_res;
+};
+
/* create async context and handle */
static
struct ldb_async_handle *
@@ -191,7 +200,7 @@
return new;
}
-#define MAP_DN_REBASE(dn) dn = ldb_dn_rebase(request, dn, map->local_base_dn, map->remote_base_dn)
+#define MAP_DN_REBASE(dn) dn = ldb_dn_rebase(request, dn, data->local_base_dn, data->remote_base_dn)
/* run request in the remote partition */
static
@@ -199,7 +208,7 @@
ldb_next_remote_request(struct ldb_module *module,
struct ldb_request *request)
{
- struct ldb_map_context *map = map_get_privdat(module);
+ struct ldb_map_context *data = map_get_privdat(module);
struct ldb_message *msg;
switch (request->operation) {
@@ -315,24 +324,71 @@
}
-/* Checking ldb_messages */
+/* Checking ... stuff */
+/* True if dn is below the local baseDN */
static
-int
-check_msg_is_mapped(struct ldb_module *module,
- const struct ldb_message *msg)
+BOOL
+check_dn_local(struct ldb_module *module,
+ const struct ldb_dn *dn)
{
struct ldb_map_context *data = map_get_privdat(module);
+
+ return ldb_dn_compare_base(module->ldb, data->local_base_dn, dn) == 0;
+}
+
+/* True if attr has an associated mapping that does not ignore it */
+static
+BOOL
+check_attr_mapped(struct ldb_map_context *data,
+ const char* attr)
+{
struct ldb_map_attribute *map;
+
+ map = find_attr_local(data, attr);
+ if (map == NULL)
+ return False;
+ if (map->type == MAP_IGNORE)
+ return False;
+ return True;
+}
+
+/* True if any of attrs is mapped */
+static
+BOOL
+check_attrs_mapped(struct ldb_module *module,
+ const char * const *attrs)
+{
+ struct ldb_map_context *data = map_get_privdat(module);
+ BOOL ret;
int i;
+ for (i = 0; attrs[i]; i++) {
+ ret = check_attr_mapped(data, attrs[i]);
+ if (ret)
+ return ret;
+ }
+
+ return False;
+}
+
+/* True if any of the message elements is mapped */
+static
+BOOL
+check_msg_mapped(struct ldb_module *module,
+ const struct ldb_message *msg)
+{
+ struct ldb_map_context *data = map_get_privdat(module);
+ BOOL ret;
+ int i;
+
for (i = 0; i < msg->num_elements; i++) {
- map = find_attr_local(data, msg->elements[i].name);
- if (map && map->type != MAP_IGNORE)
- return 1;
+ ret = check_attr_mapped(data, msg->elements[i].name);
+ if (ret)
+ return ret;
}
- return 0;
+ return False;
}
/* Check whether the given objectClass is contained in the specified
@@ -1340,11 +1396,12 @@
}
+/* store single search result in async context */
static
int
-get_self_callback(struct ldb_context *ldb,
- void *context,
- struct ldb_async_result *ares)
+search_self_callback(struct ldb_context *ldb,
+ void *context,
+ struct ldb_async_result *ares)
{
struct map_async_context *ac;
@@ -1361,7 +1418,8 @@
return LDB_SUCCESS;
}
- if (ac->remote_dn != NULL) {
+ /* we already have a remote DN */
+ if (ac->remote_dn) {
ldb_set_errstring(ldb,
talloc_asprintf(ldb, "Too many results"));
talloc_free(ares);
@@ -1369,17 +1427,18 @@
}
ac->search_res = talloc_steal(ac, ares);
- ac->remote_dn
- = ldb_dn_explode(ac, ldb_msg_find_string(ares->message,
- IS_MAPPED, NULL));
+ ac->remote_dn = ldb_dn_explode(ac,
+ ldb_msg_find_string(ares->message,
+ IS_MAPPED, NULL));
return LDB_SUCCESS;
}
+/* create request that searches for DN */
static
struct ldb_request *
-build_self_req(struct map_async_context *ac,
- const struct ldb_dn *dn)
+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
@@ -1406,13 +1465,53 @@
req->controls = NULL;
req->async.context = ac;
- req->async.callback = get_self_callback;
+ req->async.callback = search_self_callback;
ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, req);
return req;
}
+static
+int
+local_search_callback(struct ldb_context *ldb,
+ void *context,
+ struct ldb_async_result *ares)
+{
+ struct map_async_search_context *sc;
+ 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);
+
+ 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;
+ }
+
+ sc->local_res = talloc_steal(sc, ares);
+
+ /* don't return the 'IS_MAPPED' attribute */
+ ldb_msg_remove_attr(ares->message, IS_MAPPED);
+
+ /* 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;
+ }
+}
+
+
/* Handling LDB requests */
/* /\* Search fallback database *\/ */
@@ -1612,6 +1711,73 @@
/* } */
+/* Search a record */
+static
+int
+map_search(struct ldb_module *module,
+ struct ldb_request *req)
+{
+ struct ldb_async_handle *h;
+ struct map_async_context *ac;
+ const char * const *local_attrs;
+ int ret;
+
+ /* do not manipulate our control entries */
+ if (ldb_dn_is_special(req->op.search.base))
+ return ldb_next_request(module, req);
+
+ /* no mapping requested, skip to next module */
+ if (!check_dn_local(module, req->op.search.base))
+ return ldb_next_request(module, req);
+
+ /* no mapping needed, skip to next module */
+ if (req->op.search.attrs
+ && (!ldb_attr_in_list(req->op.search.attrs, "*"))
+ && (!check_attrs_mapped(module, req->op.search.attrs)))
+ return ldb_next_request(module, req);
+
+ /* prepare async context and handle */
+ h = map_init_handle(req, module);
+ if (h == NULL)
+ return LDB_ERR_OPERATIONS_ERROR;
+ ac = talloc_get_type(h->private_data, struct map_async_context);
+
+ /* return or own handle to deal with this call */
+ /* req->async.handle = h; */
+
+ /* prepare the local operation */
+ ac->local_req = talloc_zero(ac, struct ldb_request);
+ if (ac->local_req == NULL) {
+ map_oom(module);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ *(ac->local_req) = *req; /* copy the request */
+
+ /* return or own handle to deal with this call */
+ ac->local_req->async.handle = h;
+
+ ac->local_req->async.context = ac;
+ ac->local_req->async.callback = local_search_callback;
+
+ /* XXX: ... */
+
+ ac->local_req->op.search.attrs = local_attrs;
+
+ ldb_set_timeout_from_prev_req(module->ldb, req, ac->local_req);
+
+ h->state = LDB_ASYNC_INIT;
+ h->status = LDB_SUCCESS;
+
+ ac->step = MAP_SEARCH_LOCAL;
+
+ ret = ldb_next_request(module, ac->local_req);
+ if (ret == LDB_SUCCESS)
+ req->async.handle = ac->local_req->async.handle;
+ return ret;
+}
+
+
/* Add the local record */
static
int
@@ -1644,8 +1810,12 @@
if (ldb_dn_is_special(msg->dn))
return ldb_next_request(module, req);
+ /* no mapping requested, skip to next module */
+ if (!check_dn_local(module, msg->dn))
+ return ldb_next_request(module, req);
+
/* no mapping needed, skip to next module */
- if (!check_msg_is_mapped(module, msg))
+ if (!check_msg_mapped(module, msg))
return ldb_next_request(module, req);
/* prepare async context and handle */
@@ -1797,8 +1967,12 @@
if (ldb_dn_is_special(msg->dn))
return ldb_next_request(module, req);
+ /* no mapping requested, skip to next module */
+ if (!check_dn_local(module, msg->dn))
+ return ldb_next_request(module, req);
+
/* no mapping needed, skip to next module */
- if (!check_msg_is_mapped(module, msg))
+ if (!check_msg_mapped(module, msg))
return ldb_next_request(module, req);
/* prepare async context and handle */
@@ -1860,7 +2034,7 @@
return map_modify_do_local(h);
/* prepare the search operation */
- ac->search_req = build_self_req(ac, msg->dn);
+ ac->search_req = search_self_req(ac, msg->dn);
if (ac->search_req == NULL)
return LDB_ERR_OPERATIONS_ERROR;
@@ -1951,8 +2125,11 @@
if (ldb_dn_is_special(req->op.del.dn))
return ldb_next_request(module, req);
- /* TODO: check that DN is under the local baseDN */
+ /* no mapping requested, skip to next module */
+ if (!check_dn_local(module, req->op.del.dn))
+ return ldb_next_request(module, req);
+
/* prepare async context and handle */
h = map_init_handle(req, module);
if (h == NULL)
@@ -1963,7 +2140,7 @@
req->async.handle = h;
/* prepare the search operation */
- ac->search_req = build_self_req(ac, req->op.del.dn);
+ ac->search_req = search_self_req(ac, req->op.del.dn);
if (ac->search_req == NULL)
return LDB_ERR_OPERATIONS_ERROR;
@@ -2104,7 +2281,11 @@
if (ldb_dn_is_special(req->op.rename.olddn))
return ldb_next_request(module, req);
- /* TODO: check that DN is under the local baseDN */
+ /* no mapping requested, skip to next module */
+ /* TODO: both? either? neither? what to doin each case? */
+ if (!check_dn_local(module, req->op.rename.olddn) ||
+ !check_dn_local(module, req->op.rename.newdn))
+ return ldb_next_request(module, req);
/* prepare async context and handle */
h = map_init_handle(req, module);
@@ -2116,7 +2297,7 @@
req->async.handle = h;
/* prepare the search operation */
- ac->search_req = build_self_req(ac, req->op.rename.olddn);
+ ac->search_req = search_self_req(ac, req->op.rename.olddn);
if (ac->search_req == NULL)
return LDB_ERR_OPERATIONS_ERROR;
@@ -2291,7 +2472,7 @@
.modify = map_modify,
.del = map_delete,
.rename = map_rename,
-/* .search = map_search_bytree, */
+ .search = map_search,
.async_wait = map_async_wait,
};
More information about the samba-cvs
mailing list