WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const char *df, const char *dn) { struct ldb_ldif *ldif; struct ldb_message *msg; TALLOC_CTX *mem_ctx; WERROR status; int ret; struct dsdb_schema *schema; const struct ldb_val *prefix_val; const struct ldb_val *info_val; struct ldb_val info_val_default; mem_ctx = talloc_new(ldb); if (!mem_ctx) { goto nomem; } schema = dsdb_new_schema(mem_ctx); if (!schema) { goto nomem; } schema->base_dn = ldb_dn_new(schema, ldb, dn); if (!schema->base_dn) { goto nomem; } schema->fsmo.we_are_master = true; schema->fsmo.update_allowed = true; schema->fsmo.master_dn = ldb_dn_new(schema, ldb, "@PROVISION_SCHEMA_MASTER"); if (!schema->fsmo.master_dn) { goto nomem; } /* * load the prefixMap attribute from pf */ ldif = ldb_ldif_read_string(ldb, &pf); if (!ldif) { status = WERR_INVALID_PARAM; goto failed; } talloc_steal(mem_ctx, ldif); ret = ldb_msg_normalize(ldb, mem_ctx, ldif->msg, &msg); if (ret != LDB_SUCCESS) { goto nomem; } talloc_free(ldif); prefix_val = ldb_msg_find_ldb_val(msg, "prefixMap"); if (!prefix_val) { status = WERR_INVALID_PARAM; goto failed; } info_val = ldb_msg_find_ldb_val(msg, "schemaInfo"); if (!info_val) { status = dsdb_schema_info_blob_new(mem_ctx, &info_val_default); W_ERROR_NOT_OK_GOTO(status, failed); info_val = &info_val_default; } status = dsdb_load_oid_mappings_ldb(schema, prefix_val, info_val); if (!W_ERROR_IS_OK(status)) { DEBUG(0,("ERROR: dsdb_load_oid_mappings_ldb() failed with %s\n", win_errstr(status))); goto failed; } /* load the attribute and class definitions out of df */ while ((ldif = ldb_ldif_read_string(ldb, &df))) { talloc_steal(mem_ctx, ldif); ret = ldb_msg_normalize(ldb, ldif, ldif->msg, &msg); if (ret != LDB_SUCCESS) { goto nomem; } status = dsdb_schema_set_el_from_ldb_msg(ldb, schema, msg); talloc_free(ldif); if (!W_ERROR_IS_OK(status)) { goto failed; } } ret = dsdb_set_schema(ldb, schema); if (ret != LDB_SUCCESS) { status = WERR_FOOBAR; goto failed; } ret = dsdb_schema_fill_extended_dn(ldb, schema); if (ret != LDB_SUCCESS) { status = WERR_FOOBAR; goto failed; } goto done; nomem: status = WERR_NOMEM; failed: done: talloc_free(mem_ctx); return status; }
/** * Loads dsdb_schema from ldb connection using remote prefixMap. * Schema will be loaded only if: * - ldb has no attached schema * - reload_schema is true * * This function is to be used in tests that use GetNCChanges() function */ bool drs_util_dsdb_schema_load_ldb(struct torture_context *tctx, struct ldb_context *ldb, const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr, bool reload_schema) { int i, ret; WERROR werr; const char *err_msg; struct ldb_result *a_res; struct ldb_result *c_res; struct ldb_dn *schema_dn; struct dsdb_schema *ldap_schema; ldap_schema = dsdb_get_schema(ldb, NULL); if (ldap_schema && !reload_schema) { return true; } schema_dn = ldb_get_schema_basedn(ldb); torture_assert(tctx, schema_dn != NULL, talloc_asprintf(tctx, "ldb_get_schema_basedn() failed: %s", ldb_errstring(ldb))); ldap_schema = dsdb_new_schema(ldb); torture_assert(tctx, ldap_schema != NULL, "dsdb_new_schema() failed!"); werr = dsdb_load_prefixmap_from_drsuapi(ldap_schema, mapping_ctr); torture_assert_werr_ok(tctx, werr, "Failed to construct prefixMap from drsuapi data"); /* * load the attribute definitions */ ret = ldb_search(ldb, ldap_schema, &a_res, schema_dn, LDB_SCOPE_ONELEVEL, NULL, "(objectClass=attributeSchema)"); if (ret != LDB_SUCCESS) { err_msg = talloc_asprintf(tctx, "failed to search attributeSchema objects: %s", ldb_errstring(ldb)); torture_fail(tctx, err_msg); } /* * load the objectClass definitions */ ret = ldb_search(ldb, ldap_schema, &c_res, schema_dn, LDB_SCOPE_ONELEVEL, NULL, "(objectClass=classSchema)"); if (ret != LDB_SUCCESS) { err_msg = talloc_asprintf(tctx, "failed to search classSchema objects: %s", ldb_errstring(ldb)); torture_fail(tctx, err_msg); } /* Build schema */ for (i=0; i < a_res->count; i++) { werr = dsdb_attribute_from_ldb(ldb, ldap_schema, a_res->msgs[i]); torture_assert_werr_ok(tctx, werr, talloc_asprintf(tctx, "dsdb_attribute_from_ldb() failed for: %s", ldb_dn_get_linearized(a_res->msgs[i]->dn))); } for (i=0; i < c_res->count; i++) { werr = dsdb_class_from_ldb(ldap_schema, c_res->msgs[i]); torture_assert_werr_ok(tctx, werr, talloc_asprintf(tctx, "dsdb_class_from_ldb() failed for: %s", ldb_dn_get_linearized(c_res->msgs[i]->dn))); } talloc_free(a_res); talloc_free(c_res); ret = dsdb_set_schema(ldb, ldap_schema); if (ret != LDB_SUCCESS) { torture_fail(tctx, talloc_asprintf(tctx, "dsdb_set_schema() failed: %s", ldb_strerror(ret))); } return true; }
int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct ldb_result *schema_res, struct ldb_result *attrs_class_res, struct dsdb_schema **schema_out, char **error_string) { WERROR status; const struct ldb_val *prefix_val; const struct ldb_val *info_val; struct ldb_val info_val_default; struct dsdb_schema *schema; struct loadparm_context *lp_ctx = NULL; int ret; schema = dsdb_new_schema(mem_ctx); if (!schema) { dsdb_oom(error_string, mem_ctx); return ldb_operr(ldb); } schema->base_dn = talloc_steal(schema, schema_res->msgs[0]->dn); prefix_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "prefixMap"); if (!prefix_val) { *error_string = talloc_asprintf(mem_ctx, "schema_fsmo_init: no prefixMap attribute found"); DEBUG(0,(__location__ ": %s\n", *error_string)); return LDB_ERR_CONSTRAINT_VIOLATION; } info_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "schemaInfo"); if (!info_val) { status = dsdb_schema_info_blob_new(mem_ctx, &info_val_default); if (!W_ERROR_IS_OK(status)) { *error_string = talloc_asprintf(mem_ctx, "schema_fsmo_init: dsdb_schema_info_blob_new() failed - %s", win_errstr(status)); DEBUG(0,(__location__ ": %s\n", *error_string)); return ldb_operr(ldb); } info_val = &info_val_default; } status = dsdb_load_oid_mappings_ldb(schema, prefix_val, info_val); if (!W_ERROR_IS_OK(status)) { *error_string = talloc_asprintf(mem_ctx, "schema_fsmo_init: failed to load oid mappings: %s", win_errstr(status)); DEBUG(0,(__location__ ": %s\n", *error_string)); return LDB_ERR_CONSTRAINT_VIOLATION; } ret = dsdb_load_ldb_results_into_schema(mem_ctx, ldb, schema, attrs_class_res, error_string); if (ret != LDB_SUCCESS) { return ret; } schema->fsmo.master_dn = ldb_msg_find_attr_as_dn(ldb, schema, schema_res->msgs[0], "fSMORoleOwner"); if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), schema->fsmo.master_dn) == 0) { schema->fsmo.we_are_master = true; } else { schema->fsmo.we_are_master = false; } lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"), struct loadparm_context); if (lp_ctx) { bool allowed = lpcfg_parm_bool(lp_ctx, NULL, "dsdb", "schema update allowed", false); schema->fsmo.update_allowed = allowed; } else { schema->fsmo.update_allowed = false; } DEBUG(5, ("schema_fsmo_init: we are master[%s] updates allowed[%s]\n", (schema->fsmo.we_are_master?"yes":"no"), (schema->fsmo.update_allowed?"yes":"no"))); *schema_out = schema; return LDB_SUCCESS; }
struct dsdb_schema *dsdb_schema_copy_shallow(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const struct dsdb_schema *schema) { int ret; struct dsdb_class *cls; struct dsdb_attribute *attr; struct dsdb_schema *schema_copy; schema_copy = dsdb_new_schema(mem_ctx); if (!schema_copy) { return NULL; } /* schema base_dn */ schema_copy->base_dn = ldb_dn_copy(schema_copy, schema->base_dn); if (!schema_copy->base_dn) { goto failed; } /* copy prexiMap & schemaInfo */ schema_copy->prefixmap = dsdb_schema_pfm_copy_shallow(schema_copy, schema->prefixmap); if (!schema_copy->prefixmap) { goto failed; } schema_copy->schema_info = talloc_strdup(schema_copy, schema->schema_info); /* copy classes and attributes*/ for (cls = schema->classes; cls; cls = cls->next) { struct dsdb_class *class_copy = talloc_memdup(schema_copy, cls, sizeof(*cls)); if (!class_copy) { goto failed; } DLIST_ADD(schema_copy->classes, class_copy); } schema_copy->num_classes = schema->num_classes; for (attr = schema->attributes; attr; attr = attr->next) { struct dsdb_attribute *a_copy = talloc_memdup(schema_copy, attr, sizeof(*attr)); if (!a_copy) { goto failed; } DLIST_ADD(schema_copy->attributes, a_copy); } schema_copy->num_attributes = schema->num_attributes; /* rebuild indexes */ ret = dsdb_setup_sorted_accessors(ldb, schema_copy); if (ret != LDB_SUCCESS) { goto failed; } /* leave reload_seq_number = 0 so it will be refresh ASAP */ schema_copy->refresh_fn = schema->refresh_fn; schema_copy->loaded_from_module = schema->loaded_from_module; return schema_copy; failed: talloc_free(schema_copy); return NULL; }
int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct ldb_result *schema_res, struct ldb_result *attrs_res, struct ldb_result *objectclass_res, struct dsdb_schema **schema_out, char **error_string) { WERROR status; unsigned int i; const struct ldb_val *prefix_val; const struct ldb_val *info_val; struct ldb_val info_val_default; struct dsdb_schema *schema; schema = dsdb_new_schema(mem_ctx); if (!schema) { dsdb_oom(error_string, mem_ctx); return ldb_operr(ldb); } schema->base_dn = talloc_steal(schema, schema_res->msgs[0]->dn); prefix_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "prefixMap"); if (!prefix_val) { *error_string = talloc_asprintf(mem_ctx, "schema_fsmo_init: no prefixMap attribute found"); DEBUG(0,(__location__ ": %s\n", *error_string)); return LDB_ERR_CONSTRAINT_VIOLATION; } info_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "schemaInfo"); if (!info_val) { status = dsdb_schema_info_blob_new(mem_ctx, &info_val_default); if (!W_ERROR_IS_OK(status)) { *error_string = talloc_asprintf(mem_ctx, "schema_fsmo_init: dsdb_schema_info_blob_new() failed - %s", win_errstr(status)); DEBUG(0,(__location__ ": %s\n", *error_string)); return ldb_operr(ldb); } info_val = &info_val_default; } status = dsdb_load_oid_mappings_ldb(schema, prefix_val, info_val); if (!W_ERROR_IS_OK(status)) { *error_string = talloc_asprintf(mem_ctx, "schema_fsmo_init: failed to load oid mappings: %s", win_errstr(status)); DEBUG(0,(__location__ ": %s\n", *error_string)); return LDB_ERR_CONSTRAINT_VIOLATION; } for (i=0; i < attrs_res->count; i++) { status = dsdb_attribute_from_ldb(ldb, schema, attrs_res->msgs[i]); if (!W_ERROR_IS_OK(status)) { *error_string = talloc_asprintf(mem_ctx, "schema_fsmo_init: failed to load attribute definition: %s:%s", ldb_dn_get_linearized(attrs_res->msgs[i]->dn), win_errstr(status)); DEBUG(0,(__location__ ": %s\n", *error_string)); return LDB_ERR_CONSTRAINT_VIOLATION; } } for (i=0; i < objectclass_res->count; i++) { status = dsdb_class_from_ldb(schema, objectclass_res->msgs[i]); if (!W_ERROR_IS_OK(status)) { *error_string = talloc_asprintf(mem_ctx, "schema_fsmo_init: failed to load class definition: %s:%s", ldb_dn_get_linearized(objectclass_res->msgs[i]->dn), win_errstr(status)); DEBUG(0,(__location__ ": %s\n", *error_string)); return LDB_ERR_CONSTRAINT_VIOLATION; } } schema->fsmo.master_dn = ldb_msg_find_attr_as_dn(ldb, schema, schema_res->msgs[0], "fSMORoleOwner"); if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), schema->fsmo.master_dn) == 0) { schema->fsmo.we_are_master = true; } else { schema->fsmo.we_are_master = false; } DEBUG(5, ("schema_fsmo_init: we are master: %s\n", (schema->fsmo.we_are_master?"yes":"no"))); *schema_out = schema; return LDB_SUCCESS; }
WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const char *df) { struct ldb_ldif *ldif; struct ldb_message *msg; TALLOC_CTX *mem_ctx; WERROR status; int ret; struct dsdb_schema *schema; const struct ldb_val *prefix_val; const struct ldb_val *info_val; struct ldb_val info_val_default; mem_ctx = talloc_new(ldb); if (!mem_ctx) { goto nomem; } schema = dsdb_new_schema(mem_ctx, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm"))); schema->fsmo.we_are_master = true; schema->fsmo.master_dn = ldb_dn_new_fmt(schema, ldb, "@PROVISION_SCHEMA_MASTER"); if (!schema->fsmo.master_dn) { goto nomem; } /* * load the prefixMap attribute from pf */ ldif = ldb_ldif_read_string(ldb, &pf); if (!ldif) { status = WERR_INVALID_PARAM; goto failed; } talloc_steal(mem_ctx, ldif); msg = ldb_msg_canonicalize(ldb, ldif->msg); if (!msg) { goto nomem; } talloc_steal(mem_ctx, msg); talloc_free(ldif); prefix_val = ldb_msg_find_ldb_val(msg, "prefixMap"); if (!prefix_val) { status = WERR_INVALID_PARAM; goto failed; } info_val = ldb_msg_find_ldb_val(msg, "schemaInfo"); if (!info_val) { info_val_default = strhex_to_data_blob(mem_ctx, "FF0000000000000000000000000000000000000000"); if (!info_val_default.data) { goto nomem; } info_val = &info_val_default; } status = dsdb_load_oid_mappings_ldb(schema, prefix_val, info_val); if (!W_ERROR_IS_OK(status)) { goto failed; } /* * load the attribute and class definitions outof df */ while ((ldif = ldb_ldif_read_string(ldb, &df))) { talloc_steal(mem_ctx, ldif); msg = ldb_msg_canonicalize(ldb, ldif->msg); if (!msg) { goto nomem; } status = dsdb_schema_set_el_from_ldb_msg(ldb, schema, msg); talloc_free(ldif); if (!W_ERROR_IS_OK(status)) { goto failed; } } ret = dsdb_set_schema(ldb, schema); if (ret != LDB_SUCCESS) { status = WERR_FOOBAR; goto failed; } ret = dsdb_schema_fill_extended_dn(ldb, schema); if (ret != LDB_SUCCESS) { status = WERR_FOOBAR; goto failed; } goto done; nomem: status = WERR_NOMEM; failed: done: talloc_free(mem_ctx); return status; }