summaryrefslogtreecommitdiff
path: root/source4/libnet/libnet_become_dc.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libnet/libnet_become_dc.c')
-rw-r--r--source4/libnet/libnet_become_dc.c66
1 files changed, 56 insertions, 10 deletions
diff --git a/source4/libnet/libnet_become_dc.c b/source4/libnet/libnet_become_dc.c
index 38357efffe..3fb308dcd7 100644
--- a/source4/libnet/libnet_become_dc.c
+++ b/source4/libnet/libnet_become_dc.c
@@ -731,6 +731,20 @@ struct libnet_BecomeDC_state {
struct libnet_BecomeDC_Callbacks callbacks;
};
+static int32_t get_dc_function_level(struct loadparm_context *lp_ctx)
+{
+ /* per default we are (Windows) 2008 compatible */
+ return lp_parm_int(lp_ctx, NULL, "ads", "dc function level",
+ DS_DC_FUNCTION_2008);
+}
+
+static int32_t get_min_function_level(struct loadparm_context *lp_ctx)
+{
+ /* per default it is (Windows) 2003 Native compatible */
+ return lp_parm_int(lp_ctx, NULL, "ads", "min function level",
+ DS_DOMAIN_FUNCTION_2003);
+}
+
static void becomeDC_recv_cldap(struct tevent_req *req);
static void becomeDC_send_cldap(struct libnet_BecomeDC_state *s)
@@ -876,6 +890,22 @@ static NTSTATUS becomeDC_ldap1_crossref_behavior_version(struct libnet_BecomeDC_
}
s->forest.crossref_behavior_version = ldb_msg_find_attr_as_uint(r->msgs[0], "msDs-Behavior-Version", 0);
+ if (s->forest.crossref_behavior_version <
+ get_min_function_level(s->libnet->lp_ctx)) {
+ talloc_free(r);
+ DEBUG(0,("The servers function level %u is below 'ads:min function level' of %u\n",
+ s->forest.crossref_behavior_version,
+ get_min_function_level(s->libnet->lp_ctx)));
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+ if (s->forest.crossref_behavior_version >
+ get_dc_function_level(s->libnet->lp_ctx)) {
+ talloc_free(r);
+ DEBUG(0,("The servers function level %u is above 'ads:dc function level' of %u\n",
+ s->forest.crossref_behavior_version,
+ get_dc_function_level(s->libnet->lp_ctx)));
+ return NT_STATUS_NOT_SUPPORTED;
+ }
talloc_free(r);
return NT_STATUS_OK;
@@ -905,6 +935,22 @@ static NTSTATUS becomeDC_ldap1_domain_behavior_version(struct libnet_BecomeDC_st
}
s->domain.behavior_version = ldb_msg_find_attr_as_uint(r->msgs[0], "msDs-Behavior-Version", 0);
+ if (s->domain.behavior_version <
+ get_min_function_level(s->libnet->lp_ctx)) {
+ talloc_free(r);
+ DEBUG(0,("The servers function level %u is below 'ads:min function level' of %u\n",
+ s->forest.crossref_behavior_version,
+ get_min_function_level(s->libnet->lp_ctx)));
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+ if (s->domain.behavior_version >
+ get_dc_function_level(s->libnet->lp_ctx)) {
+ talloc_free(r);
+ DEBUG(0,("The servers function level %u is above 'ads:dc function level' of %u\n",
+ s->forest.crossref_behavior_version,
+ get_dc_function_level(s->libnet->lp_ctx)));
+ return NT_STATUS_NOT_SUPPORTED;
+ }
talloc_free(r);
return NT_STATUS_OK;
@@ -1282,8 +1328,8 @@ static NTSTATUS becomeDC_ldap1_server_object_1(struct libnet_BecomeDC_state *s)
NT_STATUS_HAVE_NO_MEMORY(computer_dn);
/*
- * if the server object belongs to another DC in another domain in the forest,
- * we should not touch this object!
+ * if the server object belongs to another DC in another domain
+ * in the forest, we should not touch this object!
*/
if (ldb_dn_compare(computer_dn, server_reference_dn) != 0) {
talloc_free(r);
@@ -1519,9 +1565,10 @@ static void becomeDC_drsuapi_connect_send(struct libnet_BecomeDC_state *s,
* Note: Replication only works with Windows 2000 when 'krb5' is
* passed as auth_type here. If NTLMSSP is used, Windows
* 2000 returns garbage in the DsGetNCChanges() response
- * if encrypted password attributes would be in the response.
- * That means the replication of the schema and configuration
- * partition works fine, but it fails for the domain partition.
+ * if encrypted password attributes would be in the
+ * response. That means the replication of the schema and
+ * configuration partition works fine, but it fails for
+ * the domain partition.
*/
if (lp_parm_bool(s->libnet->lp_ctx, NULL, "become_dc",
"force krb5", true))
@@ -1589,7 +1636,7 @@ static void becomeDC_drsuapi_bind_send(struct libnet_BecomeDC_state *s,
bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION;
bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE;
bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2;
- if (s->domain.behavior_version == 2) {
+ if (s->domain.behavior_version >= DS_DOMAIN_FUNCTION_2003) {
/* TODO: find out how this is really triggered! */
bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION;
}
@@ -1716,8 +1763,8 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
s->dest_dsa.invocation_id = GUID_random();
/*
- * if the schema version indicates w2k3, then
- * also send some w2k3 specific attributes
+ * if the schema version indicates w2k3, then also send some w2k3
+ * specific attributes.
*/
if (s->forest.schema_object_version >= 30) {
w2k3 = true;
@@ -2101,8 +2148,7 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
vd[0] = data_blob_talloc(vd, NULL, 4);
if (composite_nomem(vd[0].data, c)) return;
- SIVAL(vd[0].data, 0,
- lp_parm_int(s->libnet->lp_ctx, NULL, "ads", "functional level", DS_DC_FUNCTION_2008));
+ SIVAL(vd[0].data, 0, get_dc_function_level(s->libnet->lp_ctx));
vs[0].blob = &vd[0];