summaryrefslogtreecommitdiff
path: root/source4/lib/ldb/ldb_tdb/ldb_cache.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-07-01 06:21:26 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:19:01 -0500
commita06d66a3a669c3a0a0f816438e2b3e91e208f398 (patch)
tree0a80e63dad3f00cd584263e56df6f751b46de58e /source4/lib/ldb/ldb_tdb/ldb_cache.c
parent8ab3f59a10d00357cb129a2051fd0f694b5c8081 (diff)
downloadsamba-a06d66a3a669c3a0a0f816438e2b3e91e208f398.tar.gz
samba-a06d66a3a669c3a0a0f816438e2b3e91e208f398.tar.bz2
samba-a06d66a3a669c3a0a0f816438e2b3e91e208f398.zip
r8037: a fairly major update to the internals of ldb. Changes are:
- moved the knowledge of attribute types out of ldb_tdb and into the generic ldb code. This allows the ldb_match() message match logic to be generic, so it can be used by other backend - added the generic ability to load attribute handlers, for canonicalisation, compare, ldif read and ldif write. In the future this will be used by the schema module to allow us to correctly obey the attributetype schema elements - added attribute handlers for some of the core ldap attribute types, Integer, DirectoryString, DN, ObjectClass etc - added automatic registration of attribute handlers for well-known attribute names 'cn', 'dc', 'dn', 'ou' and 'objectClass' - converted the objectSid special handlers for Samba to the new system - added more correct handling of indexing in tdb backend based on the attribute canonicalisation function - added generic support for subclasses, moving it out of the tdb backend. This will be used in future by the schema module - fixed several bugs in the dn_explode code. It still needs more work, but doesn't corrupt ldb dbs any more. (This used to be commit 944c5844ab441b96d8e5d7b2d151982139d1fab9)
Diffstat (limited to 'source4/lib/ldb/ldb_tdb/ldb_cache.c')
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_cache.c188
1 files changed, 184 insertions, 4 deletions
diff --git a/source4/lib/ldb/ldb_tdb/ldb_cache.c b/source4/lib/ldb/ldb_tdb/ldb_cache.c
index 0bc2d7b123..0b7ddad5db 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_cache.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_cache.c
@@ -37,6 +37,11 @@
#include "ldb/include/ldb_private.h"
#include "ldb/ldb_tdb/ldb_tdb.h"
+#define LTDB_FLAG_CASE_INSENSITIVE (1<<0)
+#define LTDB_FLAG_INTEGER (1<<1)
+#define LTDB_FLAG_WILDCARD (1<<2)
+#define LTDB_FLAG_HIDDEN (1<<3)
+#define LTDB_FLAG_OBJECTCLASS (1<<4)
/* valid attribute flags */
static const struct {
@@ -47,12 +52,182 @@ static const struct {
{ "INTEGER", LTDB_FLAG_INTEGER },
{ "WILDCARD", LTDB_FLAG_WILDCARD },
{ "HIDDEN", LTDB_FLAG_HIDDEN },
- { "NONE", LTDB_FLAG_NONE },
+ { "NONE", 0 },
{ NULL, 0 }
};
/*
+ de-register any special handlers for @ATTRIBUTES
+*/
+static void ltdb_attributes_unload(struct ldb_module *module)
+{
+ struct ltdb_private *ltdb = module->private_data;
+ struct ldb_message *msg;
+ int i;
+
+ if (ltdb->cache->attributes == NULL) {
+ /* no previously loaded attributes */
+ return;
+ }
+
+ msg = ltdb->cache->attributes;
+ for (i=0;i<msg->num_elements;i++) {
+ const struct ldb_attrib_handler *h;
+ /* this is rather ugly - a consequence of const handling */
+ h = ldb_attrib_handler(module->ldb, msg->elements[i].name);
+ ldb_remove_attrib_handler(module->ldb, msg->elements[i].name);
+ if (strcmp(h->attr, msg->elements[i].name) == 0) {
+ talloc_steal(msg, h->attr);
+ }
+ }
+
+ talloc_free(ltdb->cache->attributes);
+ ltdb->cache->attributes = NULL;
+}
+
+/*
+ add up the attrib flags for a @ATTRIBUTES element
+*/
+static int ltdb_attributes_flags(struct ldb_message_element *el, unsigned *v)
+{
+ int i;
+ unsigned value = 0;
+ for (i=0;i<el->num_values;i++) {
+ int j;
+ for (j=0;ltdb_valid_attr_flags[j].name;j++) {
+ if (strcmp(ltdb_valid_attr_flags[j].name,
+ el->values[i].data) == 0) {
+ value |= ltdb_valid_attr_flags[j].value;
+ break;
+ }
+ }
+ if (ltdb_valid_attr_flags[j].name == NULL) {
+ return -1;
+ }
+ }
+ *v = value;
+ return 0;
+}
+
+/*
+ register any special handlers from @ATTRIBUTES
+*/
+static int ltdb_attributes_load(struct ldb_module *module)
+{
+ struct ltdb_private *ltdb = module->private_data;
+ struct ldb_message *msg = ltdb->cache->attributes;
+ int i;
+
+ if (ltdb_search_dn1(module, LTDB_ATTRIBUTES, msg) == -1) {
+ goto failed;
+ }
+ /* mapping these flags onto ldap 'syntaxes' isn't strictly correct,
+ but its close enough for now */
+ for (i=0;i<msg->num_elements;i++) {
+ unsigned flags;
+ const char *syntax;
+ const struct ldb_attrib_handler *h;
+ struct ldb_attrib_handler h2;
+
+ if (ltdb_attributes_flags(&msg->elements[i], &flags) != 0) {
+ ldb_debug(module->ldb, LDB_DEBUG_ERROR, "Invalid @ATTRIBUTES element for '%s'\n", msg->elements[i].name);
+ goto failed;
+ }
+ switch (flags & ~LTDB_FLAG_HIDDEN) {
+ case 0:
+ syntax = LDB_SYNTAX_OCTET_STRING;
+ break;
+ case LTDB_FLAG_WILDCARD:
+ case LTDB_FLAG_WILDCARD | LTDB_FLAG_CASE_INSENSITIVE:
+ syntax = LDB_SYNTAX_WILDCARD;
+ break;
+ case LTDB_FLAG_CASE_INSENSITIVE:
+ syntax = LDB_SYNTAX_DIRECTORY_STRING;
+ break;
+ case LTDB_FLAG_INTEGER:
+ syntax = LDB_SYNTAX_INTEGER;
+ break;
+ default:
+ ldb_debug(module->ldb, LDB_DEBUG_ERROR,
+ "Invalid flag combination 0x%x for '%s' in @ATTRIBUTES\n",
+ flags, msg->elements[i].name);
+ goto failed;
+ }
+
+ h = ldb_attrib_handler_syntax(module->ldb, syntax);
+ if (h == NULL) {
+ ldb_debug(module->ldb, LDB_DEBUG_ERROR,
+ "Invalid attribute syntax '%s' for '%s' in @ATTRIBUTES\n",
+ syntax, msg->elements[i].name);
+ goto failed;
+ }
+ h2 = *h;
+ h2.attr = talloc_strdup(module, msg->elements[i].name);
+ if (ldb_set_attrib_handlers(module->ldb, &h2, 1) != 0) {
+ goto failed;
+ }
+ }
+
+ return 0;
+failed:
+ return -1;
+}
+
+
+/*
+ register any subclasses from @SUBCLASSES
+*/
+static int ltdb_subclasses_load(struct ldb_module *module)
+{
+ struct ltdb_private *ltdb = module->private_data;
+ struct ldb_message *msg = ltdb->cache->subclasses;
+ int i, j;
+
+ if (ltdb_search_dn1(module, LTDB_SUBCLASSES, msg) == -1) {
+ goto failed;
+ }
+
+ for (i=0;i<msg->num_elements;i++) {
+ struct ldb_message_element *el = &msg->elements[i];
+ for (j=0;j<el->num_values;j++) {
+ if (ldb_subclass_add(module->ldb, el->name, el->values[j].data) != 0) {
+ goto failed;
+ }
+ }
+ }
+
+ return 0;
+failed:
+ return -1;
+}
+
+
+/*
+ de-register any @SUBCLASSES
+*/
+static void ltdb_subclasses_unload(struct ldb_module *module)
+{
+ struct ltdb_private *ltdb = module->private_data;
+ struct ldb_message *msg;
+ int i;
+
+ if (ltdb->cache->subclasses == NULL) {
+ /* no previously loaded subclasses */
+ return;
+ }
+
+ msg = ltdb->cache->subclasses;
+ for (i=0;i<msg->num_elements;i++) {
+ ldb_subclass_remove(module->ldb, msg->elements[i].name);
+ }
+
+ talloc_free(ltdb->cache->subclasses);
+ ltdb->cache->subclasses = NULL;
+}
+
+
+/*
initialise the baseinfo record
*/
static int ltdb_baseinfo_init(struct ldb_module *module)
@@ -122,6 +297,8 @@ static void ltdb_cache_free(struct ldb_module *module)
*/
int ltdb_cache_reload(struct ldb_module *module)
{
+ ltdb_attributes_unload(module);
+ ltdb_subclasses_unload(module);
ltdb_cache_free(module);
return ltdb_cache_load(module);
}
@@ -176,9 +353,11 @@ int ltdb_cache_load(struct ldb_module *module)
talloc_free(ltdb->cache->last_attribute.name);
memset(&ltdb->cache->last_attribute, 0, sizeof(ltdb->cache->last_attribute));
+ ltdb_attributes_unload(module);
+ ltdb_subclasses_unload(module);
+
talloc_free(ltdb->cache->indexlist);
talloc_free(ltdb->cache->subclasses);
- talloc_free(ltdb->cache->attributes);
ltdb->cache->indexlist = talloc_zero(ltdb->cache, struct ldb_message);
ltdb->cache->subclasses = talloc_zero(ltdb->cache, struct ldb_message);
@@ -192,10 +371,11 @@ int ltdb_cache_load(struct ldb_module *module)
if (ltdb_search_dn1(module, LTDB_INDEXLIST, ltdb->cache->indexlist) == -1) {
goto failed;
}
- if (ltdb_search_dn1(module, LTDB_SUBCLASSES, ltdb->cache->subclasses) == -1) {
+
+ if (ltdb_attributes_load(module) == -1) {
goto failed;
}
- if (ltdb_search_dn1(module, LTDB_ATTRIBUTES, ltdb->cache->attributes) == -1) {
+ if (ltdb_subclasses_load(module) == -1) {
goto failed;
}