diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-07-01 06:21:26 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:19:01 -0500 |
commit | a06d66a3a669c3a0a0f816438e2b3e91e208f398 (patch) | |
tree | 0a80e63dad3f00cd584263e56df6f751b46de58e /source4/lib/ldb/ldb_tdb/ldb_cache.c | |
parent | 8ab3f59a10d00357cb129a2051fd0f694b5c8081 (diff) | |
download | samba-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.c | 188 |
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(<db->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; } |