s4:dsdb Use the schema from our local provision to decode the schema
authorAndrew Bartlett <abartlet@samba.org>
Wed, 9 Jun 2010 08:57:52 +0000 (18:57 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 15 Jun 2010 00:51:34 +0000 (10:51 +1000)
This works on the assumption that the schema partition can only
contain schema objects.

We may need to pass down some kind of 'relax' to the DRS -> LDB
conversion code, so that it allows incomplete conversions, so that we
don't fail if a new attribute is present, and we can't decode it.
This would then be resolved the second time we do the conversion.

Andrew Bartlett

Signed-off-by: Kamen Mazdrashki <kamenim@samba.org>
source4/dsdb/schema/schema_init.c
source4/libnet/libnet_vampire.c

index 8e47f1228dc78c50c4bfda0c01dccabe969f8310..2cf5af685dba2eed8ebe89d134e3a969fb5c2131 100644 (file)
@@ -806,370 +806,3 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
        *schema_out = schema;
        return LDB_SUCCESS;
 }
-
-
-static const struct {
-       const char *name;
-       const char *oid;
-} name_mappings[] = {
-       { "cn",                                 "2.5.4.3" },
-       { "name",                               "1.2.840.113556.1.4.1" },
-       { "lDAPDisplayName",                    "1.2.840.113556.1.2.460" },
-       { "attributeID",                        "1.2.840.113556.1.2.30" },
-       { "schemaIDGUID",                       "1.2.840.113556.1.4.148" },
-       { "mAPIID",                             "1.2.840.113556.1.2.49" },
-       { "attributeSecurityGUID",              "1.2.840.113556.1.4.149" },
-       { "searchFlags",                        "1.2.840.113556.1.2.334" },
-       { "systemFlags",                        "1.2.840.113556.1.4.375" },
-       { "isMemberOfPartialAttributeSet",      "1.2.840.113556.1.4.639" },
-       { "linkID",                             "1.2.840.113556.1.2.50" },
-       { "attributeSyntax",                    "1.2.840.113556.1.2.32" },
-       { "oMSyntax",                           "1.2.840.113556.1.2.231" },
-       { "oMObjectClass",                      "1.2.840.113556.1.2.218" },
-       { "isSingleValued",                     "1.2.840.113556.1.2.33" },
-       { "rangeLower",                         "1.2.840.113556.1.2.34" },
-       { "rangeUpper",                         "1.2.840.113556.1.2.35" },
-       { "extendedCharsAllowed",               "1.2.840.113556.1.2.380" },
-       { "schemaFlagsEx",                      "1.2.840.113556.1.4.120" },
-       { "msDs-Schema-Extensions",             "1.2.840.113556.1.4.1440" },
-       { "showInAdvancedViewOnly",             "1.2.840.113556.1.2.169" },
-       { "adminDisplayName",                   "1.2.840.113556.1.2.194" },
-       { "adminDescription",                   "1.2.840.113556.1.2.226" },
-       { "classDisplayName",                   "1.2.840.113556.1.4.610" },
-       { "isEphemeral",                        "1.2.840.113556.1.4.1212" },
-       { "isDefunct",                          "1.2.840.113556.1.4.661" },
-       { "systemOnly",                         "1.2.840.113556.1.4.170" },
-       { "governsID",                          "1.2.840.113556.1.2.22" },
-       { "objectClassCategory",                "1.2.840.113556.1.2.370" },
-       { "rDNAttID",                           "1.2.840.113556.1.2.26" },
-       { "defaultObjectCategory",              "1.2.840.113556.1.4.783" },
-       { "subClassOf",                         "1.2.840.113556.1.2.21" },
-       { "systemAuxiliaryClass",               "1.2.840.113556.1.4.198" },
-       { "systemPossSuperiors",                "1.2.840.113556.1.4.195" },
-       { "systemMustContain",                  "1.2.840.113556.1.4.197" },
-       { "systemMayContain",                   "1.2.840.113556.1.4.196" },
-       { "auxiliaryClass",                     "1.2.840.113556.1.2.351" },
-       { "possSuperiors",                      "1.2.840.113556.1.2.8" },
-       { "mustContain",                        "1.2.840.113556.1.2.24" },
-       { "mayContain",                         "1.2.840.113556.1.2.25" },
-       { "defaultSecurityDescriptor",          "1.2.840.113556.1.4.224" },
-       { "defaultHidingValue",                 "1.2.840.113556.1.4.518" },
-       { "msDS-IntId",                         "1.2.840.113556.1.4.1716" },
-};
-
-static struct drsuapi_DsReplicaAttribute *dsdb_find_object_attr_name(struct dsdb_schema *schema,
-                                                                    struct drsuapi_DsReplicaObject *obj,
-                                                                    const char *name,
-                                                                    uint32_t *idx)
-{
-       WERROR status;
-       unsigned int i;
-       uint32_t attid;
-       const char *oid = NULL;
-
-       for(i=0; i < ARRAY_SIZE(name_mappings); i++) {
-               if (strcmp(name_mappings[i].name, name) != 0) continue;
-
-               oid = name_mappings[i].oid;
-               break;
-       }
-
-       if (!oid) {
-               return NULL;
-       }
-
-       status = dsdb_schema_pfm_make_attid(schema->prefixmap, oid, &attid);
-       if (!W_ERROR_IS_OK(status)) {
-               return NULL;
-       }
-
-       for (i=0; i < obj->attribute_ctr.num_attributes; i++) {
-               if (obj->attribute_ctr.attributes[i].attid != attid) continue;
-
-               if (idx) *idx = i;
-               return &obj->attribute_ctr.attributes[i];
-       }
-
-       return NULL;
-}
-
-#define GET_STRING_DS(s, r, attr, mem_ctx, p, elem, strict) do { \
-       struct drsuapi_DsReplicaAttribute *_a; \
-       _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
-       if (strict && !_a) { \
-               d_printf("%s: %s == NULL\n", __location__, attr); \
-               return WERR_INVALID_PARAM; \
-       } \
-       if (strict && _a->value_ctr.num_values != 1) { \
-               d_printf("%s: %s num_values == %u\n", __location__, attr, \
-                       _a->value_ctr.num_values); \
-               return WERR_INVALID_PARAM; \
-       } \
-       if (_a && _a->value_ctr.num_values >= 1) { \
-               size_t _ret; \
-               if (!convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, \
-                                            _a->value_ctr.values[0].blob->data, \
-                                            _a->value_ctr.values[0].blob->length, \
-                                            (void **)discard_const(&(p)->elem), &_ret, false)) { \
-                       DEBUG(0,("%s: invalid data!\n", attr)); \
-                       dump_data(0, \
-                                    _a->value_ctr.values[0].blob->data, \
-                                    _a->value_ctr.values[0].blob->length); \
-                       return WERR_FOOBAR; \
-               } \
-       } else { \
-               (p)->elem = NULL; \
-       } \
-} while (0)
-
-#define GET_UINT32_LIST_DS(s, r, attr, mem_ctx, p, elem) do { \
-       unsigned int list_counter;                              \
-       struct drsuapi_DsReplicaAttribute *_a; \
-       _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
-       (p)->elem = _a ? talloc_array(mem_ctx, uint32_t, _a->value_ctr.num_values + 1) : NULL; \
-        for (list_counter=0;                                   \
-            _a && list_counter < _a->value_ctr.num_values;     \
-            list_counter++) {                          \
-               if (_a->value_ctr.values[list_counter].blob->length != 4) { \
-                       return WERR_INVALID_PARAM;                      \
-               }                                                       \
-               (p)->elem[list_counter] = IVAL(_a->value_ctr.values[list_counter].blob->data, 0); \
-       }                                                               \
-       if (_a) (p)->elem[list_counter] = 0;                            \
-} while (0)
-
-#define GET_BOOL_DS(s, r, attr, p, elem, strict) do { \
-       struct drsuapi_DsReplicaAttribute *_a; \
-       _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
-       if (strict && !_a) { \
-               d_printf("%s: %s == NULL\n", __location__, attr); \
-               return WERR_INVALID_PARAM; \
-       } \
-       if (strict && _a->value_ctr.num_values != 1) { \
-               d_printf("%s: %s num_values == %u\n", __location__, attr, \
-                        (unsigned int)_a->value_ctr.num_values);       \
-               return WERR_INVALID_PARAM; \
-       } \
-       if (strict && !_a->value_ctr.values[0].blob) { \
-               d_printf("%s: %s data == NULL\n", __location__, attr); \
-               return WERR_INVALID_PARAM; \
-       } \
-       if (strict && _a->value_ctr.values[0].blob->length != 4) { \
-               d_printf("%s: %s length == %u\n", __location__, attr, \
-                        (unsigned int)_a->value_ctr.values[0].blob->length); \
-               return WERR_INVALID_PARAM; \
-       } \
-       if (_a && _a->value_ctr.num_values >= 1 \
-           && _a->value_ctr.values[0].blob \
-           && _a->value_ctr.values[0].blob->length == 4) { \
-               (p)->elem = (IVAL(_a->value_ctr.values[0].blob->data,0)?true:false);\
-       } else { \
-               (p)->elem = false; \
-       } \
-} while (0)
-
-#define GET_UINT32_DS(s, r, attr, p, elem, def_val) do { \
-       struct drsuapi_DsReplicaAttribute *_a; \
-       _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
-       if (_a && _a->value_ctr.num_values >= 1 \
-           && _a->value_ctr.values[0].blob \
-           && _a->value_ctr.values[0].blob->length == 4) { \
-               (p)->elem = IVAL(_a->value_ctr.values[0].blob->data,0);\
-       } else { \
-               (p)->elem = def_val; \
-       } \
-} while (0)
-
-#define GET_UINT32_PTR_DS(s, r, attr, p, elem) do { \
-       struct drsuapi_DsReplicaAttribute *_a; \
-       _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
-       if (_a && _a->value_ctr.num_values >= 1 \
-           && _a->value_ctr.values[0].blob \
-           && _a->value_ctr.values[0].blob->length == 4) { \
-               (p)->elem = talloc(mem_ctx, uint32_t); \
-               if (!(p)->elem) { \
-                       d_printf("%s: talloc failed for %s\n", __location__, attr); \
-                       return WERR_NOMEM; \
-               } \
-               *(p)->elem = IVAL(_a->value_ctr.values[0].blob->data,0);\
-       } else { \
-               (p)->elem = NULL; \
-       } \
-} while (0)
-
-#define GET_GUID_DS(s, r, attr, mem_ctx, p, elem) do { \
-       struct drsuapi_DsReplicaAttribute *_a; \
-       _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
-       if (_a && _a->value_ctr.num_values >= 1 \
-           && _a->value_ctr.values[0].blob \
-           && _a->value_ctr.values[0].blob->length == 16) { \
-               NTSTATUS _nt_status = GUID_from_ndr_blob(_a->value_ctr.values[0].blob, &(p)->elem); \
-               if (!NT_STATUS_IS_OK(_nt_status)) { \
-                       return ntstatus_to_werror(_nt_status); \
-               } \
-       } else { \
-               ZERO_STRUCT((p)->elem);\
-       } \
-} while (0)
-
-#define GET_BLOB_DS(s, r, attr, mem_ctx, p, elem) do { \
-       struct drsuapi_DsReplicaAttribute *_a; \
-       _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
-       if (_a && _a->value_ctr.num_values >= 1 \
-           && _a->value_ctr.values[0].blob) { \
-               (p)->elem = *_a->value_ctr.values[0].blob;\
-               talloc_steal(mem_ctx, (p)->elem.data); \
-       } else { \
-               ZERO_STRUCT((p)->elem);\
-       }\
-} while (0)
-
-WERROR dsdb_attribute_from_drsuapi(struct ldb_context *ldb,
-                                  struct dsdb_schema *schema,
-                                  struct drsuapi_DsReplicaObject *r,
-                                  TALLOC_CTX *mem_ctx,
-                                  struct dsdb_attribute *attr)
-{
-       WERROR status;
-
-       GET_STRING_DS(schema, r, "name", mem_ctx, attr, cn, true);
-       GET_STRING_DS(schema, r, "lDAPDisplayName", mem_ctx, attr, lDAPDisplayName, true);
-       GET_UINT32_DS(schema, r, "attributeID", attr, attributeID_id, 0xFFFFFFFF);
-       status = dsdb_schema_pfm_oid_from_attid(schema->prefixmap, attr->attributeID_id,
-                                               mem_ctx, &attr->attributeID_oid);
-       if (!W_ERROR_IS_OK(status)) {
-               DEBUG(0,("%s: '%s': unable to map attributeID 0x%08X: %s\n",
-                       __location__, attr->lDAPDisplayName, attr->attributeID_id,
-                       win_errstr(status)));
-               return status;
-       }
-       /* fetch msDS-IntId to be used in resolving ATTRTYP values */
-       GET_UINT32_DS(schema, r, "msDS-IntId", attr, msDS_IntId, 0);
-
-       GET_GUID_DS(schema, r, "schemaIDGUID", mem_ctx, attr, schemaIDGUID);
-       GET_UINT32_DS(schema, r, "mAPIID", attr, mAPIID, 0);
-
-       GET_GUID_DS(schema, r, "attributeSecurityGUID", mem_ctx, attr, attributeSecurityGUID);
-
-       attr->objectGUID = r->identifier->guid;
-
-       GET_UINT32_DS(schema, r, "searchFlags", attr, searchFlags, 0);
-       GET_UINT32_DS(schema, r, "systemFlags", attr, systemFlags, 0);
-       GET_BOOL_DS(schema, r, "isMemberOfPartialAttributeSet", attr, isMemberOfPartialAttributeSet, false);
-       GET_UINT32_DS(schema, r, "linkID", attr, linkID, 0);
-
-       GET_UINT32_DS(schema, r, "attributeSyntax", attr, attributeSyntax_id, 0xFFFFFFFF);
-       status = dsdb_schema_pfm_oid_from_attid(schema->prefixmap, attr->attributeSyntax_id,
-                                               mem_ctx, &attr->attributeSyntax_oid);
-       if (!W_ERROR_IS_OK(status)) {
-               DEBUG(0,("%s: '%s': unable to map attributeSyntax 0x%08X: %s\n",
-                       __location__, attr->lDAPDisplayName, attr->attributeSyntax_id,
-                       win_errstr(status)));
-               return status;
-       }
-       GET_UINT32_DS(schema, r, "oMSyntax", attr, oMSyntax, 0);
-       GET_BLOB_DS(schema, r, "oMObjectClass", mem_ctx, attr, oMObjectClass);
-
-       GET_BOOL_DS(schema, r, "isSingleValued", attr, isSingleValued, true);
-       GET_UINT32_PTR_DS(schema, r, "rangeLower", attr, rangeLower);
-       GET_UINT32_PTR_DS(schema, r, "rangeUpper", attr, rangeUpper);
-       GET_BOOL_DS(schema, r, "extendedCharsAllowed", attr, extendedCharsAllowed, false);
-
-       GET_UINT32_DS(schema, r, "schemaFlagsEx", attr, schemaFlagsEx, 0);
-       GET_BLOB_DS(schema, r, "msDs-Schema-Extensions", mem_ctx, attr, msDs_Schema_Extensions);
-
-       GET_BOOL_DS(schema, r, "showInAdvancedViewOnly", attr, showInAdvancedViewOnly, false);
-       GET_STRING_DS(schema, r, "adminDisplayName", mem_ctx, attr, adminDisplayName, false);
-       GET_STRING_DS(schema, r, "adminDescription", mem_ctx, attr, adminDescription, false);
-       GET_STRING_DS(schema, r, "classDisplayName", mem_ctx, attr, classDisplayName, false);
-       GET_BOOL_DS(schema, r, "isEphemeral", attr, isEphemeral, false);
-       GET_BOOL_DS(schema, r, "isDefunct", attr, isDefunct, false);
-       GET_BOOL_DS(schema, r, "systemOnly", attr, systemOnly, false);
-
-       attr->syntax = dsdb_syntax_for_attribute(attr);
-       if (!attr->syntax) {
-               DEBUG(0,(__location__ ": Unknown schema syntax for %s\n",
-                        attr->lDAPDisplayName));
-               return WERR_DS_ATT_SCHEMA_REQ_SYNTAX;
-       }
-
-       if (dsdb_schema_setup_ldb_schema_attribute(ldb, attr) != LDB_SUCCESS) {
-               DEBUG(0,(__location__ ": Unknown schema syntax for %s\n",
-                        attr->lDAPDisplayName));
-               return WERR_DS_ATT_SCHEMA_REQ_SYNTAX;
-       }
-
-       return WERR_OK;
-}
-
-WERROR dsdb_class_from_drsuapi(struct ldb_context *ldb, 
-                              struct dsdb_schema *schema,
-                              struct drsuapi_DsReplicaObject *r,
-                              TALLOC_CTX *mem_ctx,
-                              struct dsdb_class *obj)
-{
-       WERROR status;
-       struct drsuapi_DsReplicaAttribute *attr;
-       DATA_BLOB blob;
-
-       GET_STRING_DS(schema, r, "name", mem_ctx, obj, cn, true);
-       GET_STRING_DS(schema, r, "lDAPDisplayName", mem_ctx, obj, lDAPDisplayName, true);
-       GET_UINT32_DS(schema, r, "governsID", obj, governsID_id, 0xFFFFFFFF);
-       status = dsdb_schema_pfm_oid_from_attid(schema->prefixmap, obj->governsID_id,
-                                               mem_ctx, &obj->governsID_oid);
-       if (!W_ERROR_IS_OK(status)) {
-               DEBUG(0,("%s: '%s': unable to map governsID 0x%08X: %s\n",
-                       __location__, obj->lDAPDisplayName, obj->governsID_id,
-                       win_errstr(status)));
-               return status;
-       }
-       GET_GUID_DS(schema, r, "schemaIDGUID", mem_ctx, obj, schemaIDGUID);
-
-       obj->objectGUID = r->identifier->guid;
-
-       GET_UINT32_DS(schema, r, "objectClassCategory", obj, objectClassCategory, 0);
-       GET_STRING_DS(schema, r, "rDNAttID", mem_ctx, obj, rDNAttID, false);
-
-       attr = dsdb_find_object_attr_name(schema, r, "defaultObjectCategory", NULL); 
-
-       if (!attr || attr->value_ctr.num_values != 1 || !attr->value_ctr.values[0].blob) { 
-               d_printf("%s: no defaultObjectCategory supplied\n", __location__); 
-               return WERR_INVALID_PARAM; 
-       }
-
-       status = dsdb_syntax_one_DN_drsuapi_to_ldb(mem_ctx, ldb, find_syntax_map_by_standard_oid(LDB_SYNTAX_DN), 
-                                                  attr->value_ctr.values[0].blob, &blob);
-       if (!W_ERROR_IS_OK(status)) {
-               return status;
-       }
-       obj->defaultObjectCategory = (char *)blob.data;
-
-       GET_UINT32_DS(schema, r, "subClassOf", obj, subClassOf_id, 0);
-
-       GET_UINT32_LIST_DS(schema, r, "systemAuxiliaryClass", mem_ctx, obj, systemAuxiliaryClass_ids);
-       GET_UINT32_LIST_DS(schema, r, "auxiliaryClass", mem_ctx, obj, auxiliaryClass_ids);
-
-       GET_UINT32_LIST_DS(schema, r, "systemMustContain", mem_ctx, obj, systemMustContain_ids);
-       GET_UINT32_LIST_DS(schema, r, "systemMayContain", mem_ctx, obj, systemMayContain_ids);
-       GET_UINT32_LIST_DS(schema, r, "mustContain", mem_ctx, obj, mustContain_ids);
-       GET_UINT32_LIST_DS(schema, r, "mayContain", mem_ctx, obj, mayContain_ids);
-
-       GET_UINT32_LIST_DS(schema, r, "systemPossSuperiors", mem_ctx, obj, systemPossSuperiors_ids);
-       GET_UINT32_LIST_DS(schema, r, "possSuperiors", mem_ctx, obj, possSuperiors_ids);
-
-       GET_STRING_DS(schema, r, "defaultSecurityDescriptor", mem_ctx, obj, defaultSecurityDescriptor, false);
-
-       GET_UINT32_DS(schema, r, "schemaFlagsEx", obj, schemaFlagsEx, 0);
-       GET_BLOB_DS(schema, r, "msDs-Schema-Extensions", mem_ctx, obj, msDs_Schema_Extensions);
-
-       GET_BOOL_DS(schema, r, "showInAdvancedViewOnly", obj, showInAdvancedViewOnly, false);
-       GET_STRING_DS(schema, r, "adminDisplayName", mem_ctx, obj, adminDisplayName, false);
-       GET_STRING_DS(schema, r, "adminDescription", mem_ctx, obj, adminDescription, false);
-       GET_STRING_DS(schema, r, "classDisplayName", mem_ctx, obj, classDisplayName, false);
-       GET_BOOL_DS(schema, r, "defaultHidingValue", obj, defaultHidingValue, false);
-       GET_BOOL_DS(schema, r, "isDefunct", obj, isDefunct, false);
-       GET_BOOL_DS(schema, r, "systemOnly", obj, systemOnly, false);
-
-       return WERR_OK;
-}
-
index e1e6a2a95c11022b5300c936fd50c17b90ef4182..8a9ba12141b93454475c58340b9a1492b23c42fc 100644 (file)
@@ -189,11 +189,10 @@ static NTSTATUS libnet_vampire_cb_apply_schema(struct libnet_vampire_cb_state *s
        const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr;
        uint32_t object_count;
        struct drsuapi_DsReplicaObjectListItemEx *first_object;
-       struct drsuapi_DsReplicaObjectListItemEx *cur;
        uint32_t linked_attributes_count;
        struct drsuapi_DsReplicaLinkedAttribute *linked_attributes;
        const struct drsuapi_DsReplicaCursor2CtrEx *uptodateness_vector;
-       struct dsdb_extended_replicated_objects *objs;
+       struct dsdb_extended_replicated_objects *schema_objs_1, *schema_objs_2;
        struct repsFromTo1 *s_dsa;
        char *tmp_dns_name;
        struct ldb_message *msg;
@@ -250,85 +249,48 @@ static NTSTATUS libnet_vampire_cb_apply_schema(struct libnet_vampire_cb_state *s
        NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name);
        s_dsa->other_info->dns_name = tmp_dns_name;
 
-       for (cur = first_object; cur; cur = cur->next_object) {
-               bool is_attr = false;
-               bool is_class = false;
-
-               for (i=0; i < cur->object.attribute_ctr.num_attributes; i++) {
-                       struct drsuapi_DsReplicaAttribute *a;
-                       uint32_t j;
-                       const char *oid = NULL;
-
-                       a = &cur->object.attribute_ctr.attributes[i];
-                       status = dsdb_schema_pfm_oid_from_attid(s->self_made_schema->prefixmap,
-                                                               a->attid, s, &oid);
-                       if (!W_ERROR_IS_OK(status)) {
-                               return werror_to_ntstatus(status);
-                       }
-
-                       switch (a->attid) {
-                       case DRSUAPI_ATTRIBUTE_objectClass:
-                               for (j=0; j < a->value_ctr.num_values; j++) {
-                                       uint32_t val = 0xFFFFFFFF;
-
-                                       if (a->value_ctr.values[j].blob
-                                           && a->value_ctr.values[j].blob->length == 4) {
-                                               val = IVAL(a->value_ctr.values[j].blob->data,0);
-                                       }
-
-                                       if (val == DRSUAPI_OBJECTCLASS_attributeSchema) {
-                                               is_attr = true;
-                                       }
-                                       if (val == DRSUAPI_OBJECTCLASS_classSchema) {
-                                               is_class = true;
-                                       }
-                               }
-
-                               break;
-                       default:
-                               break;
-                       }
-               }
-
-               if (is_attr) {
-                       struct dsdb_attribute *sa;
-
-                       sa = talloc_zero(s->self_made_schema, struct dsdb_attribute);
-                       NT_STATUS_HAVE_NO_MEMORY(sa);
-
-                       status = dsdb_attribute_from_drsuapi(s->ldb, s->self_made_schema, &cur->object, s, sa);
-                       if (!W_ERROR_IS_OK(status)) {
-                               return werror_to_ntstatus(status);
-                       }
-
-                       DLIST_ADD_END(s->self_made_schema->attributes, sa, struct dsdb_attribute *);
-               }
-
-               if (is_class) {
-                       struct dsdb_class *sc;
-
-                       sc = talloc_zero(s->self_made_schema, struct dsdb_class);
-                       NT_STATUS_HAVE_NO_MEMORY(sc);
+       /* Now convert the schema elements again, using the schema we just imported */
+       status = dsdb_extended_replicated_objects_convert(s->ldb,
+                                                         c->partition->nc.dn,
+                                                         mapping_ctr,
+                                                         object_count,
+                                                         first_object,
+                                                         linked_attributes_count,
+                                                         linked_attributes,
+                                                         s_dsa,
+                                                         uptodateness_vector,
+                                                         c->gensec_skey,
+                                                         s, &schema_objs_1);
+       if (!W_ERROR_IS_OK(status)) {
+               DEBUG(0,("Failed to convert objects: %s\n", win_errstr(status)));
+               return werror_to_ntstatus(status);
+       }
 
-                       status = dsdb_class_from_drsuapi(s->ldb, s->self_made_schema, &cur->object, s, sc);
-                       if (!W_ERROR_IS_OK(status)) {
-                               return werror_to_ntstatus(status);
-                       }
-                       DLIST_ADD_END(s->self_made_schema->classes, sc, struct dsdb_class *);
+       for (i=0; i < schema_objs_1->num_objects; i++) {
+               status = dsdb_schema_set_el_from_ldb_msg(s->ldb, s->self_made_schema, schema_objs_1->objects[i].msg);
+               if (!W_ERROR_IS_OK(status)) {
+                       DEBUG(0,("Failed to convert object %s into a schema element: %s\n",
+                                ldb_dn_get_linearized(schema_objs_1->objects[i].msg->dn),
+                                win_errstr(status)));
+                       return werror_to_ntstatus(status);
                }
        }
+       /* We don't need the first conversion of the schema any more */
+       talloc_free(schema_objs_1);
 
-       /* attach the schema to the ldb */
+       /* attach the schema we just brought over DRS to the ldb */
        ret = dsdb_set_schema(s->ldb, s->self_made_schema);
        if (ret != LDB_SUCCESS) {
                DEBUG(0,("Failed to attach schema from DRS.\n"));
                return NT_STATUS_FOOBAR;
        }
+
        /* we don't want to access the self made schema anymore */
        s->schema = s->self_made_schema;
        s->self_made_schema = NULL;
 
-       /* Now convert the schema elements again, using the schema we just imported */
+       /* Now convert the schema elements again, using the schema we just imported - we do this
+          'just in case' the schema in our LDIF was wrong, but correct enough to read a valid schema */
        status = dsdb_extended_replicated_objects_convert(s->ldb, 
                                                          c->partition->nc.dn,
                                                          mapping_ctr,
@@ -339,32 +301,32 @@ static NTSTATUS libnet_vampire_cb_apply_schema(struct libnet_vampire_cb_state *s
                                                          s_dsa,
                                                          uptodateness_vector,
                                                          c->gensec_skey,
-                                                         s, &objs);
+                                                         s, &schema_objs_2);
        if (!W_ERROR_IS_OK(status)) {
-               DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status)));
+               DEBUG(0,("Failed to convert objects: %s\n", win_errstr(status)));
                return werror_to_ntstatus(status);
        }
 
        if (lp_parm_bool(s->lp_ctx, NULL, "become dc", "dump objects", false)) {
-               for (i=0; i < objs->num_objects; i++) {
+               for (i=0; i < schema_objs_2->num_objects; i++) {
                        struct ldb_ldif ldif;
                        fprintf(stdout, "#\n");
                        ldif.changetype = LDB_CHANGETYPE_NONE;
-                       ldif.msg = objs->objects[i].msg;
+                       ldif.msg = schema_objs_2->objects[i].msg;
                        ldb_ldif_write_file(s->ldb, stdout, &ldif);
-                       NDR_PRINT_DEBUG(replPropertyMetaDataBlob, objs->objects[i].meta_data);
+                       NDR_PRINT_DEBUG(replPropertyMetaDataBlob, schema_objs_2->objects[i].meta_data);
                }
        }
 
-       status = dsdb_extended_replicated_objects_commit(s->ldb, objs, &seq_num);
+       status = dsdb_extended_replicated_objects_commit(s->ldb, schema_objs_2, &seq_num);
        if (!W_ERROR_IS_OK(status)) {
                DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status)));
                return werror_to_ntstatus(status);
        }
 
-       msg = ldb_msg_new(objs);
+       msg = ldb_msg_new(schema_objs_2);
        NT_STATUS_HAVE_NO_MEMORY(msg);
-       msg->dn = objs->partition_dn;
+       msg->dn = schema_objs_2->partition_dn;
 
        status = dsdb_get_oid_mappings_ldb(s->schema, msg, &prefixMap_val, &schemaInfo_val);
        if (!W_ERROR_IS_OK(status)) {
@@ -381,12 +343,12 @@ static NTSTATUS libnet_vampire_cb_apply_schema(struct libnet_vampire_cb_state *s
 
        ret = ldb_modify(s->ldb, msg);
        if (ret != LDB_SUCCESS) {
-               DEBUG(0,("Failed to add prefixMap and schemaInfo %s\n", ldb_strerror(ret)));
+               DEBUG(0,("Failed to add prefixMap: %s\n", ldb_strerror(ret)));
                return NT_STATUS_FOOBAR;
        }
 
        talloc_free(s_dsa);
-       talloc_free(objs);
+       talloc_free(schema_objs_2);
 
        /* We must set these up to ensure the replMetaData is written
         * correctly, before our NTDS Settings entry is replicated */