s4/rodc: change the libnet_become_dc code to do RODC join
authorAnatoliy Atanasov <anatoliy.atanasov@postpath.com>
Wed, 17 Feb 2010 16:01:31 +0000 (18:01 +0200)
committerAnatoliy Atanasov <anatoliy.atanasov@postpath.com>
Wed, 17 Feb 2010 16:03:32 +0000 (18:03 +0200)
source4/libnet/libnet_become_dc.c
source4/libnet/libnet_become_dc.h
source4/libnet/libnet_vampire.c

index b7205dca594ff1a9218dc36c8dd192f95bb999eb..f3e4ec7ccdfde6dc58ca1a4298734711d5fd8e30 100644 (file)
@@ -729,6 +729,8 @@ struct libnet_BecomeDC_state {
        struct libnet_BecomeDC_PrepareDB _pp;
        struct libnet_BecomeDC_StoreChunk _sc;
        struct libnet_BecomeDC_Callbacks callbacks;
+
+       bool rodc_join;
 };
 
 static int32_t get_dc_function_level(struct loadparm_context *lp_ctx)
@@ -1762,7 +1764,7 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
        if (composite_nomem(identifier->dn, c)) return;
 
        /* allocate attribute array */
-       num_attrs       = 11;
+       num_attrs       = 12;
        attrs           = talloc_array(r, struct drsuapi_DsReplicaAttribute, num_attrs);
        if (composite_nomem(attrs, c)) return;
 
@@ -1846,7 +1848,7 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
                i++;
        }
 
-       /* objectClass: nTDSDSA */
+       /* objectClass: nTDSDSA or nTDSDSARO*/
        {
                struct drsuapi_DsAttributeValue *vs;
                DATA_BLOB *vd;
@@ -1872,7 +1874,7 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
                i++;
        }
 
-       /* objectCategory: CN=NTDS-DSA,CN=Schema,... */
+       /* objectCategory: CN=NTDS-DSA,CN=Schema,... or CN=NTDS-DSA-RO,CN=Schema,... */
        {
                struct drsuapi_DsAttributeValue *vs;
                DATA_BLOB *vd;
@@ -1886,8 +1888,14 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
 
                v[0].guid               = GUID_zero();
                v[0].sid                = s->zero_sid;
-               v[0].dn                 = talloc_asprintf(vd, "CN=NTDS-DSA,%s",
+
+               if (s->rodc_join) {
+                   v[0].dn             = talloc_asprintf(vd, "CN=NTDS-DSA-RO,%s",
                                                          s->forest.schema_dn_str);
+               } else {
+                   v[0].dn             = talloc_asprintf(vd, "CN=NTDS-DSA,%s",
+                                                         s->forest.schema_dn_str);
+               }
                if (composite_nomem(v[0].dn, c)) return;
 
                ndr_err = ndr_push_struct_blob(&vd[0], vd, iconv_convenience, &v[0], 
@@ -2147,7 +2155,11 @@ 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, SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE);
+               if (s->rodc_join) {
+                   SIVAL(vd[0].data, 0, SYSTEM_FLAG_CONFIG_ALLOW_RENAME);
+               } else {
+                   SIVAL(vd[0].data, 0, SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE);
+               }
 
                vs[0].blob              = &vd[0];
 
@@ -2190,6 +2202,31 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
                i++;
        }
 
+       /* options:... */
+       if (s->rodc_join) {
+               struct drsuapi_DsAttributeValue *vs;
+               DATA_BLOB *vd;
+
+               vs = talloc_array(attrs, struct drsuapi_DsAttributeValue, 1);
+               if (composite_nomem(vs, c)) return;
+
+               vd = talloc_array(vs, DATA_BLOB, 1);
+               if (composite_nomem(vd, c)) return;
+
+               vd[0] = data_blob_talloc(vd, NULL, 4);
+               if (composite_nomem(vd[0].data, c)) return;
+
+               SIVAL(vd[0].data, 0, DS_NTDSDSA_OPT_DISABLE_OUTBOUND_REPL);
+
+               vs[0].blob              = &vd[0];
+
+               attrs[i].attid                  = DRSUAPI_ATTRIBUTE_options;
+               attrs[i].value_ctr.num_values   = 1;
+               attrs[i].value_ctr.values       = vs;
+
+               i++;
+       }
+
        /* truncate the attribute list to the attribute count we have filled in */
        num_attrs = i;
 
@@ -2582,6 +2619,9 @@ static void becomeDC_drsuapi3_pull_schema_send(struct libnet_BecomeDC_state *s)
                                        | DRSUAPI_DRS_FULL_SYNC_IN_PROGRESS
                                        | DRSUAPI_DRS_NEVER_SYNCED
                                        | DRSUAPI_DRS_USE_COMPRESSION;
+       if (s->rodc_join) {
+           s->schema_part.replica_flags &= ~DRSUAPI_DRS_WRIT_REP;
+       }
 
        s->schema_part.store_chunk      = s->callbacks.schema_chunk;
 
@@ -2646,6 +2686,9 @@ static void becomeDC_drsuapi3_pull_config_send(struct libnet_BecomeDC_state *s)
                                        | DRSUAPI_DRS_FULL_SYNC_IN_PROGRESS
                                        | DRSUAPI_DRS_NEVER_SYNCED
                                        | DRSUAPI_DRS_USE_COMPRESSION;
+       if (s->rodc_join) {
+           s->schema_part.replica_flags &= ~DRSUAPI_DRS_WRIT_REP;
+       }
 
        s->config_part.store_chunk      = s->callbacks.config_chunk;
 
@@ -2708,6 +2751,9 @@ static void becomeDC_drsuapi3_pull_domain_send(struct libnet_BecomeDC_state *s)
                                        | DRSUAPI_DRS_FULL_SYNC_IN_PROGRESS
                                        | DRSUAPI_DRS_NEVER_SYNCED
                                        | DRSUAPI_DRS_USE_COMPRESSION;
+       if (s->rodc_join) {
+           s->schema_part.replica_flags &= ~DRSUAPI_DRS_WRIT_REP;
+       }
 
        s->domain_part.store_chunk      = s->callbacks.domain_chunk;
 
@@ -3017,6 +3063,9 @@ struct composite_context *libnet_BecomeDC_send(struct libnet_context *ctx, TALLO
        /* Callback function pointers */
        s->callbacks = r->in.callbacks;
 
+        /* RODC join*/
+        s->rodc_join = r->in.rodc_join;
+
        becomeDC_send_cldap(s);
        return c;
 }
index 58fc4dc15d489b91ace9a5dde046867e4276fcd8..604813f6bc576d912db594744baca7b4ffa1a2cf 100644 (file)
@@ -136,7 +136,9 @@ struct libnet_BecomeDC {
                const char *dest_dsa_netbios_name;
 
                struct libnet_BecomeDC_Callbacks callbacks;
-       } in;
+
+                bool rodc_join;
+        } in;
 
        struct {
                const char *error_string;
index e38488771e7f788946b6ae9954b8b42d8c0a7c50..9554a63b3cc4b5b23a76233aa88904f1cfd0e177 100644 (file)
@@ -686,6 +686,8 @@ NTSTATUS libnet_Vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx,
        b.in.callbacks.config_chunk     = vampire_store_chunk;
        b.in.callbacks.domain_chunk     = vampire_store_chunk;
 
+       b.in.rodc_join = lp_parm_bool(s->lp_ctx, NULL, "repl", "RODC", false);
+
        status = libnet_BecomeDC(ctx, s, &b);
        if (!NT_STATUS_IS_OK(status)) {
                printf("libnet_BecomeDC() failed - %s\n", nt_errstr(status));