4 Copyright (C) Andrew Tridgell 2004
6 ** NOTE! The following LGPL license applies to the ldb
7 ** library. This does NOT imply that all of Samba is released
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 * Component: ldb tdb cache functions
30 * Description: cache special records in a ldb/tdb
32 * Author: Andrew Tridgell
36 #include "ldb/include/ldb.h"
37 #include "ldb/include/ldb_private.h"
38 #include "ldb/ldb_tdb/ldb_tdb.h"
41 initialise the baseinfo record
43 static int ltdb_baseinfo_init(struct ldb_module *module)
45 struct ltdb_private *ltdb = module->private_data;
46 struct ldb_message *msg;
47 struct ldb_message_element el;
50 /* the initial sequence number must be different from the one
51 set in ltdb_cache_free(). Thanks to Jon for pointing this
53 const char *initial_sequence_number = "1";
55 ltdb->sequence_number = atof(initial_sequence_number);
57 msg = talloc(ltdb, struct ldb_message);
62 msg->num_elements = 1;
64 msg->dn = talloc_strdup(msg, LTDB_BASEINFO);
68 el.name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER);
75 val.data = talloc_strdup(msg, initial_sequence_number);
81 ret = ltdb_store(module, msg, TDB_INSERT);
94 free any cache records
96 static void ltdb_cache_free(struct ldb_module *module)
98 struct ltdb_private *ltdb = module->private_data;
100 ltdb->sequence_number = 0;
101 talloc_free(ltdb->cache);
108 int ltdb_cache_reload(struct ldb_module *module)
110 ltdb_cache_free(module);
111 return ltdb_cache_load(module);
115 load the cache records
117 int ltdb_cache_load(struct ldb_module *module)
119 struct ltdb_private *ltdb = module->private_data;
122 if (ltdb->cache == NULL) {
123 ltdb->cache = talloc_zero(ltdb, struct ltdb_cache);
124 if (ltdb->cache == NULL) goto failed;
125 ltdb->cache->indexlist = talloc_zero(ltdb->cache, struct ldb_message);
126 ltdb->cache->subclasses = talloc_zero(ltdb->cache, struct ldb_message);
127 ltdb->cache->attributes = talloc_zero(ltdb->cache, struct ldb_message);
128 if (ltdb->cache->indexlist == NULL ||
129 ltdb->cache->subclasses == NULL ||
130 ltdb->cache->attributes == NULL) {
135 talloc_free(ltdb->cache->baseinfo);
136 ltdb->cache->baseinfo = talloc(ltdb->cache, struct ldb_message);
137 if (ltdb->cache->baseinfo == NULL) goto failed;
139 if (ltdb_search_dn1(module, LTDB_BASEINFO, ltdb->cache->baseinfo) == -1) {
143 /* possibly initialise the baseinfo */
144 if (!ltdb->cache->baseinfo->dn) {
145 if (ltdb_baseinfo_init(module) != 0) {
148 if (ltdb_search_dn1(module, LTDB_BASEINFO, ltdb->cache->baseinfo) != 1) {
153 /* if the current internal sequence number is the same as the one
154 in the database then assume the rest of the cache is OK */
155 seq = ldb_msg_find_double(ltdb->cache->baseinfo, LTDB_SEQUENCE_NUMBER, 0);
156 if (seq == ltdb->sequence_number) {
159 ltdb->sequence_number = seq;
161 talloc_free(ltdb->cache->last_attribute.name);
162 memset(<db->cache->last_attribute, 0, sizeof(ltdb->cache->last_attribute));
164 talloc_free(ltdb->cache->indexlist);
165 talloc_free(ltdb->cache->subclasses);
166 talloc_free(ltdb->cache->attributes);
168 ltdb->cache->indexlist = talloc_zero(ltdb->cache, struct ldb_message);
169 ltdb->cache->subclasses = talloc_zero(ltdb->cache, struct ldb_message);
170 ltdb->cache->attributes = talloc_zero(ltdb->cache, struct ldb_message);
171 if (ltdb->cache->indexlist == NULL ||
172 ltdb->cache->subclasses == NULL ||
173 ltdb->cache->attributes == NULL) {
177 if (ltdb_search_dn1(module, LTDB_INDEXLIST, ltdb->cache->indexlist) == -1) {
180 if (ltdb_search_dn1(module, LTDB_SUBCLASSES, ltdb->cache->subclasses) == -1) {
183 if (ltdb_search_dn1(module, LTDB_ATTRIBUTES, ltdb->cache->attributes) == -1) {
196 increase the sequence number to indicate a database change
198 int ltdb_increase_sequence_number(struct ldb_module *module)
200 struct ltdb_private *ltdb = module->private_data;
201 struct ldb_message *msg;
202 struct ldb_message_element el;
207 msg = talloc(ltdb, struct ldb_message);
213 s = talloc_asprintf(msg, "%.0f", ltdb->sequence_number+1);
219 msg->num_elements = 1;
221 msg->dn = talloc_strdup(msg, LTDB_BASEINFO);
222 el.name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER);
225 el.flags = LDB_FLAG_MOD_REPLACE;
227 val.length = strlen(s);
229 ret = ltdb_modify_internal(module, msg);
234 ltdb->sequence_number += 1;
242 return the attribute flags from the @ATTRIBUTES record
243 for the given attribute
245 int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name)
247 struct ltdb_private *ltdb = module->private_data;
253 { "CASE_INSENSITIVE", LTDB_FLAG_CASE_INSENSITIVE },
254 { "INTEGER", LTDB_FLAG_INTEGER },
255 { "WILDCARD", LTDB_FLAG_WILDCARD },
256 { "HIDDEN", LTDB_FLAG_HIDDEN },
262 if (ltdb->cache->last_attribute.name &&
263 ldb_attr_cmp(ltdb->cache->last_attribute.name, attr_name) == 0) {
264 return ltdb->cache->last_attribute.flags;
267 /* objectclass is a special default case */
268 if (ldb_attr_cmp(attr_name, LTDB_OBJECTCLASS) == 0) {
269 ret = LTDB_FLAG_OBJECTCLASS | LTDB_FLAG_CASE_INSENSITIVE;
272 attrs = ldb_msg_find_string(ltdb->cache->attributes, attr_name, NULL);
278 /* we avoid using strtok and friends due to their nasty
279 interface. This is a little trickier, but much nicer
280 from a C interface point of view */
281 while ((len = strcspn(attrs, " ,")) > 0) {
282 for (i=0;names[i].name;i++) {
283 if (strncmp(names[i].name, attrs, len) == 0 &&
284 names[i].name[len] == 0) {
285 ret |= names[i].value;
289 attrs += strspn(attrs, " ,");
292 talloc_free(ltdb->cache->last_attribute.name);
294 ltdb->cache->last_attribute.name = talloc_strdup(ltdb->cache, attr_name);
295 ltdb->cache->last_attribute.flags = ret;