int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema) { int ret; ret = dsdb_setup_sorted_accessors(ldb, schema); if (ret != LDB_SUCCESS) { return ret; } ret = schema_fill_constructed(schema); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_set_opaque(ldb, "dsdb_schema", schema); if (ret != LDB_SUCCESS) { return ret; } /* Set the new attributes based on the new schema */ ret = dsdb_schema_set_attributes(ldb, schema, true); if (ret != LDB_SUCCESS) { return ret; } talloc_steal(ldb, schema); return LDB_SUCCESS; }
/* create the sorted accessor arrays for the schema */ int dsdb_setup_sorted_accessors(struct ldb_context *ldb, struct dsdb_schema *schema) { struct dsdb_class *cur; struct dsdb_attribute *a; unsigned int i; unsigned int num_int_id; int ret; /* free all caches */ dsdb_sorted_accessors_free(schema); /* count the classes */ for (i=0, cur=schema->classes; cur; i++, cur=cur->next) /* noop */ ; schema->num_classes = i; /* setup classes_by_* */ schema->classes_by_lDAPDisplayName = talloc_array(schema, struct dsdb_class *, i); schema->classes_by_governsID_id = talloc_array(schema, struct dsdb_class *, i); schema->classes_by_governsID_oid = talloc_array(schema, struct dsdb_class *, i); schema->classes_by_cn = talloc_array(schema, struct dsdb_class *, i); if (schema->classes_by_lDAPDisplayName == NULL || schema->classes_by_governsID_id == NULL || schema->classes_by_governsID_oid == NULL || schema->classes_by_cn == NULL) { goto failed; } for (i=0, cur=schema->classes; cur; i++, cur=cur->next) { schema->classes_by_lDAPDisplayName[i] = cur; schema->classes_by_governsID_id[i] = cur; schema->classes_by_governsID_oid[i] = cur; schema->classes_by_cn[i] = cur; } /* sort the arrays */ TYPESAFE_QSORT(schema->classes_by_lDAPDisplayName, schema->num_classes, dsdb_compare_class_by_lDAPDisplayName); TYPESAFE_QSORT(schema->classes_by_governsID_id, schema->num_classes, dsdb_compare_class_by_governsID_id); TYPESAFE_QSORT(schema->classes_by_governsID_oid, schema->num_classes, dsdb_compare_class_by_governsID_oid); TYPESAFE_QSORT(schema->classes_by_cn, schema->num_classes, dsdb_compare_class_by_cn); /* now build the attribute accessor arrays */ /* count the attributes * and attributes with msDS-IntId set */ num_int_id = 0; for (i=0, a=schema->attributes; a; i++, a=a->next) { if (a->msDS_IntId != 0) { num_int_id++; } } schema->num_attributes = i; schema->num_int_id_attr = num_int_id; /* setup attributes_by_* */ schema->attributes_by_lDAPDisplayName = talloc_array(schema, struct dsdb_attribute *, i); schema->attributes_by_attributeID_id = talloc_array(schema, struct dsdb_attribute *, i); schema->attributes_by_msDS_IntId = talloc_array(schema, struct dsdb_attribute *, num_int_id); schema->attributes_by_attributeID_oid = talloc_array(schema, struct dsdb_attribute *, i); schema->attributes_by_linkID = talloc_array(schema, struct dsdb_attribute *, i); if (schema->attributes_by_lDAPDisplayName == NULL || schema->attributes_by_attributeID_id == NULL || schema->attributes_by_msDS_IntId == NULL || schema->attributes_by_attributeID_oid == NULL || schema->attributes_by_linkID == NULL) { goto failed; } num_int_id = 0; for (i=0, a=schema->attributes; a; i++, a=a->next) { schema->attributes_by_lDAPDisplayName[i] = a; schema->attributes_by_attributeID_id[i] = a; schema->attributes_by_attributeID_oid[i] = a; schema->attributes_by_linkID[i] = a; /* append attr-by-msDS-IntId values */ if (a->msDS_IntId != 0) { schema->attributes_by_msDS_IntId[num_int_id] = a; num_int_id++; } } SMB_ASSERT(num_int_id == schema->num_int_id_attr); /* sort the arrays */ TYPESAFE_QSORT(schema->attributes_by_lDAPDisplayName, schema->num_attributes, dsdb_compare_attribute_by_lDAPDisplayName); TYPESAFE_QSORT(schema->attributes_by_attributeID_id, schema->num_attributes, dsdb_compare_attribute_by_attributeID_id); TYPESAFE_QSORT(schema->attributes_by_msDS_IntId, schema->num_int_id_attr, dsdb_compare_attribute_by_msDS_IntId); TYPESAFE_QSORT(schema->attributes_by_attributeID_oid, schema->num_attributes, dsdb_compare_attribute_by_attributeID_oid); TYPESAFE_QSORT(schema->attributes_by_linkID, schema->num_attributes, dsdb_compare_attribute_by_linkID); dsdb_setup_attribute_shortcuts(ldb, schema); ret = schema_fill_constructed(schema); if (ret != LDB_SUCCESS) { dsdb_sorted_accessors_free(schema); return ret; } return LDB_SUCCESS; failed: dsdb_sorted_accessors_free(schema); return ldb_oom(ldb); }