diff options
Diffstat (limited to 'source4/dsdb/samdb/ldb_modules/repl_meta_data.c')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 11e043f5d0..374467cb94 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -1076,6 +1076,7 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb, */ static int replmd_update_rpmd(struct ldb_module *module, const struct dsdb_schema *schema, + struct ldb_request *req, struct ldb_message *msg, uint64_t *seq_num, time_t t, bool *is_urgent) @@ -1092,6 +1093,7 @@ static int replmd_update_rpmd(struct ldb_module *module, struct ldb_context *ldb; struct ldb_message_element *objectclass_el; enum urgent_situation situation; + bool rodc; ldb = ldb_module_get_ctx(module); @@ -1157,6 +1159,20 @@ static int replmd_update_rpmd(struct ldb_module *module, return LDB_ERR_OPERATIONS_ERROR; } + /*we have elements that will be modified*/ + if (msg->num_elements > 0) { + /*if we are RODC and this is a DRSR update then its ok*/ + if (!ldb_request_get_control(req, DSDB_CONTROL_REPLICATED_UPDATE_OID)) { + ret = samdb_rodc(ldb, &rodc); + if (ret != LDB_SUCCESS) { + DEBUG(4, (__location__ ": unable to tell if we are an RODC\n")); + } else if (rodc) { + ldb_asprintf_errstring(ldb, "RODC modify is forbidden\n"); + return LDB_ERR_REFERRAL; + } + } + } + for (i=0; i<msg->num_elements; i++) { struct ldb_message_element *old_el; old_el = ldb_msg_find_element(res->msgs[0], msg->elements[i].name); @@ -2043,6 +2059,8 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) time_t t = time(NULL); int ret; bool is_urgent = false; + struct loadparm_context *lp_ctx; + char *referral; /* do not manipulate our control entries */ if (ldb_dn_is_special(req->op.mod.message->dn)) { @@ -2050,6 +2068,8 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) } ldb = ldb_module_get_ctx(module); + lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"), + struct loadparm_context); ldb_debug(ldb, LDB_DEBUG_TRACE, "replmd_modify\n"); @@ -2069,7 +2089,18 @@ static int replmd_modify(struct ldb_module *module, struct ldb_request *req) ldb_msg_remove_attr(msg, "whenChanged"); ldb_msg_remove_attr(msg, "uSNChanged"); - ret = replmd_update_rpmd(module, ac->schema, msg, &ac->seq_num, t, &is_urgent); + ret = replmd_update_rpmd(module, ac->schema, req, msg, &ac->seq_num, t, &is_urgent); + if (ret == LDB_ERR_REFERRAL) { + talloc_free(ac); + + referral = talloc_asprintf(req, + "ldap://%s/%s", + lp_dnsdomain(lp_ctx), + ldb_dn_get_linearized(msg->dn)); + ret = ldb_module_send_referral(req, referral); + return ldb_module_done(req, NULL, NULL, ret); + } + if (ret != LDB_SUCCESS) { talloc_free(ac); return ret; |