1 /*
2    ldb database library
3 
4    Copyright (C) Andrew Tridgell  2005
5 
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
9 
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.
14 
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.
19 
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/>.
22 */
23 /*
24   register handlers for specific attributes and objectclass relationships
25 
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
29 */
30 
31 #include "ldb_private.h"
32 #include "ldb_handlers.h"
33 
34 /*
35   fill in an attribute to the ldb_schema into the supplied buffer
36 
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!
41 
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!
45 
46 */
ldb_schema_attribute_fill_with_syntax(struct ldb_context * ldb,TALLOC_CTX * mem_ctx,const char * attribute,unsigned flags,const struct ldb_schema_syntax * syntax,struct ldb_schema_attribute * a)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)
53 {
54 	a->name	= attribute;
55 	a->flags	= flags;
56 	a->syntax	= syntax;
57 
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;
63 		}
64 	}
65 
66 	return 0;
67 }
68 
69 /*
70   add a attribute to the ldb_schema
71 
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!
76 
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!
80 
81 */
ldb_schema_attribute_add_with_syntax(struct ldb_context * ldb,const char * attribute,unsigned flags,const struct ldb_schema_syntax * syntax)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)
86 {
87 	unsigned int i, n;
88 	struct ldb_schema_attribute *a;
89 
90 	if (!syntax) {
91 		return LDB_ERR_OPERATIONS_ERROR;
92 	}
93 
94 	n = ldb->schema.num_attributes + 1;
95 
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;
101 	}
102 	ldb->schema.attributes = a;
103 
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;
110 			}
111 			if (a[i].flags & LDB_ATTR_FLAG_ALLOCATED) {
112 				talloc_free(discard_const_p(char, a[i].name));
113 			}
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;
120 		}
121 	}
122 	ldb->schema.num_attributes++;
123 
124 	a[i].name	= attribute;
125 	a[i].flags	= flags;
126 	a[i].syntax	= syntax;
127 
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;
133 		}
134 	}
135 
136 	return 0;
137 }
138 
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
145 };
146 
147 static const struct ldb_schema_attribute ldb_attribute_default = {
148 	.name	= NULL,
149 	.flags	= 0,
150 	.syntax	= &ldb_syntax_default
151 };
152 
153 /*
154  * Return the attribute handlers for a given attribute
155  *
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
161  */
ldb_schema_attribute_by_name_internal(struct ldb_context * ldb,const char * name)162 static const struct ldb_schema_attribute *ldb_schema_attribute_by_name_internal(
163 	struct ldb_context *ldb,
164 	const char *name)
165 {
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;
170 
171 	/* fallback to default attribute implementation */
172 	if (name == NULL) {
173 		return def;
174 	}
175 
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;
180 	}
181 
182 	/* do a binary search on the array */
183 	e = ldb->schema.num_attributes - 1;
184 
185 	while ((b <= e) && (e != (unsigned int) -1)) {
186 		i = (b + e) / 2;
187 
188 		r = ldb_attr_cmp(name, ldb->schema.attributes[i].name);
189 		if (r == 0) {
190 			return &ldb->schema.attributes[i];
191 		}
192 		if (r < 0) {
193 			e = i - 1;
194 		} else {
195 			b = i + 1;
196 		}
197 	}
198 
199 	return def;
200 }
201 
202 /*
203   return the attribute handlers for a given attribute
204 */
ldb_schema_attribute_by_name(struct ldb_context * ldb,const char * name)205 const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb,
206 								const char *name)
207 {
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;
215 		}
216 	}
217 
218 	return ldb_schema_attribute_by_name_internal(ldb, name);
219 }
220 
221 
222 /*
223   add to the list of ldif handlers for this ldb context
224 */
ldb_schema_attribute_remove(struct ldb_context * ldb,const char * name)225 void ldb_schema_attribute_remove(struct ldb_context *ldb, const char *name)
226 {
227 	const struct ldb_schema_attribute *a;
228 	ptrdiff_t i;
229 
230 	a = ldb_schema_attribute_by_name_internal(ldb, name);
231 	if (a == NULL || a->name == NULL) {
232 		return;
233 	}
234 
235 	/* FIXED attributes are never removed */
236 	if (a->flags & LDB_ATTR_FLAG_FIXED) {
237 		return;
238 	}
239 
240 	if (a->flags & LDB_ATTR_FLAG_ALLOCATED) {
241 		talloc_free(discard_const_p(char, a->name));
242 	}
243 
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)));
248 	}
249 
250 	ldb->schema.num_attributes--;
251 }
252 
253 /*
254   remove attributes with a specified flag (eg LDB_ATTR_FLAG_FROM_DB) for this ldb context
255 
256   This is to permit correct reloads
257 */
ldb_schema_attribute_remove_flagged(struct ldb_context * ldb,unsigned int flag)258 void ldb_schema_attribute_remove_flagged(struct ldb_context *ldb, unsigned int flag)
259 {
260 	ptrdiff_t i;
261 
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;
269 		}
270 		if ((a->flags & flag) == 0) {
271 			i++;
272 			continue;
273 		}
274 		if (a->flags & LDB_ATTR_FLAG_ALLOCATED) {
275 			talloc_free(discard_const_p(char, a->name));
276 		}
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)));
280 		}
281 
282 		ldb->schema.num_attributes--;
283 	}
284 }
285 
286 /*
287   setup a attribute handler using a standard syntax
288 */
ldb_schema_attribute_add(struct ldb_context * ldb,const char * attribute,unsigned flags,const char * syntax)289 int ldb_schema_attribute_add(struct ldb_context *ldb,
290 			     const char *attribute,
291 			     unsigned flags,
292 			     const char *syntax)
293 {
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);
296 }
297 
298 /*
299   setup the attribute handles for well known attributes
300 */
ldb_setup_wellknown_attributes(struct ldb_context * ldb)301 int ldb_setup_wellknown_attributes(struct ldb_context *ldb)
302 {
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 }
313 	};
314 	unsigned int i;
315 	int ret;
316 
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;
322 		}
323 	}
324 
325 	return LDB_SUCCESS;
326 }
327 
328 
329 /*
330   add a extended dn syntax to the ldb_schema
331 */
ldb_dn_extended_add_syntax(struct ldb_context * ldb,unsigned flags,const struct ldb_dn_extended_syntax * syntax)332 int ldb_dn_extended_add_syntax(struct ldb_context *ldb,
333 			       unsigned flags,
334 			       const struct ldb_dn_extended_syntax *syntax)
335 {
336 	unsigned int n;
337 	struct ldb_dn_extended_syntax *a;
338 
339 	if (!syntax) {
340 		return LDB_ERR_OPERATIONS_ERROR;
341 	}
342 
343 	n = ldb->schema.num_dn_extended_syntax + 1;
344 
345 	a = talloc_realloc(ldb, ldb->schema.dn_extended_syntax,
346 			   struct ldb_dn_extended_syntax, n);
347 
348 	if (!a) {
349 		return LDB_ERR_OPERATIONS_ERROR;
350 	}
351 
352 	a[ldb->schema.num_dn_extended_syntax] = *syntax;
353 	ldb->schema.dn_extended_syntax = a;
354 
355 	ldb->schema.num_dn_extended_syntax = n;
356 
357 	return LDB_SUCCESS;
358 }
359 
360 /*
361   return the extended dn syntax for a given name
362 */
ldb_dn_extended_syntax_by_name(struct ldb_context * ldb,const char * name)363 const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb,
364 								    const char *name)
365 {
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];
370 		}
371 	}
372 	return NULL;
373 }
374 
375 /*
376   set an attribute handler override function - used to delegate schema handling
377   to external code
378  */
ldb_schema_attribute_set_override_handler(struct ldb_context * ldb,ldb_attribute_handler_override_fn_t override,void * private_data)379 void ldb_schema_attribute_set_override_handler(struct ldb_context *ldb,
380 					       ldb_attribute_handler_override_fn_t override,
381 					       void *private_data)
382 {
383 	ldb->schema.attribute_handler_override_private = private_data;
384 	ldb->schema.attribute_handler_override = override;
385 }
386 
387 /*
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
391  */
ldb_schema_set_override_indexlist(struct ldb_context * ldb,bool one_level_indexes)392 void ldb_schema_set_override_indexlist(struct ldb_context *ldb,
393 				       bool one_level_indexes)
394 {
395 	ldb->schema.index_handler_override = true;
396 	ldb->schema.one_level_indexes = one_level_indexes;
397 }
398 
399 /*
400  * set that the GUID index mode is in operation
401  *
402  * The caller must ensure the supplied strings do not go out of
403  * scope (they are typically constant memory).
404  */
ldb_schema_set_override_GUID_index(struct ldb_context * ldb,const char * GUID_index_attribute,const char * GUID_index_dn_component)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)
408 {
409 	ldb->schema.GUID_index_attribute = GUID_index_attribute;
410 	ldb->schema.GUID_index_dn_component = GUID_index_dn_component;
411 }
412