diff options
author | Stefan Metzmacher <metze@samba.org> | 2011-11-11 15:54:11 +0100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2011-11-15 09:46:29 +0100 |
commit | 38868c8b7f9c099158c62f8c653e10d5ca1c91ac (patch) | |
tree | b5f327f15279b3be63ed25ceb9eb1eac7d5d88aa | |
parent | 76b99bb379f2372903288c680e9b9abf85b02e09 (diff) | |
download | samba-38868c8b7f9c099158c62f8c653e10d5ca1c91ac.tar.gz samba-38868c8b7f9c099158c62f8c653e10d5ca1c91ac.tar.bz2 samba-38868c8b7f9c099158c62f8c653e10d5ca1c91ac.zip |
s4:dsdb/schema_data: make sure we reject schema changes if we're not the schema master
metze
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/schema_data.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/schema_data.c b/source4/dsdb/samdb/ldb_modules/schema_data.c index a2f2267d43..3d50d99ac2 100644 --- a/source4/dsdb/samdb/ldb_modules/schema_data.c +++ b/source4/dsdb/samdb/ldb_modules/schema_data.c @@ -243,6 +243,105 @@ static int schema_data_add(struct ldb_module *module, struct ldb_request *req) return ldb_next_request(module, req); } +static int schema_data_modify(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct dsdb_schema *schema; + int cmp; + bool rodc = false; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* special objects should always go through */ + if (ldb_dn_is_special(req->op.mod.message->dn)) { + return ldb_next_request(module, req); + } + + /* replicated update should always go through */ + if (ldb_request_get_control(req, DSDB_CONTROL_REPLICATED_UPDATE_OID)) { + return ldb_next_request(module, req); + } + + /* dbcheck should be able to fix things */ + if (ldb_request_get_control(req, DSDB_CONTROL_DBCHECK)) { + return ldb_next_request(module, req); + } + + schema = dsdb_get_schema(ldb, req); + if (!schema) { + return ldb_next_request(module, req); + } + + cmp = ldb_dn_compare(req->op.mod.message->dn, schema->base_dn); + if (cmp == 0) { + return ldb_next_request(module, req); + } + + ret = samdb_rodc(ldb, &rodc); + if (ret != LDB_SUCCESS) { + DEBUG(4, (__location__ ": unable to tell if we are an RODC \n")); + } + + if (!schema->fsmo.we_are_master && !rodc) { + ldb_debug_set(ldb, LDB_DEBUG_ERROR, + "schema_data_modify: we are not master: reject request\n"); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + return ldb_next_request(module, req); +} + +static int schema_data_del(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct dsdb_schema *schema; + bool rodc = false; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* special objects should always go through */ + if (ldb_dn_is_special(req->op.del.dn)) { + return ldb_next_request(module, req); + } + + /* replicated update should always go through */ + if (ldb_request_get_control(req, DSDB_CONTROL_REPLICATED_UPDATE_OID)) { + return ldb_next_request(module, req); + } + + /* dbcheck should be able to fix things */ + if (ldb_request_get_control(req, DSDB_CONTROL_DBCHECK)) { + return ldb_next_request(module, req); + } + + schema = dsdb_get_schema(ldb, req); + if (!schema) { + return ldb_next_request(module, req); + } + + ret = samdb_rodc(ldb, &rodc); + if (ret != LDB_SUCCESS) { + DEBUG(4, (__location__ ": unable to tell if we are an RODC \n")); + } + + if (!schema->fsmo.we_are_master && !rodc) { + ldb_debug_set(ldb, LDB_DEBUG_ERROR, + "schema_data_modify: we are not master: reject request\n"); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + /* + * normaly the DACL will prevent delete + * with LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS + * above us. + */ + ldb_debug_set(ldb, LDB_DEBUG_ERROR, + "schema_data_del: delete is not allowed in the schema\n"); + return LDB_ERR_UNWILLING_TO_PERFORM; +} + static int generate_objectClasses(struct ldb_context *ldb, struct ldb_message *msg, const struct dsdb_schema *schema) { @@ -512,6 +611,8 @@ static const struct ldb_module_ops ldb_schema_data_module_ops = { .name = "schema_data", .init_context = schema_data_init, .add = schema_data_add, + .modify = schema_data_modify, + .del = schema_data_del, .search = schema_data_search }; |