2 Unix SMB/CIFS mplementation.
5 Copyright (C) Stefan Metzmacher <metze@samba.org> 2006-2007
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006-2008
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "dsdb/samdb/samdb.h"
26 const struct dsdb_attribute *dsdb_attribute_by_attributeID_id(const struct dsdb_schema *schema,
29 struct dsdb_attribute *cur;
32 * 0xFFFFFFFF is used as value when no mapping table is available,
33 * so don't try to match with it
35 if (id == 0xFFFFFFFF) return NULL;
37 /* TODO: add binary search */
38 for (cur = schema->attributes; cur; cur = cur->next) {
39 if (cur->attributeID_id != id) continue;
47 const struct dsdb_attribute *dsdb_attribute_by_attributeID_oid(const struct dsdb_schema *schema,
50 struct dsdb_attribute *cur;
52 if (!oid) return NULL;
54 /* TODO: add binary search */
55 for (cur = schema->attributes; cur; cur = cur->next) {
56 if (strcmp(cur->attributeID_oid, oid) != 0) continue;
64 const struct dsdb_attribute *dsdb_attribute_by_lDAPDisplayName(const struct dsdb_schema *schema,
67 struct dsdb_attribute *cur;
69 if (!name) return NULL;
71 /* TODO: add binary search */
72 for (cur = schema->attributes; cur; cur = cur->next) {
73 if (strcasecmp(cur->lDAPDisplayName, name) != 0) continue;
81 const struct dsdb_attribute *dsdb_attribute_by_linkID(const struct dsdb_schema *schema,
84 struct dsdb_attribute *cur;
86 /* TODO: add binary search */
87 for (cur = schema->attributes; cur; cur = cur->next) {
88 if (cur->linkID != linkID) continue;
96 const struct dsdb_class *dsdb_class_by_governsID_id(const struct dsdb_schema *schema,
99 struct dsdb_class *cur;
102 * 0xFFFFFFFF is used as value when no mapping table is available,
103 * so don't try to match with it
105 if (id == 0xFFFFFFFF) return NULL;
107 /* TODO: add binary search */
108 for (cur = schema->classes; cur; cur = cur->next) {
109 if (cur->governsID_id != id) continue;
117 const struct dsdb_class *dsdb_class_by_governsID_oid(const struct dsdb_schema *schema,
120 struct dsdb_class *cur;
122 if (!oid) return NULL;
124 /* TODO: add binary search */
125 for (cur = schema->classes; cur; cur = cur->next) {
126 if (strcmp(cur->governsID_oid, oid) != 0) continue;
134 const struct dsdb_class *dsdb_class_by_lDAPDisplayName(const struct dsdb_schema *schema,
137 struct dsdb_class *cur;
139 if (!name) return NULL;
141 /* TODO: add binary search */
142 for (cur = schema->classes; cur; cur = cur->next) {
143 if (strcasecmp(cur->lDAPDisplayName, name) != 0) continue;
151 const struct dsdb_class *dsdb_class_by_cn(const struct dsdb_schema *schema,
154 struct dsdb_class *cur;
156 if (!cn) return NULL;
158 /* TODO: add binary search */
159 for (cur = schema->classes; cur; cur = cur->next) {
160 if (strcasecmp(cur->cn, cn) != 0) continue;
168 const char *dsdb_lDAPDisplayName_by_id(const struct dsdb_schema *schema,
171 const struct dsdb_attribute *a;
172 const struct dsdb_class *c;
174 /* TODO: add binary search */
175 a = dsdb_attribute_by_attributeID_id(schema, id);
177 return a->lDAPDisplayName;
180 c = dsdb_class_by_governsID_id(schema, id);
182 return c->lDAPDisplayName;
189 Return a list of linked attributes, in lDAPDisplayName format.
191 This may be used to determine if a modification would require
192 backlinks to be updated, for example
195 WERROR dsdb_linked_attribute_lDAPDisplayName_list(const struct dsdb_schema *schema, TALLOC_CTX *mem_ctx, const char ***attr_list_ret)
197 const char **attr_list = NULL;
198 struct dsdb_attribute *cur;
200 for (cur = schema->attributes; cur; cur = cur->next) {
201 if (cur->linkID == 0) continue;
203 attr_list = talloc_realloc(mem_ctx, attr_list, const char *, i+2);
207 attr_list[i] = cur->lDAPDisplayName;
211 *attr_list_ret = attr_list;
215 char **merge_attr_list(TALLOC_CTX *mem_ctx,
216 char **attrs, const char **new_attrs)
220 size_t new_len, orig_len = str_list_length((const char **)attrs);
225 ret_attrs = talloc_realloc(mem_ctx,
226 attrs, char *, orig_len + str_list_length(new_attrs) + 1);
228 for (i=0; i < str_list_length(new_attrs); i++) {
229 ret_attrs[orig_len + i] = new_attrs[i];
231 new_len = orig_len + str_list_length(new_attrs);
233 ret_attrs[new_len] = NULL;
240 Return a merged list of the attributes of exactly one class (not
241 considering subclasses, auxillary classes etc)
244 char **dsdb_attribute_list(TALLOC_CTX *mem_ctx, const struct dsdb_class *class, enum dsdb_attr_list_query query)
246 char **attr_list = NULL;
248 case DSDB_SCHEMA_ALL_MAY:
249 attr_list = merge_attr_list(mem_ctx, attr_list, class->mayContain);
250 attr_list = merge_attr_list(mem_ctx, attr_list, class->systemMayContain);
253 case DSDB_SCHEMA_ALL_MUST:
254 attr_list = merge_attr_list(mem_ctx, attr_list, class->mustContain);
255 attr_list = merge_attr_list(mem_ctx, attr_list, class->systemMustContain);
258 case DSDB_SCHEMA_SYS_MAY:
259 attr_list = merge_attr_list(mem_ctx, attr_list, class->systemMayContain);
262 case DSDB_SCHEMA_SYS_MUST:
263 attr_list = merge_attr_list(mem_ctx, attr_list, class->systemMustContain);
266 case DSDB_SCHEMA_MAY:
267 attr_list = merge_attr_list(mem_ctx, attr_list, class->mayContain);
270 case DSDB_SCHEMA_MUST:
271 attr_list = merge_attr_list(mem_ctx, attr_list, class->mustContain);
274 case DSDB_SCHEMA_ALL:
275 attr_list = merge_attr_list(mem_ctx, attr_list, class->mayContain);
276 attr_list = merge_attr_list(mem_ctx, attr_list, class->systemMayContain);
277 attr_list = merge_attr_list(mem_ctx, attr_list, class->mustContain);
278 attr_list = merge_attr_list(mem_ctx, attr_list, class->systemMustContain);
284 static char **dsdb_full_attribute_list_internal(TALLOC_CTX *mem_ctx,
285 const struct dsdb_schema *schema,
286 const char **class_list,
287 enum dsdb_attr_list_query query)
290 const struct dsdb_class *class;
292 char **attr_list = NULL;
293 char **this_class_list;
294 char **recursive_list;
296 for (i=0; class_list && class_list[i]; i++) {
297 class = dsdb_class_by_lDAPDisplayName(schema, class_list[i]);
299 this_class_list = dsdb_attribute_list(mem_ctx, class, query);
300 attr_list = merge_attr_list(mem_ctx, attr_list, (const char **)this_class_list);
302 recursive_list = dsdb_full_attribute_list_internal(mem_ctx, schema,
303 class->systemAuxiliaryClass,
306 attr_list = merge_attr_list(mem_ctx, attr_list, (const char **)recursive_list);
308 recursive_list = dsdb_full_attribute_list_internal(mem_ctx, schema,
309 class->auxiliaryClass,
312 attr_list = merge_attr_list(mem_ctx, attr_list, (const char **)recursive_list);
318 char **dsdb_full_attribute_list(TALLOC_CTX *mem_ctx,
319 const struct dsdb_schema *schema,
320 const char **class_list,
321 enum dsdb_attr_list_query query)
323 char **attr_list = dsdb_full_attribute_list_internal(mem_ctx, schema, class_list, query);
324 size_t new_len = str_list_length((const char **)attr_list);
326 /* Remove duplicates */
329 qsort(attr_list, new_len,
331 (comparison_fn_t)strcasecmp);
333 for (i=1 ; i < new_len; i++) {
334 char **val1 = &attr_list[i-1];
335 char **val2 = &attr_list[i];
336 if (ldb_attr_cmp(*val1, *val2) == 0) {
337 memmove(val1, val2, (new_len - i) * sizeof( *attr_list));