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
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
32 #include "ldb/include/includes.h"
35 add to the list of ldif handlers for this ldb context
37 int ldb_set_attrib_handlers(struct ldb_context
*ldb
,
38 const struct ldb_attrib_handler
*handlers
,
39 unsigned num_handlers
)
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
);
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
) {
63 ldb
->schema
.num_attrib_handlers
+= num_handlers
;
69 default function for read/write/canonicalise
71 static int ldb_default_copy(struct ldb_context
*ldb
,
73 const struct ldb_val
*in
,
76 *out
= ldb_val_dup(mem_ctx
, in
);
78 if (out
->data
== NULL
&& in
->data
!= NULL
) {
86 default function for comparison
88 static int ldb_default_cmp(struct ldb_context
*ldb
,
90 const struct ldb_val
*v1
,
91 const struct ldb_val
*v2
)
93 if (v1
->length
!= v2
->length
) {
94 return v1
->length
- v2
->length
;
96 return memcmp(v1
->data
, v2
->data
, v1
->length
);
100 default handler function pointers
102 static const struct ldb_attrib_handler ldb_default_attrib_handler
= {
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
,
111 return the attribute handlers for a given attribute
113 const struct ldb_attrib_handler
*ldb_attrib_handler(struct ldb_context
*ldb
,
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
];
123 if (ldb_attr_cmp(attrib
, ldb
->schema
.attrib_handlers
[i
].attr
) == 0) {
124 return &ldb
->schema
.attrib_handlers
[i
];
132 add to the list of ldif handlers for this ldb context
134 void ldb_remove_attrib_handler(struct ldb_context
*ldb
, const char *attrib
)
136 const struct ldb_attrib_handler
*h
;
138 h
= ldb_attrib_handler(ldb
, attrib
);
139 if (h
== &ldb_default_attrib_handler
) {
142 if (h
->flags
& LDB_ATTR_FLAG_ALLOCATED
) {
143 talloc_free(discard_const_p(char, h
->attr
));
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)));
150 ldb
->schema
.num_attrib_handlers
--;
154 setup a attribute handler using a standard syntax
156 int ldb_set_attrib_handler_syntax(struct ldb_context
*ldb
,
157 const char *attr
, const char *syntax
)
159 const struct ldb_attrib_handler
*h
= ldb_attrib_handler_syntax(ldb
, syntax
);
160 struct ldb_attrib_handler h2
;
162 ldb_debug(ldb
, LDB_DEBUG_ERROR
, "Unknown syntax '%s'\n", syntax
);
167 return ldb_set_attrib_handlers(ldb
, &h2
, 1);
171 setup the attribute handles for well known attributes
173 int ldb_setup_wellknown_attributes(struct ldb_context
*ldb
)
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
}
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) {
199 return the list of subclasses for a class
201 const char **ldb_subclass_list(struct ldb_context
*ldb
, const char *classname
)
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
;
216 static int ldb_subclass_new(struct ldb_context
*ldb
, const char *classname
, const char *subclass
)
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
;
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
;
227 c
->subclasses
= talloc_array(s
, char *, 2);
228 if (c
->subclasses
== NULL
) goto failed
;
230 c
->subclasses
[0] = talloc_strdup(c
->subclasses
, subclass
);
231 if (c
->subclasses
[0] == NULL
) goto failed
;
232 c
->subclasses
[1] = NULL
;
234 ldb
->schema
.num_classes
++;
245 int ldb_subclass_add(struct ldb_context
*ldb
, const char *classname
, const char *subclass
)
248 struct ldb_subclass
*c
;
251 for (i
=0;i
<ldb
->schema
.num_classes
;i
++) {
252 if (ldb_attr_cmp(classname
, ldb
->schema
.classes
[i
].name
) == 0) {
256 if (i
== ldb
->schema
.num_classes
) {
257 return ldb_subclass_new(ldb
, classname
, subclass
);
259 c
= &ldb
->schema
.classes
[i
];
261 for (n
=0;c
->subclasses
[n
];n
++) /* noop */;
263 s
= talloc_realloc(ldb
->schema
.classes
, c
->subclasses
, char *, n
+2);
270 s
[n
] = talloc_strdup(s
, subclass
);
281 remove a set of subclasses for a class
283 void ldb_subclass_remove(struct ldb_context
*ldb
, const char *classname
)
286 struct ldb_subclass
*c
;
288 for (i
=0;i
<ldb
->schema
.num_classes
;i
++) {
289 if (ldb_attr_cmp(classname
, ldb
->schema
.classes
[i
].name
) == 0) {
293 if (i
== ldb
->schema
.num_classes
) {
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)));
303 ldb
->schema
.num_classes
--;
304 if (ldb
->schema
.num_classes
== 0) {
305 talloc_free(ldb
->schema
.classes
);
306 ldb
->schema
.classes
= NULL
;