• 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/source3/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 "includes.h"
32#include "ldb/include/includes.h"
33
34/*
35  add to the list of ldif handlers for this ldb context
36*/
37int ldb_set_attrib_handlers(struct ldb_context *ldb,
38			    const struct ldb_attrib_handler *handlers,
39			    unsigned num_handlers)
40{
41	int i;
42	struct ldb_attrib_handler *h;
43	h = talloc_realloc(ldb, ldb->schema.attrib_handlers,
44			   struct ldb_attrib_handler,
45			   ldb->schema.num_attrib_handlers + num_handlers);
46	if (h == NULL) {
47		ldb_oom(ldb);
48		return -1;
49	}
50	ldb->schema.attrib_handlers = h;
51	memcpy(h + ldb->schema.num_attrib_handlers,
52	       handlers, sizeof(*h) * num_handlers);
53	for (i=0;i<num_handlers;i++) {
54		if (h[ldb->schema.num_attrib_handlers+i].flags & LDB_ATTR_FLAG_ALLOCATED) {
55			h[ldb->schema.num_attrib_handlers+i].attr = talloc_strdup(ldb->schema.attrib_handlers,
56										  h[ldb->schema.num_attrib_handlers+i].attr);
57			if (h[ldb->schema.num_attrib_handlers+i].attr == NULL) {
58				ldb_oom(ldb);
59				return -1;
60			}
61		}
62	}
63	ldb->schema.num_attrib_handlers += num_handlers;
64	return 0;
65}
66
67
68/*
69  default function for read/write/canonicalise
70*/
71static int ldb_default_copy(struct ldb_context *ldb,
72			    void *mem_ctx,
73			    const struct ldb_val *in,
74			    struct ldb_val *out)
75{
76	*out = ldb_val_dup(mem_ctx, in);
77
78	if (out->data == NULL && in->data != NULL) {
79		return -1;
80	}
81
82	return 0;
83}
84
85/*
86  default function for comparison
87*/
88static int ldb_default_cmp(struct ldb_context *ldb,
89			    void *mem_ctx,
90			   const struct ldb_val *v1,
91			   const struct ldb_val *v2)
92{
93	if (v1->length != v2->length) {
94		return v1->length - v2->length;
95	}
96	return memcmp(v1->data, v2->data, v1->length);
97}
98
99/*
100  default handler function pointers
101*/
102static const struct ldb_attrib_handler ldb_default_attrib_handler = {
103	.attr = NULL,
104	.ldif_read_fn    = ldb_default_copy,
105	.ldif_write_fn   = ldb_default_copy,
106	.canonicalise_fn = ldb_default_copy,
107	.comparison_fn   = ldb_default_cmp,
108};
109
110/*
111  return the attribute handlers for a given attribute
112*/
113const struct ldb_attrib_handler *ldb_attrib_handler(struct ldb_context *ldb,
114						    const char *attrib)
115{
116	int i;
117	const struct ldb_attrib_handler *def = &ldb_default_attrib_handler;
118	/* TODO: should be replaced with a binary search, with a sort on add */
119	for (i=0;i<ldb->schema.num_attrib_handlers;i++) {
120		if (strcmp(ldb->schema.attrib_handlers[i].attr, "*") == 0) {
121			def = &ldb->schema.attrib_handlers[i];
122		}
123		if (ldb_attr_cmp(attrib, ldb->schema.attrib_handlers[i].attr) == 0) {
124			return &ldb->schema.attrib_handlers[i];
125		}
126	}
127	return def;
128}
129
130
131/*
132  add to the list of ldif handlers for this ldb context
133*/
134void ldb_remove_attrib_handler(struct ldb_context *ldb, const char *attrib)
135{
136	const struct ldb_attrib_handler *h;
137	int i;
138	h = ldb_attrib_handler(ldb, attrib);
139	if (h == &ldb_default_attrib_handler) {
140		return;
141	}
142	if (h->flags & LDB_ATTR_FLAG_ALLOCATED) {
143		talloc_free(discard_const_p(char, h->attr));
144	}
145	i = h - ldb->schema.attrib_handlers;
146	if (i < ldb->schema.num_attrib_handlers - 1) {
147		memmove(&ldb->schema.attrib_handlers[i],
148			h+1, sizeof(*h) * (ldb->schema.num_attrib_handlers-(i+1)));
149	}
150	ldb->schema.num_attrib_handlers--;
151}
152
153/*
154  setup a attribute handler using a standard syntax
155*/
156int ldb_set_attrib_handler_syntax(struct ldb_context *ldb,
157				  const char *attr, const char *syntax)
158{
159	const struct ldb_attrib_handler *h = ldb_attrib_handler_syntax(ldb, syntax);
160	struct ldb_attrib_handler h2;
161	if (h == NULL) {
162		ldb_debug(ldb, LDB_DEBUG_ERROR, "Unknown syntax '%s'\n", syntax);
163		return -1;
164	}
165	h2 = *h;
166	h2.attr = attr;
167	return ldb_set_attrib_handlers(ldb, &h2, 1);
168}
169
170/*
171  setup the attribute handles for well known attributes
172*/
173int ldb_setup_wellknown_attributes(struct ldb_context *ldb)
174{
175	const struct {
176		const char *attr;
177		const char *syntax;
178	} wellknown[] = {
179		{ "dn", LDB_SYNTAX_DN },
180		{ "ncName", LDB_SYNTAX_DN },
181		{ "distinguishedName", LDB_SYNTAX_DN },
182		{ "cn", LDB_SYNTAX_DIRECTORY_STRING },
183		{ "dc", LDB_SYNTAX_DIRECTORY_STRING },
184		{ "ou", LDB_SYNTAX_DIRECTORY_STRING },
185		{ "objectClass", LDB_SYNTAX_OBJECTCLASS }
186	};
187	int i;
188	for (i=0;i<ARRAY_SIZE(wellknown);i++) {
189		if (ldb_set_attrib_handler_syntax(ldb, wellknown[i].attr,
190						  wellknown[i].syntax) != 0) {
191			return -1;
192		}
193	}
194	return 0;
195}
196
197
198/*
199  return the list of subclasses for a class
200*/
201const char **ldb_subclass_list(struct ldb_context *ldb, const char *classname)
202{
203	int i;
204	for (i=0;i<ldb->schema.num_classes;i++) {
205		if (ldb_attr_cmp(classname, ldb->schema.classes[i].name) == 0) {
206			return (const char **)ldb->schema.classes[i].subclasses;
207		}
208	}
209	return NULL;
210}
211
212
213/*
214  add a new subclass
215*/
216static int ldb_subclass_new(struct ldb_context *ldb, const char *classname, const char *subclass)
217{
218	struct ldb_subclass *s, *c;
219	s = talloc_realloc(ldb, ldb->schema.classes, struct ldb_subclass, ldb->schema.num_classes+1);
220	if (s == NULL) goto failed;
221
222	ldb->schema.classes = s;
223	c = &s[ldb->schema.num_classes];
224	c->name = talloc_strdup(s, classname);
225	if (c->name == NULL) goto failed;
226
227	c->subclasses = talloc_array(s, char *, 2);
228	if (c->subclasses == NULL) goto failed;
229
230	c->subclasses[0] = talloc_strdup(c->subclasses, subclass);
231	if (c->subclasses[0] == NULL) goto failed;
232	c->subclasses[1] = NULL;
233
234	ldb->schema.num_classes++;
235
236	return 0;
237failed:
238	ldb_oom(ldb);
239	return -1;
240}
241
242/*
243  add a subclass
244*/
245int ldb_subclass_add(struct ldb_context *ldb, const char *classname, const char *subclass)
246{
247	int i, n;
248	struct ldb_subclass *c;
249	char **s;
250
251	for (i=0;i<ldb->schema.num_classes;i++) {
252		if (ldb_attr_cmp(classname, ldb->schema.classes[i].name) == 0) {
253			break;
254		}
255	}
256	if (i == ldb->schema.num_classes) {
257		return ldb_subclass_new(ldb, classname, subclass);
258	}
259	c = &ldb->schema.classes[i];
260
261	for (n=0;c->subclasses[n];n++) /* noop */;
262
263	s = talloc_realloc(ldb->schema.classes, c->subclasses, char *, n+2);
264	if (s == NULL) {
265		ldb_oom(ldb);
266		return -1;
267	}
268
269	c->subclasses = s;
270	s[n] = talloc_strdup(s, subclass);
271	if (s[n] == NULL) {
272		ldb_oom(ldb);
273		return -1;
274	}
275	s[n+1] = NULL;
276
277	return 0;
278}
279
280/*
281  remove a set of subclasses for a class
282*/
283void ldb_subclass_remove(struct ldb_context *ldb, const char *classname)
284{
285	int i;
286	struct ldb_subclass *c;
287
288	for (i=0;i<ldb->schema.num_classes;i++) {
289		if (ldb_attr_cmp(classname, ldb->schema.classes[i].name) == 0) {
290			break;
291		}
292	}
293	if (i == ldb->schema.num_classes) {
294		return;
295	}
296
297	c = &ldb->schema.classes[i];
298	talloc_free(c->name);
299	talloc_free(c->subclasses);
300	if (ldb->schema.num_classes-(i+1) > 0) {
301		memmove(c, c+1, sizeof(*c) * (ldb->schema.num_classes-(i+1)));
302	}
303	ldb->schema.num_classes--;
304	if (ldb->schema.num_classes == 0) {
305		talloc_free(ldb->schema.classes);
306		ldb->schema.classes = NULL;
307	}
308}
309