static WERROR _dsdb_prefixmap_from_ldb_val(const struct ldb_val *pfm_ldb_val, struct smb_iconv_convenience *iconv_convenience, TALLOC_CTX *mem_ctx, struct dsdb_schema_prefixmap **_pfm) { WERROR werr; enum ndr_err_code ndr_err; struct prefixMapBlob pfm_blob; TALLOC_CTX *temp_ctx = talloc_new(mem_ctx); W_ERROR_HAVE_NO_MEMORY(temp_ctx); ndr_err = ndr_pull_struct_blob(pfm_ldb_val, temp_ctx, iconv_convenience, &pfm_blob, (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err); talloc_free(temp_ctx); return ntstatus_to_werror(nt_status); } if (pfm_blob.version != PREFIX_MAP_VERSION_DSDB) { DEBUG(0,("_dsdb_prefixmap_from_ldb_val: pfm_blob->version incorrect\n")); talloc_free(temp_ctx); return WERR_VERSION_PARSE_ERROR; } /* call the drsuapi version */ werr = dsdb_schema_pfm_from_drsuapi_pfm(&pfm_blob.ctr.dsdb, false, mem_ctx, _pfm, NULL); talloc_free(temp_ctx); return werr; }
/** * Multi-pass working schema creation * Function will: * - shallow copy initial schema supplied * - create a working schema in multiple passes * until all objects are resolved * Working schema is a schema with Attributes, Classes * and indexes, but w/o subClassOf, possibleSupperiors etc. * It is to be used just us cache for converting attribute values. */ WERROR dsdb_repl_make_working_schema(struct ldb_context *ldb, const struct dsdb_schema *initial_schema, const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr, uint32_t object_count, const struct drsuapi_DsReplicaObjectListItemEx *first_object, const DATA_BLOB *gensec_skey, TALLOC_CTX *mem_ctx, struct dsdb_schema **_schema_out) { WERROR werr; struct dsdb_schema_prefixmap *pfm_remote; struct dsdb_schema *working_schema; /* make a copy of the iniatial_scheam so we don't mess with it */ working_schema = dsdb_schema_copy_shallow(mem_ctx, ldb, initial_schema); if (!working_schema) { DEBUG(0,(__location__ ": schema copy failed!\n")); return WERR_NOMEM; } /* we are going to need remote prefixMap for decoding */ werr = dsdb_schema_pfm_from_drsuapi_pfm(mapping_ctr, true, mem_ctx, &pfm_remote, NULL); if (!W_ERROR_IS_OK(werr)) { DEBUG(0,(__location__ ": Failed to decode remote prefixMap: %s", win_errstr(werr))); return werr; } werr = dsdb_repl_resolve_working_schema(ldb, mem_ctx, pfm_remote, 0, /* cycle_before_switching */ working_schema, working_schema, object_count, first_object); if (!W_ERROR_IS_OK(werr)) { DEBUG(0, ("%s: dsdb_repl_resolve_working_schema() failed: %s", __location__, win_errstr(werr))); return werr; } *_schema_out = working_schema; return WERR_OK; }
WERROR dsdb_load_prefixmap_from_drsuapi(struct dsdb_schema *schema, const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr) { WERROR werr; const char *schema_info; struct dsdb_schema_prefixmap *pfm; werr = dsdb_schema_pfm_from_drsuapi_pfm(ctr, true, schema, &pfm, &schema_info); W_ERROR_NOT_OK_RETURN(werr); /* set loaded prefixMap */ talloc_free(schema->prefixmap); schema->prefixmap = pfm; talloc_free(discard_const(schema->schema_info)); schema->schema_info = schema_info; return WERR_OK; }
static WERROR _dsdb_prefixmap_from_ldb_val(const struct ldb_val *pfm_ldb_val, TALLOC_CTX *mem_ctx, struct dsdb_schema_prefixmap **_pfm) { WERROR werr; enum ndr_err_code ndr_err; struct prefixMapBlob pfm_blob; TALLOC_CTX *temp_ctx = talloc_new(mem_ctx); W_ERROR_HAVE_NO_MEMORY(temp_ctx); ndr_err = ndr_pull_struct_blob(pfm_ldb_val, temp_ctx, &pfm_blob, (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err); DEBUG(0,("_dsdb_prefixmap_from_ldb_val: Failed to parse prefixmap of length %u: %s\n", (unsigned int)pfm_ldb_val->length, ndr_map_error2string(ndr_err))); talloc_free(temp_ctx); return ntstatus_to_werror(nt_status); } if (pfm_blob.version != PREFIX_MAP_VERSION_DSDB) { DEBUG(0,("_dsdb_prefixmap_from_ldb_val: pfm_blob->version %u incorrect\n", (unsigned int)pfm_blob.version)); talloc_free(temp_ctx); return WERR_VERSION_PARSE_ERROR; } /* call the drsuapi version */ werr = dsdb_schema_pfm_from_drsuapi_pfm(&pfm_blob.ctr.dsdb, false, mem_ctx, _pfm, NULL); if (!W_ERROR_IS_OK(werr)) { DEBUG(0, (__location__ " dsdb_schema_pfm_from_drsuapi_pfm failed: %s\n", win_errstr(werr))); talloc_free(temp_ctx); return werr; } talloc_free(temp_ctx); return werr; }
WERROR dsdb_replicated_objects_convert(struct ldb_context *ldb, const struct dsdb_schema *schema, const char *partition_dn_str, const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr, uint32_t object_count, const struct drsuapi_DsReplicaObjectListItemEx *first_object, uint32_t linked_attributes_count, const struct drsuapi_DsReplicaLinkedAttribute *linked_attributes, const struct repsFromTo1 *source_dsa, const struct drsuapi_DsReplicaCursor2CtrEx *uptodateness_vector, const DATA_BLOB *gensec_skey, uint32_t dsdb_repl_flags, TALLOC_CTX *mem_ctx, struct dsdb_extended_replicated_objects **objects) { WERROR status; struct ldb_dn *partition_dn; struct dsdb_schema_prefixmap *pfm_remote; struct dsdb_extended_replicated_objects *out; const struct drsuapi_DsReplicaObjectListItemEx *cur; uint32_t i; out = talloc_zero(mem_ctx, struct dsdb_extended_replicated_objects); W_ERROR_HAVE_NO_MEMORY(out); out->version = DSDB_EXTENDED_REPLICATED_OBJECTS_VERSION; out->dsdb_repl_flags = dsdb_repl_flags; /* * Ensure schema is kept valid for as long as 'out' * which may contain pointers to it */ schema = talloc_reference(out, schema); W_ERROR_HAVE_NO_MEMORY(schema); partition_dn = ldb_dn_new(out, ldb, partition_dn_str); W_ERROR_HAVE_NO_MEMORY_AND_FREE(partition_dn, out); status = dsdb_schema_pfm_from_drsuapi_pfm(mapping_ctr, true, out, &pfm_remote, NULL); if (!W_ERROR_IS_OK(status)) { DEBUG(0,(__location__ ": Failed to decode remote prefixMap: %s", win_errstr(status))); talloc_free(out); return status; } if (ldb_dn_compare(partition_dn, ldb_get_schema_basedn(ldb)) != 0) { /* * check for schema changes in case * we are not replicating Schema NC */ status = dsdb_schema_info_cmp(schema, mapping_ctr); if (!W_ERROR_IS_OK(status)) { DEBUG(1,("Remote schema has changed while replicating %s\n", partition_dn_str)); talloc_free(out); return status; } } out->partition_dn = partition_dn; out->source_dsa = source_dsa; out->uptodateness_vector= uptodateness_vector; out->num_objects = object_count; out->objects = talloc_array(out, struct dsdb_extended_replicated_object, out->num_objects); W_ERROR_HAVE_NO_MEMORY_AND_FREE(out->objects, out); /* pass the linked attributes down to the repl_meta_data module */ out->linked_attributes_count = linked_attributes_count; out->linked_attributes = linked_attributes; for (i=0, cur = first_object; cur; cur = cur->next_object, i++) { if (i == out->num_objects) { talloc_free(out); return WERR_FOOBAR; } status = dsdb_convert_object_ex(ldb, schema, pfm_remote, cur, gensec_skey, NULL, dsdb_repl_flags, out->objects, &out->objects[i]); if (!W_ERROR_IS_OK(status)) { talloc_free(out); DEBUG(0,("Failed to convert object %s: %s\n", cur->object.identifier->dn, win_errstr(status))); return status; } } if (i != out->num_objects) { talloc_free(out); return WERR_FOOBAR; } /* free pfm_remote, we won't need it anymore */ talloc_free(pfm_remote); *objects = out; return WERR_OK; }