r20408: fix cut'n'paste error
[kai/samba.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(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(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         return WERR_OK;
291 }
292
293 WERROR dsdb_class_from_ldb(struct ldb_message *msg, TALLOC_CTX *mem_ctx, struct dsdb_class *obj)
294 {
295         GET_STRING_LDB(msg, "cn", mem_ctx, obj, cn, True);
296         GET_STRING_LDB(msg, "lDAPDisplayName", mem_ctx, obj, lDAPDisplayName, True);
297         GET_STRING_LDB(msg, "governsID", mem_ctx, obj, governsID_oid, True);
298         /* set an invalid value */
299         obj->governsID_id = 0xFFFFFFFF;
300         GET_GUID_LDB(msg, "schemaIDGUID", obj, schemaIDGUID);
301
302         GET_UINT32_LDB(msg, "objectClassCategory", obj, objectClassCategory);
303         GET_STRING_LDB(msg, "rDNAttID", mem_ctx, obj, rDNAttID, False);
304         GET_STRING_LDB(msg, "defaultObjectCategory", mem_ctx, obj, defaultObjectCategory, True);
305  
306         GET_STRING_LDB(msg, "subClassOf", mem_ctx, obj, subClassOf, True);
307
308         obj->systemAuxiliaryClass       = NULL;
309         obj->systemPossSuperiors        = NULL;
310         obj->systemMustContain          = NULL;
311         obj->systemMayContain           = NULL;
312
313         obj->auxiliaryClass             = NULL;
314         obj->possSuperiors              = NULL;
315         obj->mustContain                = NULL;
316         obj->mayContain                 = NULL;
317
318         GET_STRING_LDB(msg, "defaultSecurityDescriptor", mem_ctx, obj, defaultSecurityDescriptor, False);
319
320         GET_UINT32_LDB(msg, "schemaFlagsEx", obj, schemaFlagsEx);
321         GET_BLOB_LDB(msg, "msDs-Schema-Extensions", mem_ctx, obj, msDs_Schema_Extensions);
322
323         GET_BOOL_LDB(msg, "showInAdvancedViewOnly", obj, showInAdvancedViewOnly, False);
324         GET_STRING_LDB(msg, "adminDisplayName", mem_ctx, obj, adminDisplayName, False);
325         GET_STRING_LDB(msg, "adminDescription", mem_ctx, obj, adminDescription, False);
326         GET_STRING_LDB(msg, "classDisplayName", mem_ctx, obj, classDisplayName, False);
327         GET_BOOL_LDB(msg, "defaultHidingValue", obj, defaultHidingValue, False);
328         GET_BOOL_LDB(msg, "isDefunct", obj, isDefunct, False);
329         GET_BOOL_LDB(msg, "systemOnly", obj, systemOnly, False);
330
331         return WERR_OK;
332 }
333
334 static const struct {
335         const char *name;
336         const char *oid;
337 } name_mappings[] = {
338         { "cn",                                 "2.5.4.3" },
339         { "name",                               "1.2.840.113556.1.4.1" },
340         { "lDAPDisplayName",                    "1.2.840.113556.1.2.460" },
341         { "attributeID",                        "1.2.840.113556.1.2.30" },
342         { "schemaIDGUID",                       "1.2.840.113556.1.4.148" },
343         { "mAPIID",                             "1.2.840.113556.1.2.49" },
344         { "attributeSecurityGUID",              "1.2.840.113556.1.4.149" },
345         { "searchFlags",                        "1.2.840.113556.1.2.334" },
346         { "systemFlags",                        "1.2.840.113556.1.4.375" },
347         { "isMemberOfPartialAttributeSet",      "1.2.840.113556.1.4.639" },
348         { "linkID",                             "1.2.840.113556.1.2.50" },
349         { "attributeSyntax",                    "1.2.840.113556.1.2.32" },
350         { "oMSyntax",                           "1.2.840.113556.1.2.231" },
351         { "oMObjectClass",                      "1.2.840.113556.1.2.218" },
352         { "isSingleValued",                     "1.2.840.113556.1.2.33" },
353         { "rangeLower",                         "1.2.840.113556.1.2.34" },
354         { "rangeUpper",                         "1.2.840.113556.1.2.35" },
355         { "extendedCharsAllowed",               "1.2.840.113556.1.2.380" },
356         { "schemaFlagsEx",                      "1.2.840.113556.1.4.120" },
357         { "msDs-Schema-Extensions",             "1.2.840.113556.1.4.1440" },
358         { "showInAdvancedViewOnly",             "1.2.840.113556.1.2.169" },
359         { "adminDisplayName",                   "1.2.840.113556.1.2.194" },
360         { "adminDescription",                   "1.2.840.113556.1.2.226" },
361         { "classDisplayName",                   "1.2.840.113556.1.4.610" },
362         { "isEphemeral",                        "1.2.840.113556.1.4.1212" },
363         { "isDefunct",                          "1.2.840.113556.1.4.661" },
364         { "systemOnly",                         "1.2.840.113556.1.4.170" },
365         { "governsID",                          "1.2.840.113556.1.2.22" },
366         { "objectClassCategory",                "1.2.840.113556.1.2.370" },
367         { "rDNAttID",                           "1.2.840.113556.1.2.26" },
368         { "defaultObjectCategory",              "1.2.840.113556.1.4.783" },
369         { "subClassOf",                         "1.2.840.113556.1.2.21" },
370         { "systemAuxiliaryClass",               "1.2.840.113556.1.4.198" },
371         { "systemPossSuperiors",                "1.2.840.113556.1.4.195" },
372         { "systemMustContain",                  "1.2.840.113556.1.4.197" },
373         { "systemMayContain",                   "1.2.840.113556.1.4.196" },
374         { "auxiliaryClass",                     "1.2.840.113556.1.2.351" },
375         { "possSuperiors",                      "1.2.840.113556.1.2.8" },
376         { "mustContain",                        "1.2.840.113556.1.2.24" },
377         { "mayContain",                         "1.2.840.113556.1.2.25" },
378         { "defaultSecurityDescriptor",          "1.2.840.113556.1.4.224" },
379         { "defaultHidingValue",                 "1.2.840.113556.1.4.518" },
380 };
381
382 static struct drsuapi_DsReplicaAttribute *dsdb_find_object_attr_name(struct dsdb_schema *schema,
383                                                                      struct drsuapi_DsReplicaObject *obj,
384                                                                      const char *name,
385                                                                      uint32_t *idx)
386 {
387         WERROR status;
388         uint32_t i, id;
389         const char *oid = NULL;
390
391         for(i=0; i < ARRAY_SIZE(name_mappings); i++) {
392                 if (strcmp(name_mappings[i].name, name) != 0) continue;
393
394                 oid = name_mappings[i].oid;
395                 break;
396         }
397
398         if (!oid) {
399                 return NULL;
400         }
401
402         status = dsdb_map_oid2int(schema, oid, &id);
403         if (!W_ERROR_IS_OK(status)) {
404                 return NULL;
405         }
406
407         for (i=0; i < obj->attribute_ctr.num_attributes; i++) {
408                 if (obj->attribute_ctr.attributes[i].attid != id) continue;
409
410                 if (idx) *idx = i;
411                 return &obj->attribute_ctr.attributes[i];
412         }
413
414         return NULL;
415 }
416
417 #define GET_STRING_DS(s, r, attr, mem_ctx, p, elem, strict) do { \
418         struct drsuapi_DsReplicaAttribute *_a; \
419         _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
420         if (strict && !_a) { \
421                 d_printf("%s: %s == NULL\n", __location__, attr); \
422                 return WERR_INVALID_PARAM; \
423         } \
424         if (strict && _a->value_ctr.unicode_string.num_values != 1) { \
425                 d_printf("%s: %s num_values == %u\n", __location__, attr, \
426                         _a->value_ctr.unicode_string.num_values); \
427                 return WERR_INVALID_PARAM; \
428         } \
429         if (_a && _a->value_ctr.unicode_string.num_values >= 1) { \
430                 (p)->elem = talloc_steal(mem_ctx, _a->value_ctr.unicode_string.values[0].string);\
431         } else { \
432                 (p)->elem = NULL; \
433         } \
434 } while (0)
435
436 #define GET_BOOL_DS(s, r, attr, p, elem, strict) do { \
437         struct drsuapi_DsReplicaAttribute *_a; \
438         _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
439         if (strict && !_a) { \
440                 d_printf("%s: %s == NULL\n", __location__, attr); \
441                 return WERR_INVALID_PARAM; \
442         } \
443         if (strict && _a->value_ctr.uint32.num_values != 1) { \
444                 d_printf("%s: %s num_values == %u\n", __location__, attr, \
445                         _a->value_ctr.uint32.num_values); \
446                 return WERR_INVALID_PARAM; \
447         } \
448         if (strict && !_a->value_ctr.uint32.values[0].value) { \
449                 d_printf("%s: %s value == NULL\n", __location__, attr); \
450                 return WERR_INVALID_PARAM; \
451         } \
452         if (_a && _a->value_ctr.uint32.num_values >= 1 \
453             && _a->value_ctr.uint32.values[0].value) { \
454                 (p)->elem = (*_a->value_ctr.uint32.values[0].value?True:False);\
455         } else { \
456                 (p)->elem = False; \
457         } \
458 } while (0)
459
460 #define GET_UINT32_DS(s, r, attr, p, elem) do { \
461         struct drsuapi_DsReplicaAttribute *_a; \
462         _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
463         if (_a && _a->value_ctr.uint32.num_values >= 1 \
464             && _a->value_ctr.uint32.values[0].value) { \
465                 (p)->elem = *_a->value_ctr.uint32.values[0].value;\
466         } else { \
467                 (p)->elem = 0; \
468         } \
469 } while (0)
470
471 #define GET_GUID_DS(s, r, attr, p, elem) do { \
472         struct drsuapi_DsReplicaAttribute *_a; \
473         _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
474         if (_a && _a->value_ctr.guid.num_values >= 1 \
475             && _a->value_ctr.guid.values[0].guid) { \
476                 (p)->elem = *_a->value_ctr.guid.values[0].guid;\
477         } else { \
478                 ZERO_STRUCT((p)->elem);\
479         } \
480 } while (0)
481
482 #define GET_BLOB_DS(s, r, attr, mem_ctx, p, elem) do { \
483         struct drsuapi_DsReplicaAttribute *_a; \
484         _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
485         if (_a && _a->value_ctr.data_blob.num_values >= 1 \
486             && _a->value_ctr.data_blob.values[0].data) { \
487                 (p)->elem = *_a->value_ctr.data_blob.values[0].data;\
488                 talloc_steal(mem_ctx, (p)->elem.data); \
489         } else { \
490                 ZERO_STRUCT((p)->elem);\
491         }\
492 } while (0)
493
494 WERROR dsdb_attribute_from_drsuapi(struct dsdb_schema *schema,
495                                    struct drsuapi_DsReplicaObject *r,
496                                    TALLOC_CTX *mem_ctx,
497                                    struct dsdb_attribute *attr)
498 {
499         WERROR status;
500
501         GET_STRING_DS(schema, r, "name", mem_ctx, attr, cn, True);
502         GET_STRING_DS(schema, r, "lDAPDisplayName", mem_ctx, attr, lDAPDisplayName, True);
503         GET_UINT32_DS(schema, r, "attributeID", attr, attributeID_id);
504         status = dsdb_map_int2oid(schema, attr->attributeID_id, mem_ctx, &attr->attributeID_oid);
505         if (!W_ERROR_IS_OK(status)) {
506                 DEBUG(0,("%s: '%s': unable to map attributeID 0x%08X: %s\n",
507                         __location__, attr->lDAPDisplayName, attr->attributeID_id,
508                         win_errstr(status)));
509                 return status;
510         }
511         GET_GUID_DS(schema, r, "schemaIDGUID", attr, schemaIDGUID);
512         GET_UINT32_DS(schema, r, "mAPIID", attr, mAPIID);
513
514         GET_GUID_DS(schema, r, "attributeSecurityGUID", attr, attributeSecurityGUID);
515
516         GET_UINT32_DS(schema, r, "searchFlags", attr, searchFlags);
517         GET_UINT32_DS(schema, r, "systemFlags", attr, systemFlags);
518         GET_BOOL_DS(schema, r, "isMemberOfPartialAttributeSet", attr, isMemberOfPartialAttributeSet, False);
519         GET_UINT32_DS(schema, r, "linkID", attr, linkID);
520
521         GET_UINT32_DS(schema, r, "attributeSyntax", attr, attributeSyntax_id);
522         status = dsdb_map_int2oid(schema, attr->attributeSyntax_id, mem_ctx, &attr->attributeSyntax_oid);
523         if (!W_ERROR_IS_OK(status)) {
524                 DEBUG(0,("%s: '%s': unable to map attributeSyntax 0x%08X: %s\n",
525                         __location__, attr->lDAPDisplayName, attr->attributeSyntax_id,
526                         win_errstr(status)));
527                 return status;
528         }
529         GET_UINT32_DS(schema, r, "oMSyntax", attr, oMSyntax);
530         GET_BLOB_DS(schema, r, "oMObjectClass", mem_ctx, attr, oMObjectClass);
531
532         GET_BOOL_DS(schema, r, "isSingleValued", attr, isSingleValued, True);
533         GET_UINT32_DS(schema, r, "rangeLower", attr, rangeLower);
534         GET_UINT32_DS(schema, r, "rangeUpper", attr, rangeUpper);
535         GET_BOOL_DS(schema, r, "extendedCharsAllowed", attr, extendedCharsAllowed, False);
536
537         GET_UINT32_DS(schema, r, "schemaFlagsEx", attr, schemaFlagsEx);
538         GET_BLOB_DS(schema, r, "msDs-Schema-Extensions", mem_ctx, attr, msDs_Schema_Extensions);
539
540         GET_BOOL_DS(schema, r, "showInAdvancedViewOnly", attr, showInAdvancedViewOnly, False);
541         GET_STRING_DS(schema, r, "adminDisplayName", mem_ctx, attr, adminDisplayName, False);
542         GET_STRING_DS(schema, r, "adminDescription", mem_ctx, attr, adminDescription, False);
543         GET_STRING_DS(schema, r, "classDisplayName", mem_ctx, attr, classDisplayName, False);
544         GET_BOOL_DS(schema, r, "isEphemeral", attr, isEphemeral, False);
545         GET_BOOL_DS(schema, r, "isDefunct", attr, isDefunct, False);
546         GET_BOOL_DS(schema, r, "systemOnly", attr, systemOnly, False);
547
548         return WERR_OK;
549 }
550
551 WERROR dsdb_class_from_drsuapi(struct dsdb_schema *schema,
552                                struct drsuapi_DsReplicaObject *r,
553                                TALLOC_CTX *mem_ctx,
554                                struct dsdb_class *obj)
555 {
556         WERROR status;
557
558         GET_STRING_DS(schema, r, "name", mem_ctx, obj, cn, True);
559         GET_STRING_DS(schema, r, "lDAPDisplayName", mem_ctx, obj, lDAPDisplayName, True);
560         GET_UINT32_DS(schema, r, "governsID", obj, governsID_id);
561         status = dsdb_map_int2oid(schema, obj->governsID_id, mem_ctx, &obj->governsID_oid);
562         if (!W_ERROR_IS_OK(status)) {
563                 DEBUG(0,("%s: '%s': unable to map governsID 0x%08X: %s\n",
564                         __location__, obj->lDAPDisplayName, obj->governsID_id,
565                         win_errstr(status)));
566                 return status;
567         }
568         GET_GUID_DS(schema, r, "schemaIDGUID", obj, schemaIDGUID);
569
570         GET_UINT32_DS(schema, r, "objectClassCategory", obj, objectClassCategory);
571         GET_STRING_DS(schema, r, "rDNAttID", mem_ctx, obj, rDNAttID, False);
572         GET_STRING_DS(schema, r, "defaultObjectCategory", mem_ctx, obj, defaultObjectCategory, True);
573  
574         GET_STRING_DS(schema, r, "subClassOf", mem_ctx, obj, subClassOf, True);
575
576         obj->systemAuxiliaryClass       = NULL;
577         obj->systemPossSuperiors        = NULL;
578         obj->systemMustContain          = NULL;
579         obj->systemMayContain           = NULL;
580
581         obj->auxiliaryClass             = NULL;
582         obj->possSuperiors              = NULL;
583         obj->mustContain                = NULL;
584         obj->mayContain                 = NULL;
585
586         GET_STRING_DS(schema, r, "defaultSecurityDescriptor", mem_ctx, obj, defaultSecurityDescriptor, False);
587
588         GET_UINT32_DS(schema, r, "schemaFlagsEx", obj, schemaFlagsEx);
589         GET_BLOB_DS(schema, r, "msDs-Schema-Extensions", mem_ctx, obj, msDs_Schema_Extensions);
590
591         GET_BOOL_DS(schema, r, "showInAdvancedViewOnly", obj, showInAdvancedViewOnly, False);
592         GET_STRING_DS(schema, r, "adminDisplayName", mem_ctx, obj, adminDisplayName, False);
593         GET_STRING_DS(schema, r, "adminDescription", mem_ctx, obj, adminDescription, False);
594         GET_STRING_DS(schema, r, "classDisplayName", mem_ctx, obj, classDisplayName, False);
595         GET_BOOL_DS(schema, r, "defaultHidingValue", obj, defaultHidingValue, False);
596         GET_BOOL_DS(schema, r, "isDefunct", obj, isDefunct, False);
597         GET_BOOL_DS(schema, r, "systemOnly", obj, systemOnly, False);
598
599         return WERR_OK;
600 }