smbd: Assert we have an fsp in smbd_do_setfilepathinfo
[Samba.git] / lib / ldb / common / ldb_attributes.c
blob32f25fd0fe89616068feb325e1c15e4ae36e6824
1 /*
2 ldb database library
4 Copyright (C) Andrew Tridgell 2005
6 ** NOTE! The following LGPL license applies to the ldb
7 ** library. This does NOT imply that all of Samba is released
8 ** under the LGPL
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 3 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, see <http://www.gnu.org/licenses/>.
24 register handlers for specific attributes and objectclass relationships
26 this allows a backend to store its schema information in any format
27 it likes (or to not have any schema information at all) while keeping the
28 message matching logic generic
31 #include "ldb_private.h"
32 #include "ldb_handlers.h"
35 fill in an attribute to the ldb_schema into the supplied buffer
37 if flags contains LDB_ATTR_FLAG_ALLOCATED
38 the attribute name string will be copied using
39 talloc_strdup(), otherwise it needs to be a static const
40 string at least with a lifetime longer than the ldb struct!
42 the ldb_schema_syntax structure should be a pointer
43 to a static const struct or at least it needs to be
44 a struct with a longer lifetime than the ldb context!
47 int ldb_schema_attribute_fill_with_syntax(struct ldb_context *ldb,
48 TALLOC_CTX *mem_ctx,
49 const char *attribute,
50 unsigned flags,
51 const struct ldb_schema_syntax *syntax,
52 struct ldb_schema_attribute *a)
54 a->name = attribute;
55 a->flags = flags;
56 a->syntax = syntax;
58 if (a->flags & LDB_ATTR_FLAG_ALLOCATED) {
59 a->name = talloc_strdup(mem_ctx, a->name);
60 if (a->name == NULL) {
61 ldb_oom(ldb);
62 return -1;
66 return 0;
70 add a attribute to the ldb_schema
72 if flags contains LDB_ATTR_FLAG_ALLOCATED
73 the attribute name string will be copied using
74 talloc_strdup(), otherwise it needs to be a static const
75 string at least with a lifetime longer than the ldb struct!
77 the ldb_schema_syntax structure should be a pointer
78 to a static const struct or at least it needs to be
79 a struct with a longer lifetime than the ldb context!
82 int ldb_schema_attribute_add_with_syntax(struct ldb_context *ldb,
83 const char *attribute,
84 unsigned flags,
85 const struct ldb_schema_syntax *syntax)
87 unsigned int i, n;
88 struct ldb_schema_attribute *a;
90 if (!syntax) {
91 return LDB_ERR_OPERATIONS_ERROR;
94 n = ldb->schema.num_attributes + 1;
96 a = talloc_realloc(ldb, ldb->schema.attributes,
97 struct ldb_schema_attribute, n);
98 if (a == NULL) {
99 ldb_oom(ldb);
100 return -1;
102 ldb->schema.attributes = a;
104 for (i = 0; i < ldb->schema.num_attributes; i++) {
105 int cmp = ldb_attr_cmp(attribute, a[i].name);
106 if (cmp == 0) {
107 /* silently ignore attempts to overwrite fixed attributes */
108 if (a[i].flags & LDB_ATTR_FLAG_FIXED) {
109 return 0;
111 if (a[i].flags & LDB_ATTR_FLAG_ALLOCATED) {
112 talloc_free(discard_const_p(char, a[i].name));
114 /* To cancel out increment below */
115 ldb->schema.num_attributes--;
116 break;
117 } else if (cmp < 0) {
118 memmove(a+i+1, a+i, sizeof(*a) * (ldb->schema.num_attributes-i));
119 break;
122 ldb->schema.num_attributes++;
124 a[i].name = attribute;
125 a[i].flags = flags;
126 a[i].syntax = syntax;
128 if (a[i].flags & LDB_ATTR_FLAG_ALLOCATED) {
129 a[i].name = talloc_strdup(a, a[i].name);
130 if (a[i].name == NULL) {
131 ldb_oom(ldb);
132 return -1;
136 return 0;
139 static const struct ldb_schema_syntax ldb_syntax_default = {
140 .name = LDB_SYNTAX_OCTET_STRING,
141 .ldif_read_fn = ldb_handler_copy,
142 .ldif_write_fn = ldb_handler_copy,
143 .canonicalise_fn = ldb_handler_copy,
144 .comparison_fn = ldb_comparison_binary
147 static const struct ldb_schema_attribute ldb_attribute_default = {
148 .name = NULL,
149 .flags = 0,
150 .syntax = &ldb_syntax_default
154 * Return the attribute handlers for a given attribute
156 * @param ldb ldb context
157 * @param name attribute name to search for
158 * @return Always return valid pointer to schema attribute.
159 * In case there is no attribute with name,
160 * ldb_attribute_default is returned
162 static const struct ldb_schema_attribute *ldb_schema_attribute_by_name_internal(
163 struct ldb_context *ldb,
164 const char *name)
166 /* for binary search we need signed variables */
167 unsigned int i, e, b = 0;
168 int r;
169 const struct ldb_schema_attribute *def = &ldb_attribute_default;
171 /* fallback to default attribute implementation */
172 if (name == NULL) {
173 return def;
176 /* as handlers are sorted, '*' must be the first if present */
177 if (strcmp(ldb->schema.attributes[0].name, "*") == 0) {
178 def = &ldb->schema.attributes[0];
179 b = 1;
182 /* do a binary search on the array */
183 e = ldb->schema.num_attributes - 1;
185 while ((b <= e) && (e != (unsigned int) -1)) {
186 i = (b + e) / 2;
188 r = ldb_attr_cmp(name, ldb->schema.attributes[i].name);
189 if (r == 0) {
190 return &ldb->schema.attributes[i];
192 if (r < 0) {
193 e = i - 1;
194 } else {
195 b = i + 1;
199 return def;
203 return the attribute handlers for a given attribute
205 const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb,
206 const char *name)
208 if (ldb->schema.attribute_handler_override) {
209 const struct ldb_schema_attribute *ret =
210 ldb->schema.attribute_handler_override(ldb,
211 ldb->schema.attribute_handler_override_private,
212 name);
213 if (ret) {
214 return ret;
218 return ldb_schema_attribute_by_name_internal(ldb, name);
223 add to the list of ldif handlers for this ldb context
225 void ldb_schema_attribute_remove(struct ldb_context *ldb, const char *name)
227 const struct ldb_schema_attribute *a;
228 ptrdiff_t i;
230 a = ldb_schema_attribute_by_name_internal(ldb, name);
231 if (a == NULL || a->name == NULL) {
232 return;
235 /* FIXED attributes are never removed */
236 if (a->flags & LDB_ATTR_FLAG_FIXED) {
237 return;
240 if (a->flags & LDB_ATTR_FLAG_ALLOCATED) {
241 talloc_free(discard_const_p(char, a->name));
244 i = a - ldb->schema.attributes;
245 if (i < ldb->schema.num_attributes - 1) {
246 memmove(&ldb->schema.attributes[i],
247 a+1, sizeof(*a) * (ldb->schema.num_attributes-(i+1)));
250 ldb->schema.num_attributes--;
254 remove attributes with a specified flag (eg LDB_ATTR_FLAG_FROM_DB) for this ldb context
256 This is to permit correct reloads
258 void ldb_schema_attribute_remove_flagged(struct ldb_context *ldb, unsigned int flag)
260 ptrdiff_t i;
262 for (i = 0; i < ldb->schema.num_attributes;) {
263 const struct ldb_schema_attribute *a
264 = &ldb->schema.attributes[i];
265 /* FIXED attributes are never removed */
266 if (a->flags & LDB_ATTR_FLAG_FIXED) {
267 i++;
268 continue;
270 if ((a->flags & flag) == 0) {
271 i++;
272 continue;
274 if (a->flags & LDB_ATTR_FLAG_ALLOCATED) {
275 talloc_free(discard_const_p(char, a->name));
277 if (i < ldb->schema.num_attributes - 1) {
278 memmove(&ldb->schema.attributes[i],
279 a+1, sizeof(*a) * (ldb->schema.num_attributes-(i+1)));
282 ldb->schema.num_attributes--;
287 setup a attribute handler using a standard syntax
289 int ldb_schema_attribute_add(struct ldb_context *ldb,
290 const char *attribute,
291 unsigned flags,
292 const char *syntax)
294 const struct ldb_schema_syntax *s = ldb_standard_syntax_by_name(ldb, syntax);
295 return ldb_schema_attribute_add_with_syntax(ldb, attribute, flags, s);
299 setup the attribute handles for well known attributes
301 int ldb_setup_wellknown_attributes(struct ldb_context *ldb)
303 const struct {
304 const char *attr;
305 const char *syntax;
306 } wellknown[] = {
307 { "dn", LDB_SYNTAX_DN },
308 { "distinguishedName", LDB_SYNTAX_DN },
309 { "cn", LDB_SYNTAX_DIRECTORY_STRING },
310 { "dc", LDB_SYNTAX_DIRECTORY_STRING },
311 { "ou", LDB_SYNTAX_DIRECTORY_STRING },
312 { "objectClass", LDB_SYNTAX_OBJECTCLASS }
314 unsigned int i;
315 int ret;
317 for (i=0;i<ARRAY_SIZE(wellknown);i++) {
318 ret = ldb_schema_attribute_add(ldb, wellknown[i].attr, 0,
319 wellknown[i].syntax);
320 if (ret != LDB_SUCCESS) {
321 return ret;
325 return LDB_SUCCESS;
330 add a extended dn syntax to the ldb_schema
332 int ldb_dn_extended_add_syntax(struct ldb_context *ldb,
333 unsigned flags,
334 const struct ldb_dn_extended_syntax *syntax)
336 unsigned int n;
337 struct ldb_dn_extended_syntax *a;
339 if (!syntax) {
340 return LDB_ERR_OPERATIONS_ERROR;
343 n = ldb->schema.num_dn_extended_syntax + 1;
345 a = talloc_realloc(ldb, ldb->schema.dn_extended_syntax,
346 struct ldb_dn_extended_syntax, n);
348 if (!a) {
349 return LDB_ERR_OPERATIONS_ERROR;
352 a[ldb->schema.num_dn_extended_syntax] = *syntax;
353 ldb->schema.dn_extended_syntax = a;
355 ldb->schema.num_dn_extended_syntax = n;
357 return LDB_SUCCESS;
361 return the extended dn syntax for a given name
363 const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb,
364 const char *name)
366 unsigned int i;
367 for (i=0; i < ldb->schema.num_dn_extended_syntax; i++) {
368 if (ldb_attr_cmp(ldb->schema.dn_extended_syntax[i].name, name) == 0) {
369 return &ldb->schema.dn_extended_syntax[i];
372 return NULL;
376 set an attribute handler override function - used to delegate schema handling
377 to external code
379 void ldb_schema_attribute_set_override_handler(struct ldb_context *ldb,
380 ldb_attribute_handler_override_fn_t override,
381 void *private_data)
383 ldb->schema.attribute_handler_override_private = private_data;
384 ldb->schema.attribute_handler_override = override;
388 set that the attribute handler override function - used to delegate
389 schema handling to external code, is handling setting
390 LDB_ATTR_FLAG_INDEXED
392 void ldb_schema_set_override_indexlist(struct ldb_context *ldb,
393 bool one_level_indexes)
395 ldb->schema.index_handler_override = true;
396 ldb->schema.one_level_indexes = one_level_indexes;
400 * set that the GUID index mode is in operation
402 * The caller must ensure the supplied strings do not go out of
403 * scope (they are typically constant memory).
405 void ldb_schema_set_override_GUID_index(struct ldb_context *ldb,
406 const char *GUID_index_attribute,
407 const char *GUID_index_dn_component)
409 ldb->schema.GUID_index_attribute = GUID_index_attribute;
410 ldb->schema.GUID_index_dn_component = GUID_index_dn_component;