• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.5.8/source4/lib/ldb/common/
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  add a attribute to the ldb_schema
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*/
47int ldb_schema_attribute_add_with_syntax(struct ldb_context *ldb,
48					 const char *attribute,
49					 unsigned flags,
50					 const struct ldb_schema_syntax *syntax)
51{
52	int i, n;
53	struct ldb_schema_attribute *a;
54
55	if (!syntax) {
56		return LDB_ERR_OPERATIONS_ERROR;
57	}
58
59	n = ldb->schema.num_attributes + 1;
60
61	a = talloc_realloc(ldb, ldb->schema.attributes,
62			   struct ldb_schema_attribute, n);
63	if (a == NULL) {
64		ldb_oom(ldb);
65		return -1;
66	}
67	ldb->schema.attributes = a;
68
69	for (i = 0; i < ldb->schema.num_attributes; i++) {
70		int cmp = ldb_attr_cmp(attribute, a[i].name);
71		if (cmp == 0) {
72			/* silently ignore attempts to overwrite fixed attributes */
73			if (a[i].flags & LDB_ATTR_FLAG_FIXED) {
74				return 0;
75			}
76			if (a[i].flags & LDB_ATTR_FLAG_ALLOCATED) {
77				talloc_free(discard_const_p(char, a[i].name));
78			}
79			/* To cancel out increment below */
80			ldb->schema.num_attributes--;
81			break;
82		} else if (cmp < 0) {
83			memmove(a+i+1, a+i, sizeof(*a) * (ldb->schema.num_attributes-i));
84			break;
85		}
86	}
87	ldb->schema.num_attributes++;
88
89	a[i].name	= attribute;
90	a[i].flags	= flags;
91	a[i].syntax	= syntax;
92
93	if (a[i].flags & LDB_ATTR_FLAG_ALLOCATED) {
94		a[i].name = talloc_strdup(a, a[i].name);
95		if (a[i].name == NULL) {
96			ldb_oom(ldb);
97			return -1;
98		}
99	}
100
101	return 0;
102}
103
104static const struct ldb_schema_syntax ldb_syntax_default = {
105	.name            = LDB_SYNTAX_OCTET_STRING,
106	.ldif_read_fn    = ldb_handler_copy,
107	.ldif_write_fn   = ldb_handler_copy,
108	.canonicalise_fn = ldb_handler_copy,
109	.comparison_fn   = ldb_comparison_binary
110};
111
112static const struct ldb_schema_attribute ldb_attribute_default = {
113	.name	= NULL,
114	.flags	= 0,
115	.syntax	= &ldb_syntax_default
116};
117
118/*
119  return the attribute handlers for a given attribute
120*/
121static const struct ldb_schema_attribute *ldb_schema_attribute_by_name_internal(
122	struct ldb_context *ldb,
123	const char *name)
124{
125	int i, e, b = 0, r;
126	const struct ldb_schema_attribute *def = &ldb_attribute_default;
127
128	/* as handlers are sorted, '*' must be the first if present */
129	if (strcmp(ldb->schema.attributes[0].name, "*") == 0) {
130		def = &ldb->schema.attributes[0];
131		b = 1;
132	}
133
134	/* do a binary search on the array */
135	e = ldb->schema.num_attributes - 1;
136
137	while (b <= e) {
138
139		i = (b + e) / 2;
140
141		r = ldb_attr_cmp(name, ldb->schema.attributes[i].name);
142		if (r == 0) {
143			return &ldb->schema.attributes[i];
144		}
145		if (r < 0) {
146			e = i - 1;
147		} else {
148			b = i + 1;
149		}
150
151	}
152
153	return def;
154}
155
156/*
157  return the attribute handlers for a given attribute
158*/
159const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb,
160								const char *name)
161{
162	if (ldb->schema.attribute_handler_override) {
163		const struct ldb_schema_attribute *ret =
164			ldb->schema.attribute_handler_override(ldb,
165							       ldb->schema.attribute_handler_override_private,
166							       name);
167		if (ret) {
168			return ret;
169		}
170	}
171
172	return ldb_schema_attribute_by_name_internal(ldb, name);
173}
174
175
176/*
177  add to the list of ldif handlers for this ldb context
178*/
179void ldb_schema_attribute_remove(struct ldb_context *ldb, const char *name)
180{
181	const struct ldb_schema_attribute *a;
182	int i;
183
184	a = ldb_schema_attribute_by_name_internal(ldb, name);
185	if (a == NULL || a->name == NULL) {
186		return;
187	}
188
189	/* FIXED attributes are never removed */
190	if (a->flags & LDB_ATTR_FLAG_FIXED) {
191		return;
192	}
193
194	if (a->flags & LDB_ATTR_FLAG_ALLOCATED) {
195		talloc_free(discard_const_p(char, a->name));
196	}
197
198	i = a - ldb->schema.attributes;
199	if (i < ldb->schema.num_attributes - 1) {
200		memmove(&ldb->schema.attributes[i],
201			a+1, sizeof(*a) * (ldb->schema.num_attributes-(i+1)));
202	}
203
204	ldb->schema.num_attributes--;
205}
206
207/*
208  setup a attribute handler using a standard syntax
209*/
210int ldb_schema_attribute_add(struct ldb_context *ldb,
211			     const char *attribute,
212			     unsigned flags,
213			     const char *syntax)
214{
215	const struct ldb_schema_syntax *s = ldb_standard_syntax_by_name(ldb, syntax);
216	return ldb_schema_attribute_add_with_syntax(ldb, attribute, flags, s);
217}
218
219/*
220  setup the attribute handles for well known attributes
221*/
222int ldb_setup_wellknown_attributes(struct ldb_context *ldb)
223{
224	const struct {
225		const char *attr;
226		const char *syntax;
227	} wellknown[] = {
228		{ "dn", LDB_SYNTAX_DN },
229		{ "distinguishedName", LDB_SYNTAX_DN },
230		{ "cn", LDB_SYNTAX_DIRECTORY_STRING },
231		{ "dc", LDB_SYNTAX_DIRECTORY_STRING },
232		{ "ou", LDB_SYNTAX_DIRECTORY_STRING },
233		{ "objectClass", LDB_SYNTAX_OBJECTCLASS }
234	};
235	int i;
236	int ret;
237
238	for (i=0;i<ARRAY_SIZE(wellknown);i++) {
239		ret = ldb_schema_attribute_add(ldb, wellknown[i].attr, 0,
240					       wellknown[i].syntax);
241		if (ret != LDB_SUCCESS) {
242			return ret;
243		}
244	}
245
246	return LDB_SUCCESS;
247}
248
249
250/*
251  add a extended dn syntax to the ldb_schema
252*/
253int ldb_dn_extended_add_syntax(struct ldb_context *ldb,
254			       unsigned flags,
255			       const struct ldb_dn_extended_syntax *syntax)
256{
257	int n;
258	struct ldb_dn_extended_syntax *a;
259
260	if (!syntax) {
261		return LDB_ERR_OPERATIONS_ERROR;
262	}
263
264	n = ldb->schema.num_dn_extended_syntax + 1;
265
266	a = talloc_realloc(ldb, ldb->schema.dn_extended_syntax,
267			   struct ldb_dn_extended_syntax, n);
268
269	if (!a) {
270		return LDB_ERR_OPERATIONS_ERROR;
271	}
272
273	a[ldb->schema.num_dn_extended_syntax] = *syntax;
274	ldb->schema.dn_extended_syntax = a;
275
276	ldb->schema.num_dn_extended_syntax = n;
277
278	return LDB_SUCCESS;
279}
280
281/*
282  return the extended dn syntax for a given name
283*/
284const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb,
285								    const char *name)
286{
287	int i;
288	for (i=0; i < ldb->schema.num_dn_extended_syntax; i++) {
289		if (ldb_attr_cmp(ldb->schema.dn_extended_syntax[i].name, name) == 0) {
290			return &ldb->schema.dn_extended_syntax[i];
291		}
292	}
293	return NULL;
294}
295
296/*
297  set an attribute handler override function - used to delegate schema handling
298  to external code
299 */
300void ldb_schema_attribute_set_override_handler(struct ldb_context *ldb,
301					       ldb_attribute_handler_override_fn_t override,
302					       void *private_data)
303{
304	ldb->schema.attribute_handler_override_private = private_data;
305	ldb->schema.attribute_handler_override = override;
306}
307