]> git.samba.org - kai/samba-autobuild/.git/blob - source4/dsdb/schema/schema_init.c
r20439: this should be const pointers
[kai/samba-autobuild/.git] / source4 / dsdb / schema / schema_init.c
1 /* 
2    Unix SMB/CIFS mplementation.
3    DSDB schema header
4    
5    Copyright (C) Stefan Metzmacher 2006
6     
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21 */
22
23 #include "includes.h"
24 #include "dsdb/samdb/samdb.h"
25 #include "lib/util/dlinklist.h"
26 #include "librpc/gen_ndr/drsuapi.h"
27
28 WERROR dsdb_load_oid_mappings(struct dsdb_schema *schema, const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr)
29 {
30         uint32_t i,j;
31
32         schema->prefixes = talloc_array(schema, struct dsdb_schema_oid_prefix, ctr->num_mappings);
33         W_ERROR_HAVE_NO_MEMORY(schema->prefixes);
34
35         for (i=0, j=0; i < ctr->num_mappings; i++) {
36                 if (ctr->mappings[i].oid.oid == NULL) {
37                         return WERR_INVALID_PARAM;
38                 }
39
40                 if (strncasecmp(ctr->mappings[i].oid.oid, "ff", 2) == 0) {
41                         if (ctr->mappings[i].id_prefix != 0) {
42                                 return WERR_INVALID_PARAM;
43                         }
44
45                         /* the magic value should be in the last array member */
46                         if (i != (ctr->num_mappings - 1)) {
47                                 return WERR_INVALID_PARAM;
48                         }
49
50                         if (ctr->mappings[i].oid.__ndr_size != 21) {
51                                 return WERR_INVALID_PARAM;
52                         }
53
54                         schema->schema_info = talloc_strdup(schema, ctr->mappings[i].oid.oid);
55                         W_ERROR_HAVE_NO_MEMORY(schema->schema_info);
56                 } else {
57                         /* the last array member should contain the magic value not a oid */
58                         if (i == (ctr->num_mappings - 1)) {
59                                 return WERR_INVALID_PARAM;
60                         }
61
62                         schema->prefixes[j].id  = ctr->mappings[i].id_prefix<<16;
63                         schema->prefixes[j].oid = talloc_asprintf(schema->prefixes, "%s.",
64                                                                   ctr->mappings[i].oid.oid);
65                         W_ERROR_HAVE_NO_MEMORY(schema->prefixes[j].oid);
66                         schema->prefixes[j].oid_len = strlen(schema->prefixes[j].oid);
67                         j++;
68                 }
69         }
70
71         schema->num_prefixes = j;
72         return WERR_OK;
73 }
74
75 WERROR dsdb_verify_oid_mappings(const struct dsdb_schema *schema, const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr)
76 {
77         uint32_t i,j;
78
79         for (i=0; i < ctr->num_mappings; i++) {
80                 if (ctr->mappings[i].oid.oid == NULL) {
81                         return WERR_INVALID_PARAM;
82                 }
83
84                 if (strncasecmp(ctr->mappings[i].oid.oid, "ff", 2) == 0) {
85                         if (ctr->mappings[i].id_prefix != 0) {
86                                 return WERR_INVALID_PARAM;
87                         }
88
89                         /* the magic value should be in the last array member */
90                         if (i != (ctr->num_mappings - 1)) {
91                                 return WERR_INVALID_PARAM;
92                         }
93
94                         if (ctr->mappings[i].oid.__ndr_size != 21) {
95                                 return WERR_INVALID_PARAM;
96                         }
97
98                         if (strcasecmp(schema->schema_info, ctr->mappings[i].oid.oid) != 0) {
99                                 return WERR_DS_DRA_SCHEMA_MISMATCH;
100                         }
101                 } else {
102                         /* the last array member should contain the magic value not a oid */
103                         if (i == (ctr->num_mappings - 1)) {
104                                 return WERR_INVALID_PARAM;
105                         }
106
107                         for (j=0; j < schema->num_prefixes; j++) {
108                                 size_t oid_len;
109                                 if (schema->prefixes[j].id != (ctr->mappings[i].id_prefix<<16)) {
110                                         continue;
111                                 }
112
113                                 oid_len = strlen(ctr->mappings[i].oid.oid);
114
115                                 if (oid_len != (schema->prefixes[j].oid_len - 1)) {
116                                         return WERR_DS_DRA_SCHEMA_MISMATCH;
117                                 }
118
119                                 if (strncmp(ctr->mappings[i].oid.oid, schema->prefixes[j].oid, oid_len) != 0) {
120                                         return WERR_DS_DRA_SCHEMA_MISMATCH;                             
121                                 }
122
123                                 break;
124                         }
125
126                         if (j == schema->num_prefixes) {
127                                 return WERR_DS_DRA_SCHEMA_MISMATCH;                             
128                         }
129                 }
130         }
131
132         return WERR_OK;
133 }
134
135 WERROR dsdb_map_oid2int(const struct dsdb_schema *schema, const char *in, uint32_t *out)
136 {
137         uint32_t i;
138
139         for (i=0; i < schema->num_prefixes; i++) {
140                 const char *val_str;
141                 char *end_str;
142                 unsigned val;
143
144                 if (strncmp(schema->prefixes[i].oid, in, schema->prefixes[i].oid_len) != 0) {
145                         continue;
146                 }
147
148                 val_str = in + schema->prefixes[i].oid_len;
149                 end_str = NULL;
150                 errno = 0;
151
152                 if (val_str[0] == '\0') {
153                         return WERR_INVALID_PARAM;
154                 }
155
156                 /* two '.' chars are invalid */
157                 if (val_str[0] == '.') {
158                         return WERR_INVALID_PARAM;
159                 }
160
161                 val = strtoul(val_str, &end_str, 10);
162                 if (end_str[0] == '.' && end_str[1] != '\0') {
163                         /*
164                          * if it's a '.' and not the last char
165                          * then maybe an other mapping apply
166                          */
167                         continue;
168                 } else if (end_str[0] != '\0') {
169                         return WERR_INVALID_PARAM;
170                 } else if (val > 0xFFFF) {
171                         return WERR_INVALID_PARAM;
172                 }
173
174                 *out = schema->prefixes[i].id | val;
175                 return WERR_OK;
176         }
177
178         return WERR_DS_NO_MSDS_INTID;
179 }
180
181 WERROR dsdb_map_int2oid(const struct dsdb_schema *schema, uint32_t in, TALLOC_CTX *mem_ctx, const char **out)
182 {
183         uint32_t i;
184
185         for (i=0; i < schema->num_prefixes; i++) {
186                 const char *val;
187                 if (schema->prefixes[i].id != (in & 0xFFFF0000)) {
188                         continue;
189                 }
190
191                 val = talloc_asprintf(mem_ctx, "%s%u",
192                                       schema->prefixes[i].oid,
193                                       in & 0xFFFF);
194                 W_ERROR_HAVE_NO_MEMORY(val);
195
196                 *out = val;
197                 return WERR_OK;
198         }
199
200         return WERR_DS_NO_MSDS_INTID;
201 }
202
203 #define GET_STRING_LDB(msg, attr, mem_ctx, p, elem, strict) do { \
204         (p)->elem = samdb_result_string(msg, attr, NULL);\
205         if (strict && (p)->elem == NULL) { \
206                 d_printf("%s: %s == NULL\n", __location__, attr); \
207                 return WERR_INVALID_PARAM; \
208         } \
209         talloc_steal(mem_ctx, (p)->elem); \
210 } while (0)
211
212 #define GET_BOOL_LDB(msg, attr, p, elem, strict) do { \
213         const char *str; \
214         str = samdb_result_string(msg, attr, NULL);\
215         if (str == NULL) { \
216                 if (strict) { \
217                         d_printf("%s: %s == NULL\n", __location__, attr); \
218                         return WERR_INVALID_PARAM; \
219                 } else { \
220                         (p)->elem = False; \
221                 } \
222         } else if (strcasecmp("TRUE", str) == 0) { \
223                 (p)->elem = True; \
224         } else if (strcasecmp("FALSE", str) == 0) { \
225                 (p)->elem = False; \
226         } else { \
227                 d_printf("%s: %s == %s\n", __location__, attr, str); \
228                 return WERR_INVALID_PARAM; \
229         } \
230 } while (0)
231
232 #define GET_UINT32_LDB(msg, attr, p, elem) do { \
233         (p)->elem = samdb_result_uint(msg, attr, 0);\
234 } while (0)
235
236 #define GET_GUID_LDB(msg, attr, p, elem) do { \
237         (p)->elem = samdb_result_guid(msg, attr);\
238 } while (0)
239
240 #define GET_BLOB_LDB(msg, attr, mem_ctx, p, elem) do { \
241         const struct ldb_val *_val;\
242         _val = ldb_msg_find_ldb_val(msg, attr);\
243         if (_val) {\
244                 (p)->elem = *_val;\
245                 talloc_steal(mem_ctx, (p)->elem.data);\
246         } else {\
247                 ZERO_STRUCT((p)->elem);\
248         }\
249 } while (0)
250
251 WERROR dsdb_attribute_from_ldb(struct ldb_message *msg, TALLOC_CTX *mem_ctx, struct dsdb_attribute *attr)
252 {
253         GET_STRING_LDB(msg, "cn", mem_ctx, attr, cn, True);
254         GET_STRING_LDB(msg, "lDAPDisplayName", mem_ctx, attr, lDAPDisplayName, True);
255         GET_STRING_LDB(msg, "attributeID", mem_ctx, attr, attributeID_oid, True);
256         /* set an invalid value */
257         attr->attributeID_id = 0xFFFFFFFF;
258         GET_GUID_LDB(msg, "schemaIDGUID", attr, schemaIDGUID);
259         GET_UINT32_LDB(msg, "mAPIID", attr, mAPIID);
260
261         GET_GUID_LDB(msg, "attributeSecurityGUID", attr, attributeSecurityGUID);
262
263         GET_UINT32_LDB(msg, "searchFlags", attr, searchFlags);
264         GET_UINT32_LDB(msg, "systemFlags", attr, systemFlags);
265         GET_BOOL_LDB(msg, "isMemberOfPartialAttributeSet", attr, isMemberOfPartialAttributeSet, False);
266         GET_UINT32_LDB(msg, "linkID", attr, linkID);
267
268         GET_STRING_LDB(msg, "attributeSyntax", mem_ctx, attr, attributeSyntax_oid, True);
269         /* set an invalid value */
270         attr->attributeSyntax_id = 0xFFFFFFFF;
271         GET_UINT32_LDB(msg, "oMSyntax", attr, oMSyntax);
272         GET_BLOB_LDB(msg, "oMObjectClass", mem_ctx, attr, oMObjectClass);
273
274         GET_BOOL_LDB(msg, "isSingleValued", attr, isSingleValued, True);
275         GET_UINT32_LDB(msg, "rangeLower", attr, rangeLower);
276         GET_UINT32_LDB(msg, "rangeUpper", attr, rangeUpper);
277         GET_BOOL_LDB(msg, "extendedCharsAllowed", attr, extendedCharsAllowed, False);
278
279         GET_UINT32_LDB(msg, "schemaFlagsEx", attr, schemaFlagsEx);
280         GET_BLOB_LDB(msg, "msDs-Schema-Extensions", mem_ctx, attr, msDs_Schema_Extensions);
281
282         GET_BOOL_LDB(msg, "showInAdvancedViewOnly", attr, showInAdvancedViewOnly, False);
283         GET_STRING_LDB(msg, "adminDisplayName", mem_ctx, attr, adminDisplayName, False);
284         GET_STRING_LDB(msg, "adminDescription", mem_ctx, attr, adminDescription, False);
285         GET_STRING_LDB(msg, "classDisplayName", mem_ctx, attr, classDisplayName, False);
286         GET_BOOL_LDB(msg, "isEphemeral", attr, isEphemeral, False);
287         GET_BOOL_LDB(msg, "isDefunct", attr, isDefunct, False);
288         GET_BOOL_LDB(msg, "systemOnly", attr, systemOnly, False);
289
290         attr->syntax = dsdb_syntax_for_attribute(attr);
291         if (!attr->syntax) {
292                 return WERR_DS_ATT_SCHEMA_REQ_SYNTAX;
293         }
294
295         return WERR_OK;
296 }
297
298 WERROR dsdb_class_from_ldb(struct ldb_message *msg, TALLOC_CTX *mem_ctx, struct dsdb_class *obj)
299 {
300         GET_STRING_LDB(msg, "cn", mem_ctx, obj, cn, True);
301         GET_STRING_LDB(msg, "lDAPDisplayName", mem_ctx, obj, lDAPDisplayName, True);
302         GET_STRING_LDB(msg, "governsID", mem_ctx, obj, governsID_oid, True);
303         /* set an invalid value */
304         obj->governsID_id = 0xFFFFFFFF;
305         GET_GUID_LDB(msg, "schemaIDGUID", obj, schemaIDGUID);
306
307         GET_UINT32_LDB(msg, "objectClassCategory", obj, objectClassCategory);
308         GET_STRING_LDB(msg, "rDNAttID", mem_ctx, obj, rDNAttID, False);
309         GET_STRING_LDB(msg, "defaultObjectCategory", mem_ctx, obj, defaultObjectCategory, True);
310  
311         GET_STRING_LDB(msg, "subClassOf", mem_ctx, obj, subClassOf, True);
312
313         obj->systemAuxiliaryClass       = NULL;
314         obj->systemPossSuperiors        = NULL;
315         obj->systemMustContain          = NULL;
316         obj->systemMayContain           = NULL;
317
318         obj->auxiliaryClass             = NULL;
319         obj->possSuperiors              = NULL;
320         obj->mustContain                = NULL;
321         obj->mayContain                 = NULL;
322
323         GET_STRING_LDB(msg, "defaultSecurityDescriptor", mem_ctx, obj, defaultSecurityDescriptor, False);
324
325         GET_UINT32_LDB(msg, "schemaFlagsEx", obj, schemaFlagsEx);
326         GET_BLOB_LDB(msg, "msDs-Schema-Extensions", mem_ctx, obj, msDs_Schema_Extensions);
327
328         GET_BOOL_LDB(msg, "showInAdvancedViewOnly", obj, showInAdvancedViewOnly, False);
329         GET_STRING_LDB(msg, "adminDisplayName", mem_ctx, obj, adminDisplayName, False);
330         GET_STRING_LDB(msg, "adminDescription", mem_ctx, obj, adminDescription, False);
331         GET_STRING_LDB(msg, "classDisplayName", mem_ctx, obj, classDisplayName, False);
332         GET_BOOL_LDB(msg, "defaultHidingValue", obj, defaultHidingValue, False);
333         GET_BOOL_LDB(msg, "isDefunct", obj, isDefunct, False);
334         GET_BOOL_LDB(msg, "systemOnly", obj, systemOnly, False);
335
336         return WERR_OK;
337 }
338
339 static const struct {
340         const char *name;
341         const char *oid;
342 } name_mappings[] = {
343         { "cn",                                 "2.5.4.3" },
344         { "name",                               "1.2.840.113556.1.4.1" },
345         { "lDAPDisplayName",                    "1.2.840.113556.1.2.460" },
346         { "attributeID",                        "1.2.840.113556.1.2.30" },
347         { "schemaIDGUID",                       "1.2.840.113556.1.4.148" },
348         { "mAPIID",                             "1.2.840.113556.1.2.49" },
349         { "attributeSecurityGUID",              "1.2.840.113556.1.4.149" },
350         { "searchFlags",                        "1.2.840.113556.1.2.334" },
351         { "systemFlags",                        "1.2.840.113556.1.4.375" },
352         { "isMemberOfPartialAttributeSet",      "1.2.840.113556.1.4.639" },
353         { "linkID",                             "1.2.840.113556.1.2.50" },
354         { "attributeSyntax",                    "1.2.840.113556.1.2.32" },
355         { "oMSyntax",                           "1.2.840.113556.1.2.231" },
356         { "oMObjectClass",                      "1.2.840.113556.1.2.218" },
357         { "isSingleValued",                     "1.2.840.113556.1.2.33" },
358         { "rangeLower",                         "1.2.840.113556.1.2.34" },
359         { "rangeUpper",                         "1.2.840.113556.1.2.35" },
360         { "extendedCharsAllowed",               "1.2.840.113556.1.2.380" },
361         { "schemaFlagsEx",                      "1.2.840.113556.1.4.120" },
362         { "msDs-Schema-Extensions",             "1.2.840.113556.1.4.1440" },
363         { "showInAdvancedViewOnly",             "1.2.840.113556.1.2.169" },
364         { "adminDisplayName",                   "1.2.840.113556.1.2.194" },
365         { "adminDescription",                   "1.2.840.113556.1.2.226" },
366         { "classDisplayName",                   "1.2.840.113556.1.4.610" },
367         { "isEphemeral",                        "1.2.840.113556.1.4.1212" },
368         { "isDefunct",                          "1.2.840.113556.1.4.661" },
369         { "systemOnly",                         "1.2.840.113556.1.4.170" },
370         { "governsID",                          "1.2.840.113556.1.2.22" },
371         { "objectClassCategory",                "1.2.840.113556.1.2.370" },
372         { "rDNAttID",                           "1.2.840.113556.1.2.26" },
373         { "defaultObjectCategory",              "1.2.840.113556.1.4.783" },
374         { "subClassOf",                         "1.2.840.113556.1.2.21" },
375         { "systemAuxiliaryClass",               "1.2.840.113556.1.4.198" },
376         { "systemPossSuperiors",                "1.2.840.113556.1.4.195" },
377         { "systemMustContain",                  "1.2.840.113556.1.4.197" },
378         { "systemMayContain",                   "1.2.840.113556.1.4.196" },
379         { "auxiliaryClass",                     "1.2.840.113556.1.2.351" },
380         { "possSuperiors",                      "1.2.840.113556.1.2.8" },
381         { "mustContain",                        "1.2.840.113556.1.2.24" },
382         { "mayContain",                         "1.2.840.113556.1.2.25" },
383         { "defaultSecurityDescriptor",          "1.2.840.113556.1.4.224" },
384         { "defaultHidingValue",                 "1.2.840.113556.1.4.518" },
385 };
386
387 static struct drsuapi_DsReplicaAttribute *dsdb_find_object_attr_name(struct dsdb_schema *schema,
388                                                                      struct drsuapi_DsReplicaObject *obj,
389                                                                      const char *name,
390                                                                      uint32_t *idx)
391 {
392         WERROR status;
393         uint32_t i, id;
394         const char *oid = NULL;
395
396         for(i=0; i < ARRAY_SIZE(name_mappings); i++) {
397                 if (strcmp(name_mappings[i].name, name) != 0) continue;
398
399                 oid = name_mappings[i].oid;
400                 break;
401         }
402
403         if (!oid) {
404                 return NULL;
405         }
406
407         status = dsdb_map_oid2int(schema, oid, &id);
408         if (!W_ERROR_IS_OK(status)) {
409                 return NULL;
410         }
411
412         for (i=0; i < obj->attribute_ctr.num_attributes; i++) {
413                 if (obj->attribute_ctr.attributes[i].attid != id) continue;
414
415                 if (idx) *idx = i;
416                 return &obj->attribute_ctr.attributes[i];
417         }
418
419         return NULL;
420 }
421
422 #define GET_STRING_DS(s, r, attr, mem_ctx, p, elem, strict) do { \
423         struct drsuapi_DsReplicaAttribute *_a; \
424         _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
425         if (strict && !_a) { \
426                 d_printf("%s: %s == NULL\n", __location__, attr); \
427                 return WERR_INVALID_PARAM; \
428         } \
429         if (strict && _a->value_ctr.unicode_string.num_values != 1) { \
430                 d_printf("%s: %s num_values == %u\n", __location__, attr, \
431                         _a->value_ctr.unicode_string.num_values); \
432                 return WERR_INVALID_PARAM; \
433         } \
434         if (_a && _a->value_ctr.unicode_string.num_values >= 1) { \
435                 (p)->elem = talloc_steal(mem_ctx, _a->value_ctr.unicode_string.values[0].string);\
436         } else { \
437                 (p)->elem = NULL; \
438         } \
439 } while (0)
440
441 #define GET_BOOL_DS(s, r, attr, p, elem, strict) do { \
442         struct drsuapi_DsReplicaAttribute *_a; \
443         _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
444         if (strict && !_a) { \
445                 d_printf("%s: %s == NULL\n", __location__, attr); \
446                 return WERR_INVALID_PARAM; \
447         } \
448         if (strict && _a->value_ctr.uint32.num_values != 1) { \
449                 d_printf("%s: %s num_values == %u\n", __location__, attr, \
450                         _a->value_ctr.uint32.num_values); \
451                 return WERR_INVALID_PARAM; \
452         } \
453         if (strict && !_a->value_ctr.uint32.values[0].value) { \
454                 d_printf("%s: %s value == NULL\n", __location__, attr); \
455                 return WERR_INVALID_PARAM; \
456         } \
457         if (_a && _a->value_ctr.uint32.num_values >= 1 \
458             && _a->value_ctr.uint32.values[0].value) { \
459                 (p)->elem = (*_a->value_ctr.uint32.values[0].value?True:False);\
460         } else { \
461                 (p)->elem = False; \
462         } \
463 } while (0)
464
465 #define GET_UINT32_DS(s, r, attr, p, elem) do { \
466         struct drsuapi_DsReplicaAttribute *_a; \
467         _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
468         if (_a && _a->value_ctr.uint32.num_values >= 1 \
469             && _a->value_ctr.uint32.values[0].value) { \
470                 (p)->elem = *_a->value_ctr.uint32.values[0].value;\
471         } else { \
472                 (p)->elem = 0; \
473         } \
474 } while (0)
475
476 #define GET_GUID_DS(s, r, attr, p, elem) do { \
477         struct drsuapi_DsReplicaAttribute *_a; \
478         _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
479         if (_a && _a->value_ctr.guid.num_values >= 1 \
480             && _a->value_ctr.guid.values[0].guid) { \
481                 (p)->elem = *_a->value_ctr.guid.values[0].guid;\
482         } else { \
483                 ZERO_STRUCT((p)->elem);\
484         } \
485 } while (0)
486
487 #define GET_BLOB_DS(s, r, attr, mem_ctx, p, elem) do { \
488         struct drsuapi_DsReplicaAttribute *_a; \
489         _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
490         if (_a && _a->value_ctr.data_blob.num_values >= 1 \
491             && _a->value_ctr.data_blob.values[0].data) { \
492                 (p)->elem = *_a->value_ctr.data_blob.values[0].data;\
493                 talloc_steal(mem_ctx, (p)->elem.data); \
494         } else { \
495                 ZERO_STRUCT((p)->elem);\
496         }\
497 } while (0)
498
499 WERROR dsdb_attribute_from_drsuapi(struct dsdb_schema *schema,
500                                    struct drsuapi_DsReplicaObject *r,
501                                    TALLOC_CTX *mem_ctx,
502                                    struct dsdb_attribute *attr)
503 {
504         WERROR status;
505
506         GET_STRING_DS(schema, r, "name", mem_ctx, attr, cn, True);
507         GET_STRING_DS(schema, r, "lDAPDisplayName", mem_ctx, attr, lDAPDisplayName, True);
508         GET_UINT32_DS(schema, r, "attributeID", attr, attributeID_id);
509         status = dsdb_map_int2oid(schema, attr->attributeID_id, mem_ctx, &attr->attributeID_oid);
510         if (!W_ERROR_IS_OK(status)) {
511                 DEBUG(0,("%s: '%s': unable to map attributeID 0x%08X: %s\n",
512                         __location__, attr->lDAPDisplayName, attr->attributeID_id,
513                         win_errstr(status)));
514                 return status;
515         }
516         GET_GUID_DS(schema, r, "schemaIDGUID", attr, schemaIDGUID);
517         GET_UINT32_DS(schema, r, "mAPIID", attr, mAPIID);
518
519         GET_GUID_DS(schema, r, "attributeSecurityGUID", attr, attributeSecurityGUID);
520
521         GET_UINT32_DS(schema, r, "searchFlags", attr, searchFlags);
522         GET_UINT32_DS(schema, r, "systemFlags", attr, systemFlags);
523         GET_BOOL_DS(schema, r, "isMemberOfPartialAttributeSet", attr, isMemberOfPartialAttributeSet, False);
524         GET_UINT32_DS(schema, r, "linkID", attr, linkID);
525
526         GET_UINT32_DS(schema, r, "attributeSyntax", attr, attributeSyntax_id);
527         status = dsdb_map_int2oid(schema, attr->attributeSyntax_id, mem_ctx, &attr->attributeSyntax_oid);
528         if (!W_ERROR_IS_OK(status)) {
529                 DEBUG(0,("%s: '%s': unable to map attributeSyntax 0x%08X: %s\n",
530                         __location__, attr->lDAPDisplayName, attr->attributeSyntax_id,
531                         win_errstr(status)));
532                 return status;
533         }
534         GET_UINT32_DS(schema, r, "oMSyntax", attr, oMSyntax);
535         GET_BLOB_DS(schema, r, "oMObjectClass", mem_ctx, attr, oMObjectClass);
536
537         GET_BOOL_DS(schema, r, "isSingleValued", attr, isSingleValued, True);
538         GET_UINT32_DS(schema, r, "rangeLower", attr, rangeLower);
539         GET_UINT32_DS(schema, r, "rangeUpper", attr, rangeUpper);
540         GET_BOOL_DS(schema, r, "extendedCharsAllowed", attr, extendedCharsAllowed, False);
541
542         GET_UINT32_DS(schema, r, "schemaFlagsEx", attr, schemaFlagsEx);
543         GET_BLOB_DS(schema, r, "msDs-Schema-Extensions", mem_ctx, attr, msDs_Schema_Extensions);
544
545         GET_BOOL_DS(schema, r, "showInAdvancedViewOnly", attr, showInAdvancedViewOnly, False);
546         GET_STRING_DS(schema, r, "adminDisplayName", mem_ctx, attr, adminDisplayName, False);
547         GET_STRING_DS(schema, r, "adminDescription", mem_ctx, attr, adminDescription, False);
548         GET_STRING_DS(schema, r, "classDisplayName", mem_ctx, attr, classDisplayName, False);
549         GET_BOOL_DS(schema, r, "isEphemeral", attr, isEphemeral, False);
550         GET_BOOL_DS(schema, r, "isDefunct", attr, isDefunct, False);
551         GET_BOOL_DS(schema, r, "systemOnly", attr, systemOnly, False);
552
553         attr->syntax = dsdb_syntax_for_attribute(attr);
554         if (!attr->syntax) {
555                 return WERR_DS_ATT_SCHEMA_REQ_SYNTAX;
556         }
557
558         return WERR_OK;
559 }
560
561 WERROR dsdb_class_from_drsuapi(struct dsdb_schema *schema,
562                                struct drsuapi_DsReplicaObject *r,
563                                TALLOC_CTX *mem_ctx,
564                                struct dsdb_class *obj)
565 {
566         WERROR status;
567
568         GET_STRING_DS(schema, r, "name", mem_ctx, obj, cn, True);
569         GET_STRING_DS(schema, r, "lDAPDisplayName", mem_ctx, obj, lDAPDisplayName, True);
570         GET_UINT32_DS(schema, r, "governsID", obj, governsID_id);
571         status = dsdb_map_int2oid(schema, obj->governsID_id, mem_ctx, &obj->governsID_oid);
572         if (!W_ERROR_IS_OK(status)) {
573                 DEBUG(0,("%s: '%s': unable to map governsID 0x%08X: %s\n",
574                         __location__, obj->lDAPDisplayName, obj->governsID_id,
575                         win_errstr(status)));
576                 return status;
577         }
578         GET_GUID_DS(schema, r, "schemaIDGUID", obj, schemaIDGUID);
579
580         GET_UINT32_DS(schema, r, "objectClassCategory", obj, objectClassCategory);
581         GET_STRING_DS(schema, r, "rDNAttID", mem_ctx, obj, rDNAttID, False);
582         GET_STRING_DS(schema, r, "defaultObjectCategory", mem_ctx, obj, defaultObjectCategory, True);
583  
584         GET_STRING_DS(schema, r, "subClassOf", mem_ctx, obj, subClassOf, True);
585
586         obj->systemAuxiliaryClass       = NULL;
587         obj->systemPossSuperiors        = NULL;
588         obj->systemMustContain          = NULL;
589         obj->systemMayContain           = NULL;
590
591         obj->auxiliaryClass             = NULL;
592         obj->possSuperiors              = NULL;
593         obj->mustContain                = NULL;
594         obj->mayContain                 = NULL;
595
596         GET_STRING_DS(schema, r, "defaultSecurityDescriptor", mem_ctx, obj, defaultSecurityDescriptor, False);
597
598         GET_UINT32_DS(schema, r, "schemaFlagsEx", obj, schemaFlagsEx);
599         GET_BLOB_DS(schema, r, "msDs-Schema-Extensions", mem_ctx, obj, msDs_Schema_Extensions);
600
601         GET_BOOL_DS(schema, r, "showInAdvancedViewOnly", obj, showInAdvancedViewOnly, False);
602         GET_STRING_DS(schema, r, "adminDisplayName", mem_ctx, obj, adminDisplayName, False);
603         GET_STRING_DS(schema, r, "adminDescription", mem_ctx, obj, adminDescription, False);
604         GET_STRING_DS(schema, r, "classDisplayName", mem_ctx, obj, classDisplayName, False);
605         GET_BOOL_DS(schema, r, "defaultHidingValue", obj, defaultHidingValue, False);
606         GET_BOOL_DS(schema, r, "isDefunct", obj, isDefunct, False);
607         GET_BOOL_DS(schema, r, "systemOnly", obj, systemOnly, False);
608
609         return WERR_OK;
610 }
611
612 const struct dsdb_attribute *dsdb_attribute_by_attributeID_id(const struct dsdb_schema *schema,
613                                                               uint32_t id)
614 {
615         struct dsdb_attribute *cur;
616
617         /*
618          * 0xFFFFFFFF is used as value when no mapping table is available,
619          * so don't try to match with it
620          */
621         if (id == 0xFFFFFFFF) return NULL;
622
623         /* TODO: add binary search */
624         for (cur = schema->attributes; cur; cur = cur->next) {
625                 if (cur->attributeID_id != id) continue;
626
627                 return cur;
628         }
629
630         return NULL;
631 }
632
633 const struct dsdb_attribute *dsdb_attribute_by_attributeID_oid(const struct dsdb_schema *schema,
634                                                                const char *oid)
635 {
636         struct dsdb_attribute *cur;
637
638         if (!oid) return NULL;
639
640         /* TODO: add binary search */
641         for (cur = schema->attributes; cur; cur = cur->next) {
642                 if (strcmp(cur->attributeID_oid, oid) != 0) continue;
643
644                 return cur;
645         }
646
647         return NULL;
648 }
649
650 const struct dsdb_attribute *dsdb_attribute_by_lDAPDisplayName(const struct dsdb_schema *schema,
651                                                                const char *name)
652 {
653         struct dsdb_attribute *cur;
654
655         if (!name) return NULL;
656
657         /* TODO: add binary search */
658         for (cur = schema->attributes; cur; cur = cur->next) {
659                 if (strcmp(cur->lDAPDisplayName, name) != 0) continue;
660
661                 return cur;
662         }
663
664         return NULL;
665 }
666
667 const struct dsdb_class *dsdb_class_by_governsID_id(const struct dsdb_schema *schema,
668                                                     uint32_t id)
669 {
670         struct dsdb_class *cur;
671
672         /*
673          * 0xFFFFFFFF is used as value when no mapping table is available,
674          * so don't try to match with it
675          */
676         if (id == 0xFFFFFFFF) return NULL;
677
678         /* TODO: add binary search */
679         for (cur = schema->classes; cur; cur = cur->next) {
680                 if (cur->governsID_id != id) continue;
681
682                 return cur;
683         }
684
685         return NULL;
686 }
687
688 const struct dsdb_class *dsdb_class_by_governsID_oid(const struct dsdb_schema *schema,
689                                                      const char *oid)
690 {
691         struct dsdb_class *cur;
692
693         if (!oid) return NULL;
694
695         /* TODO: add binary search */
696         for (cur = schema->classes; cur; cur = cur->next) {
697                 if (strcmp(cur->governsID_oid, oid) != 0) continue;
698
699                 return cur;
700         }
701
702         return NULL;
703 }
704
705 const struct dsdb_class *dsdb_class_by_lDAPDisplayName(const struct dsdb_schema *schema,
706                                                        const char *name)
707 {
708         struct dsdb_class *cur;
709
710         if (!name) return NULL;
711
712         /* TODO: add binary search */
713         for (cur = schema->classes; cur; cur = cur->next) {
714                 if (strcmp(cur->lDAPDisplayName, name) != 0) continue;
715
716                 return cur;
717         }
718
719         return NULL;
720 }
721
722 const char *dsdb_lDAPDisplayName_by_id(const struct dsdb_schema *schema,
723                                        uint32_t id)
724 {
725         const struct dsdb_attribute *a;
726         const struct dsdb_class *c;
727
728         /* TODO: add binary search */
729         a = dsdb_attribute_by_attributeID_id(schema, id);
730         if (a) {
731                 return a->lDAPDisplayName;
732         }
733
734         c = dsdb_class_by_governsID_id(schema, id);
735         if (c) {
736                 return c->lDAPDisplayName;
737         }
738
739         return NULL;
740 }