1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-03 01:18:10 +03:00

drepl: schema repl race condition fix

Adds final schema consistency check before committing changes.
Aborts if corruption found.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12889
Signed-off-by: Aaron Haslett <aaronhaslett@catalyst.net.nz>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
Aaron Haslett 2018-11-21 13:55:53 +13:00 committed by Andrew Bartlett
parent f460bb52ed
commit 1fd4cdfafa
3 changed files with 62 additions and 20 deletions

View File

@ -914,8 +914,10 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
}
talloc_free(ext_res);
/* Save our updated prefixMap */
/* Save our updated prefixMap and check the schema is good. */
if (working_schema) {
struct ldb_result *ext_res_2;
werr = dsdb_write_prefixes_from_schema_to_ldb(working_schema,
ldb,
working_schema);
@ -924,7 +926,9 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
if (used_global_schema) {
dsdb_set_global_schema(ldb);
} else if (cur_schema ) {
dsdb_reference_schema(ldb, cur_schema, SCHEMA_MEMORY_ONLY);
dsdb_reference_schema(ldb,
cur_schema,
SCHEMA_MEMORY_ONLY);
}
DEBUG(0,("Failed to save updated prefixMap: %s\n",
win_errstr(werr)));
@ -932,6 +936,33 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
TALLOC_FREE(tmp_ctx);
return werr;
}
/*
* Use dsdb_schema_from_db through dsdb extended to check we
* can load the schema currently sitting in the transaction.
* We need this check because someone might have written to
* the schema or prefixMap before we started the transaction,
* which may have caused corruption.
*/
ret = ldb_extended(ldb, DSDB_EXTENDED_SCHEMA_LOAD,
NULL, &ext_res_2);
if (ret != LDB_SUCCESS) {
if (used_global_schema) {
dsdb_set_global_schema(ldb);
} else if (cur_schema) {
dsdb_reference_schema(ldb, cur_schema, SCHEMA_MEMORY_ONLY);
}
DEBUG(0,("Corrupt schema write attempt detected, "
"aborting schema modification operation.\n"
"This probably happened due to bad timing of "
"another schema edit: %s (%s)\n",
ldb_errstring(ldb),
ldb_strerror(ret)));
ldb_transaction_cancel(ldb);
TALLOC_FREE(tmp_ctx);
return WERR_FOOBAR;
}
}
ret = ldb_transaction_prepare_commit(ldb);

View File

@ -552,9 +552,15 @@ static int schema_load_extended(struct ldb_module *module, struct ldb_request *r
struct dsdb_schema *schema;
int ret;
if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID) != 0) {
return ldb_next_request(module, req);
if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SCHEMA_LOAD) == 0) {
ret = dsdb_schema_from_db(module, req, 0, &schema);
if (ret == LDB_SUCCESS) {
return ldb_module_done(req, NULL, NULL, LDB_SUCCESS);
}
return ret;
} else if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID) == 0) {
/* Force a refresh */
schema = dsdb_get_schema(ldb, NULL);
@ -570,9 +576,12 @@ static int schema_load_extended(struct ldb_module *module, struct ldb_request *r
return ret;
}
return ldb_next_request(module, req);
} else {
/* Pass to next module, the partition one should finish the chain */
return ldb_next_request(module, req);
}
}
static int schema_read_lock(struct ldb_module *module)
{

View File

@ -272,6 +272,8 @@ struct dsdb_create_partition_exop {
*/
#define DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID "1.3.6.1.4.1.7165.4.4.2"
#define DSDB_EXTENDED_SCHEMA_LOAD "1.3.6.1.4.1.7165.4.4.10"
#define DSDB_EXTENDED_SCHEMA_UPGRADE_IN_PROGRESS_OID "1.3.6.1.4.1.7165.4.4.6"
#define DSDB_OPENLDAP_DEREFERENCE_CONTROL "1.3.6.1.4.1.4203.666.5.16"