/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- dsdb_attribute_by_attributeID_id
- dsdb_attribute_by_attributeID_oid
- dsdb_attribute_by_lDAPDisplayName
- dsdb_attribute_by_linkID
- dsdb_class_by_governsID_id
- dsdb_class_by_governsID_oid
- dsdb_class_by_lDAPDisplayName
- dsdb_class_by_cn
- dsdb_lDAPDisplayName_by_id
- dsdb_linked_attribute_lDAPDisplayName_list
- merge_attr_list
- dsdb_attribute_list
- dsdb_full_attribute_list_internal
- dsdb_full_attribute_list
1 /*
2 Unix SMB/CIFS mplementation.
3 DSDB schema header
4
5 Copyright (C) Stefan Metzmacher <metze@samba.org> 2006-2007
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006-2008
7
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.
12
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.
17
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/>.
20
21 */
22
23 #include "includes.h"
24 #include "dsdb/samdb/samdb.h"
25
26 const struct dsdb_attribute *dsdb_attribute_by_attributeID_id(const struct dsdb_schema *schema,
/* [<][>][^][v][top][bottom][index][help] */
27 uint32_t id)
28 {
29 struct dsdb_attribute *cur;
30
31 /*
32 * 0xFFFFFFFF is used as value when no mapping table is available,
33 * so don't try to match with it
34 */
35 if (id == 0xFFFFFFFF) return NULL;
36
37 /* TODO: add binary search */
38 for (cur = schema->attributes; cur; cur = cur->next) {
39 if (cur->attributeID_id != id) continue;
40
41 return cur;
42 }
43
44 return NULL;
45 }
46
47 const struct dsdb_attribute *dsdb_attribute_by_attributeID_oid(const struct dsdb_schema *schema,
/* [<][>][^][v][top][bottom][index][help] */
48 const char *oid)
49 {
50 struct dsdb_attribute *cur;
51
52 if (!oid) return NULL;
53
54 /* TODO: add binary search */
55 for (cur = schema->attributes; cur; cur = cur->next) {
56 if (strcmp(cur->attributeID_oid, oid) != 0) continue;
57
58 return cur;
59 }
60
61 return NULL;
62 }
63
64 const struct dsdb_attribute *dsdb_attribute_by_lDAPDisplayName(const struct dsdb_schema *schema,
/* [<][>][^][v][top][bottom][index][help] */
65 const char *name)
66 {
67 struct dsdb_attribute *cur;
68
69 if (!name) return NULL;
70
71 /* TODO: add binary search */
72 for (cur = schema->attributes; cur; cur = cur->next) {
73 if (strcasecmp(cur->lDAPDisplayName, name) != 0) continue;
74
75 return cur;
76 }
77
78 return NULL;
79 }
80
81 const struct dsdb_attribute *dsdb_attribute_by_linkID(const struct dsdb_schema *schema,
/* [<][>][^][v][top][bottom][index][help] */
82 int linkID)
83 {
84 struct dsdb_attribute *cur;
85
86 /* TODO: add binary search */
87 for (cur = schema->attributes; cur; cur = cur->next) {
88 if (cur->linkID != linkID) continue;
89
90 return cur;
91 }
92
93 return NULL;
94 }
95
96 const struct dsdb_class *dsdb_class_by_governsID_id(const struct dsdb_schema *schema,
/* [<][>][^][v][top][bottom][index][help] */
97 uint32_t id)
98 {
99 struct dsdb_class *cur;
100
101 /*
102 * 0xFFFFFFFF is used as value when no mapping table is available,
103 * so don't try to match with it
104 */
105 if (id == 0xFFFFFFFF) return NULL;
106
107 /* TODO: add binary search */
108 for (cur = schema->classes; cur; cur = cur->next) {
109 if (cur->governsID_id != id) continue;
110
111 return cur;
112 }
113
114 return NULL;
115 }
116
117 const struct dsdb_class *dsdb_class_by_governsID_oid(const struct dsdb_schema *schema,
/* [<][>][^][v][top][bottom][index][help] */
118 const char *oid)
119 {
120 struct dsdb_class *cur;
121
122 if (!oid) return NULL;
123
124 /* TODO: add binary search */
125 for (cur = schema->classes; cur; cur = cur->next) {
126 if (strcmp(cur->governsID_oid, oid) != 0) continue;
127
128 return cur;
129 }
130
131 return NULL;
132 }
133
134 const struct dsdb_class *dsdb_class_by_lDAPDisplayName(const struct dsdb_schema *schema,
/* [<][>][^][v][top][bottom][index][help] */
135 const char *name)
136 {
137 struct dsdb_class *cur;
138
139 if (!name) return NULL;
140
141 /* TODO: add binary search */
142 for (cur = schema->classes; cur; cur = cur->next) {
143 if (strcasecmp(cur->lDAPDisplayName, name) != 0) continue;
144
145 return cur;
146 }
147
148 return NULL;
149 }
150
151 const struct dsdb_class *dsdb_class_by_cn(const struct dsdb_schema *schema,
/* [<][>][^][v][top][bottom][index][help] */
152 const char *cn)
153 {
154 struct dsdb_class *cur;
155
156 if (!cn) return NULL;
157
158 /* TODO: add binary search */
159 for (cur = schema->classes; cur; cur = cur->next) {
160 if (strcasecmp(cur->cn, cn) != 0) continue;
161
162 return cur;
163 }
164
165 return NULL;
166 }
167
168 const char *dsdb_lDAPDisplayName_by_id(const struct dsdb_schema *schema,
/* [<][>][^][v][top][bottom][index][help] */
169 uint32_t id)
170 {
171 const struct dsdb_attribute *a;
172 const struct dsdb_class *c;
173
174 /* TODO: add binary search */
175 a = dsdb_attribute_by_attributeID_id(schema, id);
176 if (a) {
177 return a->lDAPDisplayName;
178 }
179
180 c = dsdb_class_by_governsID_id(schema, id);
181 if (c) {
182 return c->lDAPDisplayName;
183 }
184
185 return NULL;
186 }
187
188 /**
189 Return a list of linked attributes, in lDAPDisplayName format.
190
191 This may be used to determine if a modification would require
192 backlinks to be updated, for example
193 */
194
195 WERROR dsdb_linked_attribute_lDAPDisplayName_list(const struct dsdb_schema *schema, TALLOC_CTX *mem_ctx, const char ***attr_list_ret)
/* [<][>][^][v][top][bottom][index][help] */
196 {
197 const char **attr_list = NULL;
198 struct dsdb_attribute *cur;
199 int i = 0;
200 for (cur = schema->attributes; cur; cur = cur->next) {
201 if (cur->linkID == 0) continue;
202
203 attr_list = talloc_realloc(mem_ctx, attr_list, const char *, i+2);
204 if (!attr_list) {
205 return WERR_NOMEM;
206 }
207 attr_list[i] = cur->lDAPDisplayName;
208 i++;
209 }
210 attr_list[i] = NULL;
211 *attr_list_ret = attr_list;
212 return WERR_OK;
213 }
214
215 const char **merge_attr_list(TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
216 const char **attrs, const char * const*new_attrs)
217 {
218 const char **ret_attrs;
219 int i;
220 size_t new_len, orig_len = str_list_length(attrs);
221 if (!new_attrs) {
222 return attrs;
223 }
224
225 ret_attrs = talloc_realloc(mem_ctx,
226 attrs, const char *, orig_len + str_list_length(new_attrs) + 1);
227 if (ret_attrs) {
228 for (i=0; i < str_list_length(new_attrs); i++) {
229 ret_attrs[orig_len + i] = new_attrs[i];
230 }
231 new_len = orig_len + str_list_length(new_attrs);
232
233 ret_attrs[new_len] = NULL;
234 }
235
236 return ret_attrs;
237 }
238
239 /*
240 Return a merged list of the attributes of exactly one class (not
241 considering subclasses, auxillary classes etc)
242 */
243
244 const char **dsdb_attribute_list(TALLOC_CTX *mem_ctx, const struct dsdb_class *sclass, enum dsdb_attr_list_query query)
/* [<][>][^][v][top][bottom][index][help] */
245 {
246 const char **attr_list = NULL;
247 switch (query) {
248 case DSDB_SCHEMA_ALL_MAY:
249 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->mayContain);
250 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->systemMayContain);
251 break;
252
253 case DSDB_SCHEMA_ALL_MUST:
254 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->mustContain);
255 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->systemMustContain);
256 break;
257
258 case DSDB_SCHEMA_SYS_MAY:
259 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->systemMayContain);
260 break;
261
262 case DSDB_SCHEMA_SYS_MUST:
263 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->systemMustContain);
264 break;
265
266 case DSDB_SCHEMA_MAY:
267 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->mayContain);
268 break;
269
270 case DSDB_SCHEMA_MUST:
271 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->mustContain);
272 break;
273
274 case DSDB_SCHEMA_ALL:
275 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->mayContain);
276 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->systemMayContain);
277 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->mustContain);
278 attr_list = merge_attr_list(mem_ctx, attr_list, sclass->systemMustContain);
279 break;
280 }
281 return attr_list;
282 }
283
284 static const char **dsdb_full_attribute_list_internal(TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
285 const struct dsdb_schema *schema,
286 const char **class_list,
287 enum dsdb_attr_list_query query)
288 {
289 int i;
290 const struct dsdb_class *sclass;
291
292 const char **attr_list = NULL;
293 const char **this_class_list;
294 const char **recursive_list;
295
296 for (i=0; class_list && class_list[i]; i++) {
297 sclass = dsdb_class_by_lDAPDisplayName(schema, class_list[i]);
298
299 this_class_list = dsdb_attribute_list(mem_ctx, sclass, query);
300 attr_list = merge_attr_list(mem_ctx, attr_list, this_class_list);
301
302 recursive_list = dsdb_full_attribute_list_internal(mem_ctx, schema,
303 sclass->systemAuxiliaryClass,
304 query);
305
306 attr_list = merge_attr_list(mem_ctx, attr_list, recursive_list);
307
308 recursive_list = dsdb_full_attribute_list_internal(mem_ctx, schema,
309 sclass->auxiliaryClass,
310 query);
311
312 attr_list = merge_attr_list(mem_ctx, attr_list, recursive_list);
313
314 }
315 return attr_list;
316 }
317
318 const char **dsdb_full_attribute_list(TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
319 const struct dsdb_schema *schema,
320 const char **class_list,
321 enum dsdb_attr_list_query query)
322 {
323 const char **attr_list = dsdb_full_attribute_list_internal(mem_ctx, schema, class_list, query);
324 size_t new_len = str_list_length(attr_list);
325
326 /* Remove duplicates */
327 if (new_len > 1) {
328 int i;
329 qsort(attr_list, new_len,
330 sizeof(*attr_list),
331 (comparison_fn_t)strcasecmp);
332
333 for (i=1 ; i < new_len; i++) {
334 const char **val1 = &attr_list[i-1];
335 const char **val2 = &attr_list[i];
336 if (ldb_attr_cmp(*val1, *val2) == 0) {
337 memmove(val1, val2, (new_len - i) * sizeof( *attr_list));
338 new_len--;
339 i--;
340 }
341 }
342 }
343 return attr_list;
344 }