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 /* valid attribute flags */
45 } ltdb_valid_attr_flags[] = {
46 { "CASE_INSENSITIVE", LTDB_FLAG_CASE_INSENSITIVE },
47 { "INTEGER", LTDB_FLAG_INTEGER },
48 { "WILDCARD", LTDB_FLAG_WILDCARD },
49 { "HIDDEN", LTDB_FLAG_HIDDEN },
50 { "NONE", LTDB_FLAG_NONE },
56 initialise the baseinfo record
58 static int ltdb_baseinfo_init(struct ldb_module *module)
60 struct ltdb_private *ltdb = module->private_data;
61 struct ldb_message *msg;
62 struct ldb_message_element el;
65 /* the initial sequence number must be different from the one
66 set in ltdb_cache_free(). Thanks to Jon for pointing this
68 const char *initial_sequence_number = "1";
70 ltdb->sequence_number = atof(initial_sequence_number);
72 msg = talloc(ltdb, struct ldb_message);
77 msg->num_elements = 1;
79 msg->dn = talloc_strdup(msg, LTDB_BASEINFO);
83 el.name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER);
90 val.data = talloc_strdup(msg, initial_sequence_number);
96 ret = ltdb_store(module, msg, TDB_INSERT);
109 free any cache records
111 static void ltdb_cache_free(struct ldb_module *module)
113 struct ltdb_private *ltdb = module->private_data;
115 ltdb->sequence_number = 0;
116 talloc_free(ltdb->cache);
123 int ltdb_cache_reload(struct ldb_module *module)
125 ltdb_cache_free(module);
126 return ltdb_cache_load(module);
130 load the cache records
132 int ltdb_cache_load(struct ldb_module *module)
134 struct ltdb_private *ltdb = module->private_data;
137 if (ltdb->cache == NULL) {
138 ltdb->cache = talloc_zero(ltdb, struct ltdb_cache);
139 if (ltdb->cache == NULL) goto failed;
140 ltdb->cache->indexlist = talloc_zero(ltdb->cache, struct ldb_message);
141 ltdb->cache->subclasses = talloc_zero(ltdb->cache, struct ldb_message);
142 ltdb->cache->attributes = talloc_zero(ltdb->cache, struct ldb_message);
143 if (ltdb->cache->indexlist == NULL ||
144 ltdb->cache->subclasses == NULL ||
145 ltdb->cache->attributes == NULL) {
150 talloc_free(ltdb->cache->baseinfo);
151 ltdb->cache->baseinfo = talloc(ltdb->cache, struct ldb_message);
152 if (ltdb->cache->baseinfo == NULL) goto failed;
154 if (ltdb_search_dn1(module, LTDB_BASEINFO, ltdb->cache->baseinfo) == -1) {
158 /* possibly initialise the baseinfo */
159 if (!ltdb->cache->baseinfo->dn) {
160 if (ltdb_baseinfo_init(module) != 0) {
163 if (ltdb_search_dn1(module, LTDB_BASEINFO, ltdb->cache->baseinfo) != 1) {
168 /* if the current internal sequence number is the same as the one
169 in the database then assume the rest of the cache is OK */
170 seq = ldb_msg_find_double(ltdb->cache->baseinfo, LTDB_SEQUENCE_NUMBER, 0);
171 if (seq == ltdb->sequence_number) {
174 ltdb->sequence_number = seq;
176 talloc_free(ltdb->cache->last_attribute.name);
177 memset(<db->cache->last_attribute, 0, sizeof(ltdb->cache->last_attribute));
179 talloc_free(ltdb->cache->indexlist);
180 talloc_free(ltdb->cache->subclasses);
181 talloc_free(ltdb->cache->attributes);
183 ltdb->cache->indexlist = talloc_zero(ltdb->cache, struct ldb_message);
184 ltdb->cache->subclasses = talloc_zero(ltdb->cache, struct ldb_message);
185 ltdb->cache->attributes = talloc_zero(ltdb->cache, struct ldb_message);
186 if (ltdb->cache->indexlist == NULL ||
187 ltdb->cache->subclasses == NULL ||
188 ltdb->cache->attributes == NULL) {
192 if (ltdb_search_dn1(module, LTDB_INDEXLIST, ltdb->cache->indexlist) == -1) {
195 if (ltdb_search_dn1(module, LTDB_SUBCLASSES, ltdb->cache->subclasses) == -1) {
198 if (ltdb_search_dn1(module, LTDB_ATTRIBUTES, ltdb->cache->attributes) == -1) {
211 increase the sequence number to indicate a database change
213 int ltdb_increase_sequence_number(struct ldb_module *module)
215 struct ltdb_private *ltdb = module->private_data;
216 struct ldb_message *msg;
217 struct ldb_message_element el;
222 msg = talloc(ltdb, struct ldb_message);
228 s = talloc_asprintf(msg, "%.0f", ltdb->sequence_number+1);
234 msg->num_elements = 1;
236 msg->dn = talloc_strdup(msg, LTDB_BASEINFO);
237 el.name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER);
240 el.flags = LDB_FLAG_MOD_REPLACE;
242 val.length = strlen(s);
244 ret = ltdb_modify_internal(module, msg);
249 ltdb->sequence_number += 1;
257 return the attribute flags from the @ATTRIBUTES record
258 for the given attribute
260 int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name)
262 struct ltdb_private *ltdb = module->private_data;
263 const struct ldb_message_element *attr_el;
266 if (ltdb->cache->last_attribute.name &&
267 ldb_attr_cmp(ltdb->cache->last_attribute.name, attr_name) == 0) {
268 return ltdb->cache->last_attribute.flags;
271 /* objectclass is a special default case */
272 if (ldb_attr_cmp(attr_name, LTDB_OBJECTCLASS) == 0) {
273 ret = LTDB_FLAG_OBJECTCLASS | LTDB_FLAG_CASE_INSENSITIVE;
276 attr_el = ldb_msg_find_element(ltdb->cache->attributes, attr_name);
280 /* check if theres a wildcard attribute */
281 attr_el = ldb_msg_find_element(ltdb->cache->attributes, "*");
288 for (i = 0; i < attr_el->num_values; i++) {
289 if (strcmp(ltdb_valid_attr_flags[i].name, attr_el->values[i].data) == 0) {
290 ret |= ltdb_valid_attr_flags[i].value;
294 talloc_free(ltdb->cache->last_attribute.name);
296 ltdb->cache->last_attribute.name = talloc_strdup(ltdb->cache, attr_name);
297 ltdb->cache->last_attribute.flags = ret;
302 int ltdb_check_at_attributes_values(const struct ldb_val *value)
306 for (i = 0; ltdb_valid_attr_flags[i].name != NULL; i++) {
307 if ((strcmp(ltdb_valid_attr_flags[i].name, value->data) == 0)) {