2 Unix SMB/CIFS mplementation.
5 Copyright (C) Stefan Metzmacher 2006
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.
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.
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.
24 #include "dsdb/samdb/samdb.h"
25 #include "lib/util/dlinklist.h"
26 #include "librpc/gen_ndr/ndr_misc.h"
27 #include "librpc/gen_ndr/ndr_drsuapi.h"
29 WERROR dsdb_load_oid_mappings(struct dsdb_schema *schema, const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr)
33 schema->prefixes = talloc_array(schema, struct dsdb_schema_oid_prefix, ctr->num_mappings);
34 W_ERROR_HAVE_NO_MEMORY(schema->prefixes);
36 for (i=0, j=0; i < ctr->num_mappings; i++) {
37 if (ctr->mappings[i].oid.oid == NULL) {
38 return WERR_INVALID_PARAM;
41 if (strncasecmp(ctr->mappings[i].oid.oid, "ff", 2) == 0) {
42 if (ctr->mappings[i].id_prefix != 0) {
43 return WERR_INVALID_PARAM;
46 /* the magic value should be in the last array member */
47 if (i != (ctr->num_mappings - 1)) {
48 return WERR_INVALID_PARAM;
51 if (ctr->mappings[i].oid.__ndr_size != 21) {
52 return WERR_INVALID_PARAM;
55 schema->schema_info = talloc_strdup(schema, ctr->mappings[i].oid.oid);
56 W_ERROR_HAVE_NO_MEMORY(schema->schema_info);
58 /* the last array member should contain the magic value not a oid */
59 if (i == (ctr->num_mappings - 1)) {
60 return WERR_INVALID_PARAM;
63 schema->prefixes[j].id = ctr->mappings[i].id_prefix<<16;
64 schema->prefixes[j].oid = talloc_asprintf(schema->prefixes, "%s.",
65 ctr->mappings[i].oid.oid);
66 W_ERROR_HAVE_NO_MEMORY(schema->prefixes[j].oid);
67 schema->prefixes[j].oid_len = strlen(schema->prefixes[j].oid);
72 schema->num_prefixes = j;
76 WERROR dsdb_verify_oid_mappings(const struct dsdb_schema *schema, const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr)
80 for (i=0; i < ctr->num_mappings; i++) {
81 if (ctr->mappings[i].oid.oid == NULL) {
82 return WERR_INVALID_PARAM;
85 if (strncasecmp(ctr->mappings[i].oid.oid, "ff", 2) == 0) {
86 if (ctr->mappings[i].id_prefix != 0) {
87 return WERR_INVALID_PARAM;
90 /* the magic value should be in the last array member */
91 if (i != (ctr->num_mappings - 1)) {
92 return WERR_INVALID_PARAM;
95 if (ctr->mappings[i].oid.__ndr_size != 21) {
96 return WERR_INVALID_PARAM;
99 if (strcasecmp(schema->schema_info, ctr->mappings[i].oid.oid) != 0) {
100 return WERR_DS_DRA_SCHEMA_MISMATCH;
103 /* the last array member should contain the magic value not a oid */
104 if (i == (ctr->num_mappings - 1)) {
105 return WERR_INVALID_PARAM;
108 for (j=0; j < schema->num_prefixes; j++) {
110 if (schema->prefixes[j].id != (ctr->mappings[i].id_prefix<<16)) {
114 oid_len = strlen(ctr->mappings[i].oid.oid);
116 if (oid_len != (schema->prefixes[j].oid_len - 1)) {
117 return WERR_DS_DRA_SCHEMA_MISMATCH;
120 if (strncmp(ctr->mappings[i].oid.oid, schema->prefixes[j].oid, oid_len) != 0) {
121 return WERR_DS_DRA_SCHEMA_MISMATCH;
127 if (j == schema->num_prefixes) {
128 return WERR_DS_DRA_SCHEMA_MISMATCH;
136 WERROR dsdb_map_oid2int(const struct dsdb_schema *schema, const char *in, uint32_t *out)
140 for (i=0; i < schema->num_prefixes; i++) {
145 if (strncmp(schema->prefixes[i].oid, in, schema->prefixes[i].oid_len) != 0) {
149 val_str = in + schema->prefixes[i].oid_len;
153 if (val_str[0] == '\0') {
154 return WERR_INVALID_PARAM;
157 /* two '.' chars are invalid */
158 if (val_str[0] == '.') {
159 return WERR_INVALID_PARAM;
162 val = strtoul(val_str, &end_str, 10);
163 if (end_str[0] == '.' && end_str[1] != '\0') {
165 * if it's a '.' and not the last char
166 * then maybe an other mapping apply
169 } else if (end_str[0] != '\0') {
170 return WERR_INVALID_PARAM;
171 } else if (val > 0xFFFF) {
172 return WERR_INVALID_PARAM;
175 *out = schema->prefixes[i].id | val;
179 return WERR_DS_NO_MSDS_INTID;
182 WERROR dsdb_map_int2oid(const struct dsdb_schema *schema, uint32_t in, TALLOC_CTX *mem_ctx, const char **out)
186 for (i=0; i < schema->num_prefixes; i++) {
188 if (schema->prefixes[i].id != (in & 0xFFFF0000)) {
192 val = talloc_asprintf(mem_ctx, "%s%u",
193 schema->prefixes[i].oid,
195 W_ERROR_HAVE_NO_MEMORY(val);
201 return WERR_DS_NO_MSDS_INTID;
204 #define GET_STRING_LDB(msg, attr, mem_ctx, p, elem, strict) do { \
205 (p)->elem = samdb_result_string(msg, attr, NULL);\
206 if (strict && (p)->elem == NULL) { \
207 d_printf("%s: %s == NULL\n", __location__, attr); \
208 return WERR_INVALID_PARAM; \
210 talloc_steal(mem_ctx, (p)->elem); \
213 #define GET_BOOL_LDB(msg, attr, p, elem, strict) do { \
215 str = samdb_result_string(msg, attr, NULL);\
218 d_printf("%s: %s == NULL\n", __location__, attr); \
219 return WERR_INVALID_PARAM; \
223 } else if (strcasecmp("TRUE", str) == 0) { \
225 } else if (strcasecmp("FALSE", str) == 0) { \
228 d_printf("%s: %s == %s\n", __location__, attr, str); \
229 return WERR_INVALID_PARAM; \
233 #define GET_UINT32_LDB(msg, attr, p, elem) do { \
234 (p)->elem = samdb_result_uint(msg, attr, 0);\
237 #define GET_GUID_LDB(msg, attr, p, elem) do { \
238 (p)->elem = samdb_result_guid(msg, attr);\
241 #define GET_BLOB_LDB(msg, attr, mem_ctx, p, elem) do { \
242 const struct ldb_val *_val;\
243 _val = ldb_msg_find_ldb_val(msg, attr);\
246 talloc_steal(mem_ctx, (p)->elem.data);\
248 ZERO_STRUCT((p)->elem);\
252 WERROR dsdb_attribute_from_ldb(struct ldb_message *msg, TALLOC_CTX *mem_ctx, struct dsdb_attribute *attr)
254 GET_STRING_LDB(msg, "cn", mem_ctx, attr, cn, True);
255 GET_STRING_LDB(msg, "lDAPDisplayName", mem_ctx, attr, lDAPDisplayName, True);
256 GET_STRING_LDB(msg, "attributeID", mem_ctx, attr, attributeID_oid, True);
257 /* set an invalid value */
258 attr->attributeID_id = 0xFFFFFFFF;
259 GET_GUID_LDB(msg, "schemaIDGUID", attr, schemaIDGUID);
260 GET_UINT32_LDB(msg, "mAPIID", attr, mAPIID);
262 GET_GUID_LDB(msg, "attributeSecurityGUID", attr, attributeSecurityGUID);
264 GET_UINT32_LDB(msg, "searchFlags", attr, searchFlags);
265 GET_UINT32_LDB(msg, "systemFlags", attr, systemFlags);
266 GET_BOOL_LDB(msg, "isMemberOfPartialAttributeSet", attr, isMemberOfPartialAttributeSet, False);
267 GET_UINT32_LDB(msg, "linkID", attr, linkID);
269 GET_STRING_LDB(msg, "attributeSyntax", mem_ctx, attr, attributeSyntax_oid, True);
270 /* set an invalid value */
271 attr->attributeSyntax_id = 0xFFFFFFFF;
272 GET_UINT32_LDB(msg, "oMSyntax", attr, oMSyntax);
273 GET_BLOB_LDB(msg, "oMObjectClass", mem_ctx, attr, oMObjectClass);
275 GET_BOOL_LDB(msg, "isSingleValued", attr, isSingleValued, True);
276 GET_UINT32_LDB(msg, "rangeLower", attr, rangeLower);
277 GET_UINT32_LDB(msg, "rangeUpper", attr, rangeUpper);
278 GET_BOOL_LDB(msg, "extendedCharsAllowed", attr, extendedCharsAllowed, False);
280 GET_UINT32_LDB(msg, "schemaFlagsEx", attr, schemaFlagsEx);
281 GET_BLOB_LDB(msg, "msDs-Schema-Extensions", mem_ctx, attr, msDs_Schema_Extensions);
283 GET_BOOL_LDB(msg, "showInAdvancedViewOnly", attr, showInAdvancedViewOnly, False);
284 GET_STRING_LDB(msg, "adminDisplayName", mem_ctx, attr, adminDisplayName, False);
285 GET_STRING_LDB(msg, "adminDescription", mem_ctx, attr, adminDescription, False);
286 GET_STRING_LDB(msg, "classDisplayName", mem_ctx, attr, classDisplayName, False);
287 GET_BOOL_LDB(msg, "isEphemeral", attr, isEphemeral, False);
288 GET_BOOL_LDB(msg, "isDefunct", attr, isDefunct, False);
289 GET_BOOL_LDB(msg, "systemOnly", attr, systemOnly, False);
291 attr->syntax = dsdb_syntax_for_attribute(attr);
293 return WERR_DS_ATT_SCHEMA_REQ_SYNTAX;
299 WERROR dsdb_class_from_ldb(struct ldb_message *msg, TALLOC_CTX *mem_ctx, struct dsdb_class *obj)
301 GET_STRING_LDB(msg, "cn", mem_ctx, obj, cn, True);
302 GET_STRING_LDB(msg, "lDAPDisplayName", mem_ctx, obj, lDAPDisplayName, True);
303 GET_STRING_LDB(msg, "governsID", mem_ctx, obj, governsID_oid, True);
304 /* set an invalid value */
305 obj->governsID_id = 0xFFFFFFFF;
306 GET_GUID_LDB(msg, "schemaIDGUID", obj, schemaIDGUID);
308 GET_UINT32_LDB(msg, "objectClassCategory", obj, objectClassCategory);
309 GET_STRING_LDB(msg, "rDNAttID", mem_ctx, obj, rDNAttID, False);
310 GET_STRING_LDB(msg, "defaultObjectCategory", mem_ctx, obj, defaultObjectCategory, True);
312 GET_STRING_LDB(msg, "subClassOf", mem_ctx, obj, subClassOf, True);
314 obj->systemAuxiliaryClass = NULL;
315 obj->systemPossSuperiors = NULL;
316 obj->systemMustContain = NULL;
317 obj->systemMayContain = NULL;
319 obj->auxiliaryClass = NULL;
320 obj->possSuperiors = NULL;
321 obj->mustContain = NULL;
322 obj->mayContain = NULL;
324 GET_STRING_LDB(msg, "defaultSecurityDescriptor", mem_ctx, obj, defaultSecurityDescriptor, False);
326 GET_UINT32_LDB(msg, "schemaFlagsEx", obj, schemaFlagsEx);
327 GET_BLOB_LDB(msg, "msDs-Schema-Extensions", mem_ctx, obj, msDs_Schema_Extensions);
329 GET_BOOL_LDB(msg, "showInAdvancedViewOnly", obj, showInAdvancedViewOnly, False);
330 GET_STRING_LDB(msg, "adminDisplayName", mem_ctx, obj, adminDisplayName, False);
331 GET_STRING_LDB(msg, "adminDescription", mem_ctx, obj, adminDescription, False);
332 GET_STRING_LDB(msg, "classDisplayName", mem_ctx, obj, classDisplayName, False);
333 GET_BOOL_LDB(msg, "defaultHidingValue", obj, defaultHidingValue, False);
334 GET_BOOL_LDB(msg, "isDefunct", obj, isDefunct, False);
335 GET_BOOL_LDB(msg, "systemOnly", obj, systemOnly, False);
340 static const struct {
343 } name_mappings[] = {
345 { "name", "1.2.840.113556.1.4.1" },
346 { "lDAPDisplayName", "1.2.840.113556.1.2.460" },
347 { "attributeID", "1.2.840.113556.1.2.30" },
348 { "schemaIDGUID", "1.2.840.113556.1.4.148" },
349 { "mAPIID", "1.2.840.113556.1.2.49" },
350 { "attributeSecurityGUID", "1.2.840.113556.1.4.149" },
351 { "searchFlags", "1.2.840.113556.1.2.334" },
352 { "systemFlags", "1.2.840.113556.1.4.375" },
353 { "isMemberOfPartialAttributeSet", "1.2.840.113556.1.4.639" },
354 { "linkID", "1.2.840.113556.1.2.50" },
355 { "attributeSyntax", "1.2.840.113556.1.2.32" },
356 { "oMSyntax", "1.2.840.113556.1.2.231" },
357 { "oMObjectClass", "1.2.840.113556.1.2.218" },
358 { "isSingleValued", "1.2.840.113556.1.2.33" },
359 { "rangeLower", "1.2.840.113556.1.2.34" },
360 { "rangeUpper", "1.2.840.113556.1.2.35" },
361 { "extendedCharsAllowed", "1.2.840.113556.1.2.380" },
362 { "schemaFlagsEx", "1.2.840.113556.1.4.120" },
363 { "msDs-Schema-Extensions", "1.2.840.113556.1.4.1440" },
364 { "showInAdvancedViewOnly", "1.2.840.113556.1.2.169" },
365 { "adminDisplayName", "1.2.840.113556.1.2.194" },
366 { "adminDescription", "1.2.840.113556.1.2.226" },
367 { "classDisplayName", "1.2.840.113556.1.4.610" },
368 { "isEphemeral", "1.2.840.113556.1.4.1212" },
369 { "isDefunct", "1.2.840.113556.1.4.661" },
370 { "systemOnly", "1.2.840.113556.1.4.170" },
371 { "governsID", "1.2.840.113556.1.2.22" },
372 { "objectClassCategory", "1.2.840.113556.1.2.370" },
373 { "rDNAttID", "1.2.840.113556.1.2.26" },
374 { "defaultObjectCategory", "1.2.840.113556.1.4.783" },
375 { "subClassOf", "1.2.840.113556.1.2.21" },
376 { "systemAuxiliaryClass", "1.2.840.113556.1.4.198" },
377 { "systemPossSuperiors", "1.2.840.113556.1.4.195" },
378 { "systemMustContain", "1.2.840.113556.1.4.197" },
379 { "systemMayContain", "1.2.840.113556.1.4.196" },
380 { "auxiliaryClass", "1.2.840.113556.1.2.351" },
381 { "possSuperiors", "1.2.840.113556.1.2.8" },
382 { "mustContain", "1.2.840.113556.1.2.24" },
383 { "mayContain", "1.2.840.113556.1.2.25" },
384 { "defaultSecurityDescriptor", "1.2.840.113556.1.4.224" },
385 { "defaultHidingValue", "1.2.840.113556.1.4.518" },
388 static struct drsuapi_DsReplicaAttribute *dsdb_find_object_attr_name(struct dsdb_schema *schema,
389 struct drsuapi_DsReplicaObject *obj,
395 const char *oid = NULL;
397 for(i=0; i < ARRAY_SIZE(name_mappings); i++) {
398 if (strcmp(name_mappings[i].name, name) != 0) continue;
400 oid = name_mappings[i].oid;
408 status = dsdb_map_oid2int(schema, oid, &id);
409 if (!W_ERROR_IS_OK(status)) {
413 for (i=0; i < obj->attribute_ctr.num_attributes; i++) {
414 if (obj->attribute_ctr.attributes[i].attid != id) continue;
417 return &obj->attribute_ctr.attributes[i];
423 #define GET_STRING_DS(s, r, attr, mem_ctx, p, elem, strict) do { \
424 struct drsuapi_DsReplicaAttribute *_a; \
425 _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
426 if (strict && !_a) { \
427 d_printf("%s: %s == NULL\n", __location__, attr); \
428 return WERR_INVALID_PARAM; \
430 if (strict && _a->value_ctr.num_values != 1) { \
431 d_printf("%s: %s num_values == %u\n", __location__, attr, \
432 _a->value_ctr.num_values); \
433 return WERR_INVALID_PARAM; \
435 if (_a && _a->value_ctr.num_values >= 1) { \
437 _ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, \
438 _a->value_ctr.values[0].blob->data, \
439 _a->value_ctr.values[0].blob->length, \
440 (void **)discard_const(&(p)->elem)); \
442 DEBUG(0,("%s: invalid data!\n", attr)); \
444 _a->value_ctr.values[0].blob->data, \
445 _a->value_ctr.values[0].blob->length); \
446 return WERR_FOOBAR; \
453 #define GET_DN_DS(s, r, attr, mem_ctx, p, elem, strict) do { \
454 struct drsuapi_DsReplicaAttribute *_a; \
455 _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
456 if (strict && !_a) { \
457 d_printf("%s: %s == NULL\n", __location__, attr); \
458 return WERR_INVALID_PARAM; \
460 if (strict && _a->value_ctr.num_values != 1) { \
461 d_printf("%s: %s num_values == %u\n", __location__, attr, \
462 _a->value_ctr.num_values); \
463 return WERR_INVALID_PARAM; \
465 if (strict && !_a->value_ctr.values[0].blob) { \
466 d_printf("%s: %s data == NULL\n", __location__, attr); \
467 return WERR_INVALID_PARAM; \
469 if (_a && _a->value_ctr.num_values >= 1 \
470 && _a->value_ctr.values[0].blob) { \
471 struct drsuapi_DsReplicaObjectIdentifier3 _id3; \
472 NTSTATUS _nt_status; \
473 _nt_status = ndr_pull_struct_blob_all(_a->value_ctr.values[0].blob, \
475 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);\
476 if (!NT_STATUS_IS_OK(_nt_status)) { \
477 return ntstatus_to_werror(_nt_status); \
479 (p)->elem = _id3.dn; \
485 #define GET_BOOL_DS(s, r, attr, p, elem, strict) do { \
486 struct drsuapi_DsReplicaAttribute *_a; \
487 _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
488 if (strict && !_a) { \
489 d_printf("%s: %s == NULL\n", __location__, attr); \
490 return WERR_INVALID_PARAM; \
492 if (strict && _a->value_ctr.num_values != 1) { \
493 d_printf("%s: %s num_values == %u\n", __location__, attr, \
494 _a->value_ctr.num_values); \
495 return WERR_INVALID_PARAM; \
497 if (strict && !_a->value_ctr.values[0].blob) { \
498 d_printf("%s: %s data == NULL\n", __location__, attr); \
499 return WERR_INVALID_PARAM; \
501 if (strict && _a->value_ctr.values[0].blob->length != 4) { \
502 d_printf("%s: %s length == %u\n", __location__, attr, \
503 _a->value_ctr.values[0].blob->length); \
504 return WERR_INVALID_PARAM; \
506 if (_a && _a->value_ctr.num_values >= 1 \
507 && _a->value_ctr.values[0].blob \
508 && _a->value_ctr.values[0].blob->length == 4) { \
509 (p)->elem = (IVAL(_a->value_ctr.values[0].blob->data,0)?True:False);\
515 #define GET_UINT32_DS(s, r, attr, p, elem) do { \
516 struct drsuapi_DsReplicaAttribute *_a; \
517 _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
518 if (_a && _a->value_ctr.num_values >= 1 \
519 && _a->value_ctr.values[0].blob \
520 && _a->value_ctr.values[0].blob->length == 4) { \
521 (p)->elem = IVAL(_a->value_ctr.values[0].blob->data,0);\
527 #define GET_GUID_DS(s, r, attr, mem_ctx, p, elem) do { \
528 struct drsuapi_DsReplicaAttribute *_a; \
529 _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
530 if (_a && _a->value_ctr.num_values >= 1 \
531 && _a->value_ctr.values[0].blob \
532 && _a->value_ctr.values[0].blob->length == 16) { \
533 NTSTATUS _nt_status; \
534 _nt_status = ndr_pull_struct_blob_all(_a->value_ctr.values[0].blob, \
535 mem_ctx, &(p)->elem, \
536 (ndr_pull_flags_fn_t)ndr_pull_GUID); \
537 if (!NT_STATUS_IS_OK(_nt_status)) { \
538 return ntstatus_to_werror(_nt_status); \
541 ZERO_STRUCT((p)->elem);\
545 #define GET_BLOB_DS(s, r, attr, mem_ctx, p, elem) do { \
546 struct drsuapi_DsReplicaAttribute *_a; \
547 _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
548 if (_a && _a->value_ctr.num_values >= 1 \
549 && _a->value_ctr.values[0].blob) { \
550 (p)->elem = *_a->value_ctr.values[0].blob;\
551 talloc_steal(mem_ctx, (p)->elem.data); \
553 ZERO_STRUCT((p)->elem);\
557 WERROR dsdb_attribute_from_drsuapi(struct dsdb_schema *schema,
558 struct drsuapi_DsReplicaObject *r,
560 struct dsdb_attribute *attr)
564 GET_STRING_DS(schema, r, "name", mem_ctx, attr, cn, True);
565 GET_STRING_DS(schema, r, "lDAPDisplayName", mem_ctx, attr, lDAPDisplayName, True);
566 GET_UINT32_DS(schema, r, "attributeID", attr, attributeID_id);
567 status = dsdb_map_int2oid(schema, attr->attributeID_id, mem_ctx, &attr->attributeID_oid);
568 if (!W_ERROR_IS_OK(status)) {
569 DEBUG(0,("%s: '%s': unable to map attributeID 0x%08X: %s\n",
570 __location__, attr->lDAPDisplayName, attr->attributeID_id,
571 win_errstr(status)));
574 GET_GUID_DS(schema, r, "schemaIDGUID", mem_ctx, attr, schemaIDGUID);
575 GET_UINT32_DS(schema, r, "mAPIID", attr, mAPIID);
577 GET_GUID_DS(schema, r, "attributeSecurityGUID", mem_ctx, attr, attributeSecurityGUID);
579 GET_UINT32_DS(schema, r, "searchFlags", attr, searchFlags);
580 GET_UINT32_DS(schema, r, "systemFlags", attr, systemFlags);
581 GET_BOOL_DS(schema, r, "isMemberOfPartialAttributeSet", attr, isMemberOfPartialAttributeSet, False);
582 GET_UINT32_DS(schema, r, "linkID", attr, linkID);
584 GET_UINT32_DS(schema, r, "attributeSyntax", attr, attributeSyntax_id);
585 status = dsdb_map_int2oid(schema, attr->attributeSyntax_id, mem_ctx, &attr->attributeSyntax_oid);
586 if (!W_ERROR_IS_OK(status)) {
587 DEBUG(0,("%s: '%s': unable to map attributeSyntax 0x%08X: %s\n",
588 __location__, attr->lDAPDisplayName, attr->attributeSyntax_id,
589 win_errstr(status)));
592 GET_UINT32_DS(schema, r, "oMSyntax", attr, oMSyntax);
593 GET_BLOB_DS(schema, r, "oMObjectClass", mem_ctx, attr, oMObjectClass);
595 GET_BOOL_DS(schema, r, "isSingleValued", attr, isSingleValued, True);
596 GET_UINT32_DS(schema, r, "rangeLower", attr, rangeLower);
597 GET_UINT32_DS(schema, r, "rangeUpper", attr, rangeUpper);
598 GET_BOOL_DS(schema, r, "extendedCharsAllowed", attr, extendedCharsAllowed, False);
600 GET_UINT32_DS(schema, r, "schemaFlagsEx", attr, schemaFlagsEx);
601 GET_BLOB_DS(schema, r, "msDs-Schema-Extensions", mem_ctx, attr, msDs_Schema_Extensions);
603 GET_BOOL_DS(schema, r, "showInAdvancedViewOnly", attr, showInAdvancedViewOnly, False);
604 GET_STRING_DS(schema, r, "adminDisplayName", mem_ctx, attr, adminDisplayName, False);
605 GET_STRING_DS(schema, r, "adminDescription", mem_ctx, attr, adminDescription, False);
606 GET_STRING_DS(schema, r, "classDisplayName", mem_ctx, attr, classDisplayName, False);
607 GET_BOOL_DS(schema, r, "isEphemeral", attr, isEphemeral, False);
608 GET_BOOL_DS(schema, r, "isDefunct", attr, isDefunct, False);
609 GET_BOOL_DS(schema, r, "systemOnly", attr, systemOnly, False);
611 attr->syntax = dsdb_syntax_for_attribute(attr);
613 return WERR_DS_ATT_SCHEMA_REQ_SYNTAX;
619 WERROR dsdb_class_from_drsuapi(struct dsdb_schema *schema,
620 struct drsuapi_DsReplicaObject *r,
622 struct dsdb_class *obj)
626 GET_STRING_DS(schema, r, "name", mem_ctx, obj, cn, True);
627 GET_STRING_DS(schema, r, "lDAPDisplayName", mem_ctx, obj, lDAPDisplayName, True);
628 GET_UINT32_DS(schema, r, "governsID", obj, governsID_id);
629 status = dsdb_map_int2oid(schema, obj->governsID_id, mem_ctx, &obj->governsID_oid);
630 if (!W_ERROR_IS_OK(status)) {
631 DEBUG(0,("%s: '%s': unable to map governsID 0x%08X: %s\n",
632 __location__, obj->lDAPDisplayName, obj->governsID_id,
633 win_errstr(status)));
636 GET_GUID_DS(schema, r, "schemaIDGUID", mem_ctx, obj, schemaIDGUID);
638 GET_UINT32_DS(schema, r, "objectClassCategory", obj, objectClassCategory);
639 GET_STRING_DS(schema, r, "rDNAttID", mem_ctx, obj, rDNAttID, False);
640 GET_DN_DS(schema, r, "defaultObjectCategory", mem_ctx, obj, defaultObjectCategory, True);
642 GET_STRING_DS(schema, r, "subClassOf", mem_ctx, obj, subClassOf, True);
644 obj->systemAuxiliaryClass = NULL;
645 obj->systemPossSuperiors = NULL;
646 obj->systemMustContain = NULL;
647 obj->systemMayContain = NULL;
649 obj->auxiliaryClass = NULL;
650 obj->possSuperiors = NULL;
651 obj->mustContain = NULL;
652 obj->mayContain = NULL;
654 GET_STRING_DS(schema, r, "defaultSecurityDescriptor", mem_ctx, obj, defaultSecurityDescriptor, False);
656 GET_UINT32_DS(schema, r, "schemaFlagsEx", obj, schemaFlagsEx);
657 GET_BLOB_DS(schema, r, "msDs-Schema-Extensions", mem_ctx, obj, msDs_Schema_Extensions);
659 GET_BOOL_DS(schema, r, "showInAdvancedViewOnly", obj, showInAdvancedViewOnly, False);
660 GET_STRING_DS(schema, r, "adminDisplayName", mem_ctx, obj, adminDisplayName, False);
661 GET_STRING_DS(schema, r, "adminDescription", mem_ctx, obj, adminDescription, False);
662 GET_STRING_DS(schema, r, "classDisplayName", mem_ctx, obj, classDisplayName, False);
663 GET_BOOL_DS(schema, r, "defaultHidingValue", obj, defaultHidingValue, False);
664 GET_BOOL_DS(schema, r, "isDefunct", obj, isDefunct, False);
665 GET_BOOL_DS(schema, r, "systemOnly", obj, systemOnly, False);
670 const struct dsdb_attribute *dsdb_attribute_by_attributeID_id(const struct dsdb_schema *schema,
673 struct dsdb_attribute *cur;
676 * 0xFFFFFFFF is used as value when no mapping table is available,
677 * so don't try to match with it
679 if (id == 0xFFFFFFFF) return NULL;
681 /* TODO: add binary search */
682 for (cur = schema->attributes; cur; cur = cur->next) {
683 if (cur->attributeID_id != id) continue;
691 const struct dsdb_attribute *dsdb_attribute_by_attributeID_oid(const struct dsdb_schema *schema,
694 struct dsdb_attribute *cur;
696 if (!oid) return NULL;
698 /* TODO: add binary search */
699 for (cur = schema->attributes; cur; cur = cur->next) {
700 if (strcmp(cur->attributeID_oid, oid) != 0) continue;
708 const struct dsdb_attribute *dsdb_attribute_by_lDAPDisplayName(const struct dsdb_schema *schema,
711 struct dsdb_attribute *cur;
713 if (!name) return NULL;
715 /* TODO: add binary search */
716 for (cur = schema->attributes; cur; cur = cur->next) {
717 if (strcmp(cur->lDAPDisplayName, name) != 0) continue;
725 const struct dsdb_class *dsdb_class_by_governsID_id(const struct dsdb_schema *schema,
728 struct dsdb_class *cur;
731 * 0xFFFFFFFF is used as value when no mapping table is available,
732 * so don't try to match with it
734 if (id == 0xFFFFFFFF) return NULL;
736 /* TODO: add binary search */
737 for (cur = schema->classes; cur; cur = cur->next) {
738 if (cur->governsID_id != id) continue;
746 const struct dsdb_class *dsdb_class_by_governsID_oid(const struct dsdb_schema *schema,
749 struct dsdb_class *cur;
751 if (!oid) return NULL;
753 /* TODO: add binary search */
754 for (cur = schema->classes; cur; cur = cur->next) {
755 if (strcmp(cur->governsID_oid, oid) != 0) continue;
763 const struct dsdb_class *dsdb_class_by_lDAPDisplayName(const struct dsdb_schema *schema,
766 struct dsdb_class *cur;
768 if (!name) return NULL;
770 /* TODO: add binary search */
771 for (cur = schema->classes; cur; cur = cur->next) {
772 if (strcmp(cur->lDAPDisplayName, name) != 0) continue;
780 const char *dsdb_lDAPDisplayName_by_id(const struct dsdb_schema *schema,
783 const struct dsdb_attribute *a;
784 const struct dsdb_class *c;
786 /* TODO: add binary search */
787 a = dsdb_attribute_by_attributeID_id(schema, id);
789 return a->lDAPDisplayName;
792 c = dsdb_class_by_governsID_id(schema, id);
794 return c->lDAPDisplayName;