~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/torture/libnet/libnet_BecomeDC.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
   Unix SMB/CIFS implementation.
 
3
 
 
4
   libnet_BecomeDC() tests
 
5
 
 
6
   Copyright (C) Stefan Metzmacher <metze@samba.org> 2006
 
7
   
 
8
   This program is free software; you can redistribute it and/or modify
 
9
   it under the terms of the GNU General Public License as published by
 
10
   the Free Software Foundation; either version 3 of the License, or
 
11
   (at your option) any later version.
 
12
   
 
13
   This program is distributed in the hope that it will be useful,
 
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
   GNU General Public License for more details.
 
17
   
 
18
   You should have received a copy of the GNU General Public License
 
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
20
*/
 
21
 
 
22
#include "includes.h"
 
23
#include "lib/cmdline/popt_common.h"
 
24
#include "torture/torture.h"
 
25
#include "torture/rpc/rpc.h"
 
26
#include "libnet/libnet.h"
 
27
#include "lib/events/events.h"
 
28
#include "dsdb/samdb/samdb.h"
 
29
#include "../lib/util/dlinklist.h"
 
30
#include "lib/ldb/include/ldb.h"
 
31
#include "lib/ldb/include/ldb_errors.h"
 
32
#include "librpc/ndr/libndr.h"
 
33
#include "librpc/gen_ndr/ndr_drsuapi.h"
 
34
#include "librpc/gen_ndr/ndr_drsblobs.h"
 
35
#include "librpc/gen_ndr/ndr_misc.h"
 
36
#include "system/time.h"
 
37
#include "lib/ldb_wrap.h"
 
38
#include "auth/auth.h"
 
39
#include "param/param.h"
 
40
#include "torture/util.h"
 
41
#include "param/provision.h"
 
42
 
 
43
struct test_become_dc_state {
 
44
        struct libnet_context *ctx;
 
45
        struct torture_context *tctx;
 
46
        const char *netbios_name;
 
47
        struct test_join *tj;
 
48
        struct cli_credentials *machine_account;
 
49
        struct dsdb_schema *self_made_schema;
 
50
        const struct dsdb_schema *schema;
 
51
 
 
52
        struct ldb_context *ldb;
 
53
 
 
54
        struct {
 
55
                uint32_t object_count;
 
56
                struct drsuapi_DsReplicaObjectListItemEx *first_object;
 
57
                struct drsuapi_DsReplicaObjectListItemEx *last_object;
 
58
        } schema_part;
 
59
 
 
60
        const char *targetdir;
 
61
 
 
62
        struct loadparm_context *lp_ctx;
 
63
};
 
64
 
 
65
static NTSTATUS test_become_dc_prepare_db(void *private_data,
 
66
                                              const struct libnet_BecomeDC_PrepareDB *p)
 
67
{
 
68
        struct test_become_dc_state *s = talloc_get_type(private_data, struct test_become_dc_state);
 
69
        struct provision_settings settings;
 
70
        struct provision_result result;
 
71
        NTSTATUS status;
 
72
 
 
73
        settings.site_name = p->dest_dsa->site_name;
 
74
        settings.root_dn_str = p->forest->root_dn_str;
 
75
        settings.domain_dn_str = p->domain->dn_str;
 
76
        settings.config_dn_str = p->forest->config_dn_str;
 
77
        settings.schema_dn_str = p->forest->schema_dn_str;
 
78
        settings.server_dn_str = torture_join_server_dn_str(s->tj);
 
79
        settings.invocation_id = &p->dest_dsa->invocation_id;
 
80
        settings.netbios_name = p->dest_dsa->netbios_name;
 
81
        settings.host_ip = NULL;
 
82
        settings.realm = torture_join_dom_dns_name(s->tj);
 
83
        settings.domain = torture_join_dom_netbios_name(s->tj);
 
84
        settings.ntds_dn_str = p->dest_dsa->ntds_dn_str;
 
85
        settings.machine_password = cli_credentials_get_password(s->machine_account);
 
86
        settings.targetdir = s->targetdir;
 
87
 
 
88
        status = provision_bare(s, s->lp_ctx, &settings, &result);
 
89
        
 
90
        s->ldb = result.samdb;
 
91
        s->lp_ctx = result.lp_ctx;
 
92
        return NT_STATUS_OK;
 
93
 
 
94
 
 
95
}
 
96
 
 
97
static NTSTATUS test_become_dc_check_options(void *private_data,
 
98
                                             const struct libnet_BecomeDC_CheckOptions *o)
 
99
{
 
100
        struct test_become_dc_state *s = talloc_get_type(private_data, struct test_become_dc_state);
 
101
 
 
102
        DEBUG(0,("Become DC [%s] of Domain[%s]/[%s]\n",
 
103
                s->netbios_name,
 
104
                o->domain->netbios_name, o->domain->dns_name));
 
105
 
 
106
        DEBUG(0,("Promotion Partner is Server[%s] from Site[%s]\n",
 
107
                o->source_dsa->dns_name, o->source_dsa->site_name));
 
108
 
 
109
        DEBUG(0,("Options:crossRef behavior_version[%u]\n"
 
110
                       "\tschema object_version[%u]\n"
 
111
                       "\tdomain behavior_version[%u]\n"
 
112
                       "\tdomain w2k3_update_revision[%u]\n", 
 
113
                o->forest->crossref_behavior_version,
 
114
                o->forest->schema_object_version,
 
115
                o->domain->behavior_version,
 
116
                o->domain->w2k3_update_revision));
 
117
 
 
118
        return NT_STATUS_OK;
 
119
}
 
120
 
 
121
static NTSTATUS test_apply_schema(struct test_become_dc_state *s,
 
122
                                  const struct libnet_BecomeDC_StoreChunk *c)
 
123
{
 
124
        WERROR status;
 
125
        const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr;
 
126
        uint32_t object_count;
 
127
        struct drsuapi_DsReplicaObjectListItemEx *first_object;
 
128
        struct drsuapi_DsReplicaObjectListItemEx *cur;
 
129
        uint32_t linked_attributes_count;
 
130
        struct drsuapi_DsReplicaLinkedAttribute *linked_attributes;
 
131
        const struct drsuapi_DsReplicaCursor2CtrEx *uptodateness_vector;
 
132
        struct dsdb_extended_replicated_objects *objs;
 
133
        struct repsFromTo1 *s_dsa;
 
134
        char *tmp_dns_name;
 
135
        struct ldb_message *msg;
 
136
        struct ldb_val prefixMap_val;
 
137
        struct ldb_message_element *prefixMap_el;
 
138
        struct ldb_val schemaInfo_val;
 
139
        char *sam_ldb_path;
 
140
        uint32_t i;
 
141
        int ret;
 
142
        bool ok;
 
143
 
 
144
        DEBUG(0,("Analyze and apply schema objects\n"));
 
145
 
 
146
        s_dsa                   = talloc_zero(s, struct repsFromTo1);
 
147
        NT_STATUS_HAVE_NO_MEMORY(s_dsa);
 
148
        s_dsa->other_info       = talloc(s_dsa, struct repsFromTo1OtherInfo);
 
149
        NT_STATUS_HAVE_NO_MEMORY(s_dsa->other_info);
 
150
 
 
151
        switch (c->ctr_level) {
 
152
        case 1:
 
153
                mapping_ctr                     = &c->ctr1->mapping_ctr;
 
154
                object_count                    = s->schema_part.object_count;
 
155
                first_object                    = s->schema_part.first_object;
 
156
                linked_attributes_count         = 0;
 
157
                linked_attributes               = NULL;
 
158
                s_dsa->highwatermark            = c->ctr1->new_highwatermark;
 
159
                s_dsa->source_dsa_obj_guid      = c->ctr1->source_dsa_guid;
 
160
                s_dsa->source_dsa_invocation_id = c->ctr1->source_dsa_invocation_id;
 
161
                uptodateness_vector             = NULL; /* TODO: map it */
 
162
                break;
 
163
        case 6:
 
164
                mapping_ctr                     = &c->ctr6->mapping_ctr;
 
165
                object_count                    = s->schema_part.object_count;
 
166
                first_object                    = s->schema_part.first_object;
 
167
                linked_attributes_count         = 0; /* TODO: ! */
 
168
                linked_attributes               = NULL; /* TODO: ! */;
 
169
                s_dsa->highwatermark            = c->ctr6->new_highwatermark;
 
170
                s_dsa->source_dsa_obj_guid      = c->ctr6->source_dsa_guid;
 
171
                s_dsa->source_dsa_invocation_id = c->ctr6->source_dsa_invocation_id;
 
172
                uptodateness_vector             = c->ctr6->uptodateness_vector;
 
173
                break;
 
174
        default:
 
175
                return NT_STATUS_INVALID_PARAMETER;
 
176
        }
 
177
 
 
178
        s_dsa->replica_flags            = DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE
 
179
                                        | DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
 
180
                                        | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS;
 
181
        memset(s_dsa->schedule, 0x11, sizeof(s_dsa->schedule));
 
182
 
 
183
        tmp_dns_name    = GUID_string(s_dsa->other_info, &s_dsa->source_dsa_obj_guid);
 
184
        NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name);
 
185
        tmp_dns_name    = talloc_asprintf_append_buffer(tmp_dns_name, "._msdcs.%s", c->forest->dns_name);
 
186
        NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name);
 
187
        s_dsa->other_info->dns_name = tmp_dns_name;
 
188
 
 
189
        for (cur = first_object; cur; cur = cur->next_object) {
 
190
                bool is_attr = false;
 
191
                bool is_class = false;
 
192
 
 
193
                for (i=0; i < cur->object.attribute_ctr.num_attributes; i++) {
 
194
                        struct drsuapi_DsReplicaAttribute *a;
 
195
                        uint32_t j;
 
196
                        const char *oid = NULL;
 
197
 
 
198
                        a = &cur->object.attribute_ctr.attributes[i];
 
199
                        status = dsdb_map_int2oid(s->self_made_schema, a->attid, s, &oid);
 
200
                        if (!W_ERROR_IS_OK(status)) {
 
201
                                return werror_to_ntstatus(status);
 
202
                        }
 
203
 
 
204
                        switch (a->attid) {
 
205
                        case DRSUAPI_ATTRIBUTE_objectClass:
 
206
                                for (j=0; j < a->value_ctr.num_values; j++) {
 
207
                                        uint32_t val = 0xFFFFFFFF;
 
208
 
 
209
                                        if (a->value_ctr.values[i].blob
 
210
                                            && a->value_ctr.values[i].blob->length == 4) {
 
211
                                                val = IVAL(a->value_ctr.values[i].blob->data,0);
 
212
                                        }
 
213
 
 
214
                                        if (val == DRSUAPI_OBJECTCLASS_attributeSchema) {
 
215
                                                is_attr = true;
 
216
                                        }
 
217
                                        if (val == DRSUAPI_OBJECTCLASS_classSchema) {
 
218
                                                is_class = true;
 
219
                                        }
 
220
                                }
 
221
 
 
222
                                break;
 
223
                        default:
 
224
                                break;
 
225
                        }
 
226
                }
 
227
 
 
228
                if (is_attr) {
 
229
                        struct dsdb_attribute *sa;
 
230
 
 
231
                        sa = talloc_zero(s->self_made_schema, struct dsdb_attribute);
 
232
                        NT_STATUS_HAVE_NO_MEMORY(sa);
 
233
 
 
234
                        status = dsdb_attribute_from_drsuapi(s->self_made_schema, &cur->object, s, sa);
 
235
                        if (!W_ERROR_IS_OK(status)) {
 
236
                                return werror_to_ntstatus(status);
 
237
                        }
 
238
 
 
239
                        DLIST_ADD_END(s->self_made_schema->attributes, sa, struct dsdb_attribute *);
 
240
                }
 
241
 
 
242
                if (is_class) {
 
243
                        struct dsdb_class *sc;
 
244
 
 
245
                        sc = talloc_zero(s->self_made_schema, struct dsdb_class);
 
246
                        NT_STATUS_HAVE_NO_MEMORY(sc);
 
247
 
 
248
                        status = dsdb_class_from_drsuapi(s->self_made_schema, &cur->object, s, sc);
 
249
                        if (!W_ERROR_IS_OK(status)) {
 
250
                                return werror_to_ntstatus(status);
 
251
                        }
 
252
 
 
253
                        DLIST_ADD_END(s->self_made_schema->classes, sc, struct dsdb_class *);
 
254
                }
 
255
        }
 
256
 
 
257
        /* attach the schema to the ldb */
 
258
        ret = dsdb_set_schema(s->ldb, s->self_made_schema);
 
259
        if (ret != LDB_SUCCESS) {
 
260
                return NT_STATUS_FOOBAR;
 
261
        }
 
262
        /* we don't want to access the self made schema anymore */
 
263
        s->self_made_schema = NULL;
 
264
        s->schema = dsdb_get_schema(s->ldb);
 
265
 
 
266
        status = dsdb_extended_replicated_objects_commit(s->ldb,
 
267
                                                         c->partition->nc.dn,
 
268
                                                         mapping_ctr,
 
269
                                                         object_count,
 
270
                                                         first_object,
 
271
                                                         linked_attributes_count,
 
272
                                                         linked_attributes,
 
273
                                                         s_dsa,
 
274
                                                         uptodateness_vector,
 
275
                                                         c->gensec_skey,
 
276
                                                         s, &objs);
 
277
        if (!W_ERROR_IS_OK(status)) {
 
278
                DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status)));
 
279
                return werror_to_ntstatus(status);
 
280
        }
 
281
 
 
282
        if (lp_parm_bool(s->tctx->lp_ctx, NULL, "become dc", "dump objects", false)) {
 
283
                for (i=0; i < objs->num_objects; i++) {
 
284
                        struct ldb_ldif ldif;
 
285
                        fprintf(stdout, "#\n");
 
286
                        ldif.changetype = LDB_CHANGETYPE_NONE;
 
287
                        ldif.msg = objs->objects[i].msg;
 
288
                        ldb_ldif_write_file(s->ldb, stdout, &ldif);
 
289
                        NDR_PRINT_DEBUG(replPropertyMetaDataBlob, objs->objects[i].meta_data);
 
290
                }
 
291
        }
 
292
 
 
293
        msg = ldb_msg_new(objs);
 
294
        NT_STATUS_HAVE_NO_MEMORY(msg);
 
295
        msg->dn = objs->partition_dn;
 
296
 
 
297
        status = dsdb_get_oid_mappings_ldb(s->schema, msg, &prefixMap_val, &schemaInfo_val);
 
298
        if (!W_ERROR_IS_OK(status)) {
 
299
                DEBUG(0,("Failed dsdb_get_oid_mappings_ldb(%s)\n", win_errstr(status)));
 
300
                return werror_to_ntstatus(status);
 
301
        }
 
302
 
 
303
        /* we only add prefixMap here, because schemaInfo is a replicated attribute and already applied */
 
304
        ret = ldb_msg_add_value(msg, "prefixMap", &prefixMap_val, &prefixMap_el);
 
305
        if (ret != LDB_SUCCESS) {
 
306
                return NT_STATUS_FOOBAR;
 
307
        }
 
308
        prefixMap_el->flags = LDB_FLAG_MOD_REPLACE;
 
309
 
 
310
        ret = ldb_modify(s->ldb, msg);
 
311
        if (ret != LDB_SUCCESS) {
 
312
                DEBUG(0,("Failed to add prefixMap and schemaInfo %s\n", ldb_strerror(ret)));
 
313
                return NT_STATUS_FOOBAR;
 
314
        }
 
315
 
 
316
        talloc_free(s_dsa);
 
317
        talloc_free(objs);
 
318
 
 
319
        /* reopen the ldb */
 
320
        talloc_free(s->ldb); /* this also free's the s->schema, because dsdb_set_schema() steals it */
 
321
        s->schema = NULL;
 
322
 
 
323
        sam_ldb_path = talloc_asprintf(s, "%s/%s", s->targetdir, "private/sam.ldb");
 
324
        DEBUG(0,("Reopen the SAM LDB with system credentials and a already stored schema: %s\n", sam_ldb_path));
 
325
        s->ldb = ldb_wrap_connect(s, s->tctx->ev, s->tctx->lp_ctx, sam_ldb_path,
 
326
                                  system_session(s, s->tctx->lp_ctx),
 
327
                                  NULL, 0, NULL);
 
328
        if (!s->ldb) {
 
329
                DEBUG(0,("Failed to open '%s'\n",
 
330
                        sam_ldb_path));
 
331
                return NT_STATUS_INTERNAL_DB_ERROR;
 
332
        }
 
333
 
 
334
        ok = samdb_set_ntds_invocation_id(s->ldb, &c->dest_dsa->invocation_id);
 
335
        if (!ok) {
 
336
                DEBUG(0,("Failed to set cached ntds invocationId\n"));
 
337
                return NT_STATUS_FOOBAR;
 
338
        }
 
339
        ok = samdb_set_ntds_objectGUID(s->ldb, &c->dest_dsa->ntds_guid);
 
340
        if (!ok) {
 
341
                DEBUG(0,("Failed to set cached ntds objectGUID\n"));
 
342
                return NT_STATUS_FOOBAR;
 
343
        }
 
344
 
 
345
        s->schema = dsdb_get_schema(s->ldb);
 
346
        if (!s->schema) {
 
347
                DEBUG(0,("Failed to get loaded dsdb_schema\n"));
 
348
                return NT_STATUS_FOOBAR;
 
349
        }
 
350
 
 
351
        return NT_STATUS_OK;
 
352
}
 
353
 
 
354
static NTSTATUS test_become_dc_schema_chunk(void *private_data,
 
355
                                            const struct libnet_BecomeDC_StoreChunk *c)
 
356
{
 
357
        struct test_become_dc_state *s = talloc_get_type(private_data, struct test_become_dc_state);
 
358
        WERROR status;
 
359
        const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr;
 
360
        uint32_t nc_object_count;
 
361
        uint32_t object_count;
 
362
        struct drsuapi_DsReplicaObjectListItemEx *first_object;
 
363
        struct drsuapi_DsReplicaObjectListItemEx *cur;
 
364
        uint32_t nc_linked_attributes_count;
 
365
        uint32_t linked_attributes_count;
 
366
 
 
367
        switch (c->ctr_level) {
 
368
        case 1:
 
369
                mapping_ctr                     = &c->ctr1->mapping_ctr;
 
370
                nc_object_count                 = c->ctr1->extended_ret; /* maybe w2k send this unexpected? */
 
371
                object_count                    = c->ctr1->object_count;
 
372
                first_object                    = c->ctr1->first_object;
 
373
                nc_linked_attributes_count      = 0;
 
374
                linked_attributes_count         = 0;
 
375
                break;
 
376
        case 6:
 
377
                mapping_ctr                     = &c->ctr6->mapping_ctr;
 
378
                nc_object_count                 = c->ctr6->nc_object_count;
 
379
                object_count                    = c->ctr6->object_count;
 
380
                first_object                    = c->ctr6->first_object;
 
381
                nc_linked_attributes_count      = c->ctr6->nc_linked_attributes_count;
 
382
                linked_attributes_count         = c->ctr6->linked_attributes_count;
 
383
                break;
 
384
        default:
 
385
                return NT_STATUS_INVALID_PARAMETER;
 
386
        }
 
387
 
 
388
        if (nc_object_count) {
 
389
                DEBUG(0,("Schema-DN[%s] objects[%u/%u] linked_values[%u/%u]\n",
 
390
                        c->partition->nc.dn, object_count, nc_object_count,
 
391
                        linked_attributes_count, nc_linked_attributes_count));
 
392
        } else {
 
393
                DEBUG(0,("Schema-DN[%s] objects[%u] linked_values[%u\n",
 
394
                c->partition->nc.dn, object_count, linked_attributes_count));
 
395
        }
 
396
 
 
397
        if (!s->schema) {
 
398
                s->self_made_schema = dsdb_new_schema(s, lp_iconv_convenience(s->lp_ctx));
 
399
 
 
400
                NT_STATUS_HAVE_NO_MEMORY(s->self_made_schema);
 
401
 
 
402
                status = dsdb_load_oid_mappings_drsuapi(s->self_made_schema, mapping_ctr);
 
403
                if (!W_ERROR_IS_OK(status)) {
 
404
                        return werror_to_ntstatus(status);
 
405
                }
 
406
 
 
407
                s->schema = s->self_made_schema;
 
408
        } else {
 
409
                status = dsdb_verify_oid_mappings_drsuapi(s->schema, mapping_ctr);
 
410
                if (!W_ERROR_IS_OK(status)) {
 
411
                        return werror_to_ntstatus(status);
 
412
                }
 
413
        }
 
414
 
 
415
        if (!s->schema_part.first_object) {
 
416
                s->schema_part.object_count = object_count;
 
417
                s->schema_part.first_object = talloc_steal(s, first_object);
 
418
        } else {
 
419
                s->schema_part.object_count             += object_count;
 
420
                s->schema_part.last_object->next_object = talloc_steal(s->schema_part.last_object,
 
421
                                                                       first_object);
 
422
        }
 
423
        for (cur = first_object; cur->next_object; cur = cur->next_object) {}
 
424
        s->schema_part.last_object = cur;
 
425
 
 
426
        if (!c->partition->more_data) {
 
427
                return test_apply_schema(s, c);
 
428
        }
 
429
 
 
430
        return NT_STATUS_OK;
 
431
}
 
432
 
 
433
static NTSTATUS test_become_dc_store_chunk(void *private_data,
 
434
                                           const struct libnet_BecomeDC_StoreChunk *c)
 
435
{
 
436
        struct test_become_dc_state *s = talloc_get_type(private_data, struct test_become_dc_state);
 
437
        WERROR status;
 
438
        const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr;
 
439
        uint32_t nc_object_count;
 
440
        uint32_t object_count;
 
441
        struct drsuapi_DsReplicaObjectListItemEx *first_object;
 
442
        uint32_t nc_linked_attributes_count;
 
443
        uint32_t linked_attributes_count;
 
444
        struct drsuapi_DsReplicaLinkedAttribute *linked_attributes;
 
445
        const struct drsuapi_DsReplicaCursor2CtrEx *uptodateness_vector;
 
446
        struct dsdb_extended_replicated_objects *objs;
 
447
        struct repsFromTo1 *s_dsa;
 
448
        char *tmp_dns_name;
 
449
        uint32_t i;
 
450
 
 
451
        s_dsa                   = talloc_zero(s, struct repsFromTo1);
 
452
        NT_STATUS_HAVE_NO_MEMORY(s_dsa);
 
453
        s_dsa->other_info       = talloc(s_dsa, struct repsFromTo1OtherInfo);
 
454
        NT_STATUS_HAVE_NO_MEMORY(s_dsa->other_info);
 
455
 
 
456
        switch (c->ctr_level) {
 
457
        case 1:
 
458
                mapping_ctr                     = &c->ctr1->mapping_ctr;
 
459
                nc_object_count                 = c->ctr1->extended_ret; /* maybe w2k send this unexpected? */
 
460
                object_count                    = c->ctr1->object_count;
 
461
                first_object                    = c->ctr1->first_object;
 
462
                nc_linked_attributes_count      = 0;
 
463
                linked_attributes_count         = 0;
 
464
                linked_attributes               = NULL;
 
465
                s_dsa->highwatermark            = c->ctr1->new_highwatermark;
 
466
                s_dsa->source_dsa_obj_guid      = c->ctr1->source_dsa_guid;
 
467
                s_dsa->source_dsa_invocation_id = c->ctr1->source_dsa_invocation_id;
 
468
                uptodateness_vector             = NULL; /* TODO: map it */
 
469
                break;
 
470
        case 6:
 
471
                mapping_ctr                     = &c->ctr6->mapping_ctr;
 
472
                nc_object_count                 = c->ctr6->nc_object_count;
 
473
                object_count                    = c->ctr6->object_count;
 
474
                first_object                    = c->ctr6->first_object;
 
475
                nc_linked_attributes_count      = c->ctr6->nc_linked_attributes_count;
 
476
                linked_attributes_count         = c->ctr6->linked_attributes_count;
 
477
                linked_attributes               = c->ctr6->linked_attributes;
 
478
                s_dsa->highwatermark            = c->ctr6->new_highwatermark;
 
479
                s_dsa->source_dsa_obj_guid      = c->ctr6->source_dsa_guid;
 
480
                s_dsa->source_dsa_invocation_id = c->ctr6->source_dsa_invocation_id;
 
481
                uptodateness_vector             = c->ctr6->uptodateness_vector;
 
482
                break;
 
483
        default:
 
484
                return NT_STATUS_INVALID_PARAMETER;
 
485
        }
 
486
 
 
487
        s_dsa->replica_flags            = DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE
 
488
                                        | DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
 
489
                                        | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS;
 
490
        memset(s_dsa->schedule, 0x11, sizeof(s_dsa->schedule));
 
491
 
 
492
        tmp_dns_name    = GUID_string(s_dsa->other_info, &s_dsa->source_dsa_obj_guid);
 
493
        NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name);
 
494
        tmp_dns_name    = talloc_asprintf_append_buffer(tmp_dns_name, "._msdcs.%s", c->forest->dns_name);
 
495
        NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name);
 
496
        s_dsa->other_info->dns_name = tmp_dns_name;
 
497
 
 
498
        if (nc_object_count) {
 
499
                DEBUG(0,("Partition[%s] objects[%u/%u] linked_values[%u/%u]\n",
 
500
                        c->partition->nc.dn, object_count, nc_object_count,
 
501
                        linked_attributes_count, nc_linked_attributes_count));
 
502
        } else {
 
503
                DEBUG(0,("Partition[%s] objects[%u] linked_values[%u\n",
 
504
                c->partition->nc.dn, object_count, linked_attributes_count));
 
505
        }
 
506
 
 
507
        status = dsdb_extended_replicated_objects_commit(s->ldb,
 
508
                                                         c->partition->nc.dn,
 
509
                                                         mapping_ctr,
 
510
                                                         object_count,
 
511
                                                         first_object,
 
512
                                                         linked_attributes_count,
 
513
                                                         linked_attributes,
 
514
                                                         s_dsa,
 
515
                                                         uptodateness_vector,
 
516
                                                         c->gensec_skey,
 
517
                                                         s, &objs);
 
518
        if (!W_ERROR_IS_OK(status)) {
 
519
                DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status)));
 
520
                return werror_to_ntstatus(status);
 
521
        }
 
522
 
 
523
        if (lp_parm_bool(s->tctx->lp_ctx, NULL, "become dc", "dump objects", false)) {
 
524
                for (i=0; i < objs->num_objects; i++) {
 
525
                        struct ldb_ldif ldif;
 
526
                        fprintf(stdout, "#\n");
 
527
                        ldif.changetype = LDB_CHANGETYPE_NONE;
 
528
                        ldif.msg = objs->objects[i].msg;
 
529
                        ldb_ldif_write_file(s->ldb, stdout, &ldif);
 
530
                        NDR_PRINT_DEBUG(replPropertyMetaDataBlob, objs->objects[i].meta_data);
 
531
                }
 
532
        }
 
533
        talloc_free(s_dsa);
 
534
        talloc_free(objs);
 
535
 
 
536
        for (i=0; i < linked_attributes_count; i++) {
 
537
                const struct dsdb_attribute *sa;
 
538
 
 
539
                if (!linked_attributes[i].identifier) {
 
540
                        return NT_STATUS_FOOBAR;                
 
541
                }
 
542
 
 
543
                if (!linked_attributes[i].value.blob) {
 
544
                        return NT_STATUS_FOOBAR;                
 
545
                }
 
546
 
 
547
                sa = dsdb_attribute_by_attributeID_id(s->schema,
 
548
                                                      linked_attributes[i].attid);
 
549
                if (!sa) {
 
550
                        return NT_STATUS_FOOBAR;
 
551
                }
 
552
 
 
553
                if (lp_parm_bool(s->tctx->lp_ctx, NULL, "become dc", "dump objects", false)) {
 
554
                        DEBUG(0,("# %s\n", sa->lDAPDisplayName));
 
555
                        NDR_PRINT_DEBUG(drsuapi_DsReplicaLinkedAttribute, &linked_attributes[i]);
 
556
                        dump_data(0,
 
557
                                linked_attributes[i].value.blob->data,
 
558
                                linked_attributes[i].value.blob->length);
 
559
                }
 
560
        }
 
561
 
 
562
        return NT_STATUS_OK;
 
563
}
 
564
 
 
565
bool torture_net_become_dc(struct torture_context *torture)
 
566
{
 
567
        bool ret = true;
 
568
        NTSTATUS status;
 
569
        struct libnet_BecomeDC b;
 
570
        struct libnet_UnbecomeDC u;
 
571
        struct test_become_dc_state *s;
 
572
        struct ldb_message *msg;
 
573
        int ldb_ret;
 
574
        uint32_t i;
 
575
        char *sam_ldb_path;
 
576
 
 
577
        char *location = NULL;
 
578
        torture_assert_ntstatus_ok(torture, torture_temp_dir(torture, "libnet_BecomeDC", &location), 
 
579
                                   "torture_temp_dir should return NT_STATUS_OK" );
 
580
 
 
581
        s = talloc_zero(torture, struct test_become_dc_state);
 
582
        if (!s) return false;
 
583
 
 
584
        s->tctx = torture;
 
585
        s->lp_ctx = torture->lp_ctx;
 
586
 
 
587
        s->netbios_name = lp_parm_string(torture->lp_ctx, NULL, "become dc", "smbtorture dc");
 
588
        if (!s->netbios_name || !s->netbios_name[0]) {
 
589
                s->netbios_name = "smbtorturedc";
 
590
        }
 
591
 
 
592
        s->targetdir = location;
 
593
 
 
594
        /* Join domain as a member server. */
 
595
        s->tj = torture_join_domain(torture, s->netbios_name,
 
596
                                 ACB_WSTRUST,
 
597
                                 &s->machine_account);
 
598
        if (!s->tj) {
 
599
                DEBUG(0, ("%s failed to join domain as workstation\n",
 
600
                          s->netbios_name));
 
601
                return false;
 
602
        }
 
603
 
 
604
        s->ctx = libnet_context_init(torture->ev, torture->lp_ctx);
 
605
        s->ctx->cred = cmdline_credentials;
 
606
 
 
607
        s->ldb = ldb_init(s, torture->ev);
 
608
 
 
609
        ZERO_STRUCT(b);
 
610
        b.in.domain_dns_name            = torture_join_dom_dns_name(s->tj);
 
611
        b.in.domain_netbios_name        = torture_join_dom_netbios_name(s->tj);
 
612
        b.in.domain_sid                 = torture_join_sid(s->tj);
 
613
        b.in.source_dsa_address         = torture_setting_string(torture, "host", NULL);
 
614
        b.in.dest_dsa_netbios_name      = s->netbios_name;
 
615
 
 
616
        b.in.callbacks.private_data     = s;
 
617
        b.in.callbacks.check_options    = test_become_dc_check_options;
 
618
        b.in.callbacks.prepare_db = test_become_dc_prepare_db;
 
619
        b.in.callbacks.schema_chunk     = test_become_dc_schema_chunk;
 
620
        b.in.callbacks.config_chunk     = test_become_dc_store_chunk;
 
621
        b.in.callbacks.domain_chunk     = test_become_dc_store_chunk;
 
622
 
 
623
        status = libnet_BecomeDC(s->ctx, s, &b);
 
624
        if (!NT_STATUS_IS_OK(status)) {
 
625
                printf("libnet_BecomeDC() failed - %s\n", nt_errstr(status));
 
626
                ret = false;
 
627
                goto cleanup;
 
628
        }
 
629
 
 
630
        msg = ldb_msg_new(s);
 
631
        if (!msg) {
 
632
                printf("ldb_msg_new() failed\n");
 
633
                ret = false;
 
634
                goto cleanup;
 
635
        }
 
636
        msg->dn = ldb_dn_new(msg, s->ldb, "@ROOTDSE");
 
637
        if (!msg->dn) {
 
638
                printf("ldb_msg_new(@ROOTDSE) failed\n");
 
639
                ret = false;
 
640
                goto cleanup;
 
641
        }
 
642
 
 
643
        ldb_ret = ldb_msg_add_string(msg, "isSynchronized", "TRUE");
 
644
        if (ldb_ret != LDB_SUCCESS) {
 
645
                printf("ldb_msg_add_string(msg, isSynchronized, TRUE) failed: %d\n", ldb_ret);
 
646
                ret = false;
 
647
                goto cleanup;
 
648
        }
 
649
 
 
650
        for (i=0; i < msg->num_elements; i++) {
 
651
                msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
 
652
        }
 
653
 
 
654
        printf("mark ROOTDSE with isSynchronized=TRUE\n");
 
655
        ldb_ret = ldb_modify(s->ldb, msg);
 
656
        if (ldb_ret != LDB_SUCCESS) {
 
657
                printf("ldb_modify() failed: %d\n", ldb_ret);
 
658
                ret = false;
 
659
                goto cleanup;
 
660
        }
 
661
        
 
662
        /* reopen the ldb */
 
663
        talloc_free(s->ldb); /* this also free's the s->schema, because dsdb_set_schema() steals it */
 
664
        s->schema = NULL;
 
665
 
 
666
        sam_ldb_path = talloc_asprintf(s, "%s/%s", s->targetdir, "private/sam.ldb");
 
667
        DEBUG(0,("Reopen the SAM LDB with system credentials and all replicated data: %s\n", sam_ldb_path));
 
668
        s->ldb = ldb_wrap_connect(s, s->tctx->ev, s->lp_ctx, sam_ldb_path,
 
669
                                  system_session(s, s->lp_ctx),
 
670
                                  NULL, 0, NULL);
 
671
        if (!s->ldb) {
 
672
                DEBUG(0,("Failed to open '%s'\n",
 
673
                        sam_ldb_path));
 
674
                ret = false;
 
675
                goto cleanup;
 
676
        }
 
677
 
 
678
        s->schema = dsdb_get_schema(s->ldb);
 
679
        if (!s->schema) {
 
680
                DEBUG(0,("Failed to get loaded dsdb_schema\n"));
 
681
                ret = false;
 
682
                goto cleanup;
 
683
        }
 
684
 
 
685
        /* Make sure we get this from the command line */
 
686
        if (lp_parm_bool(torture->lp_ctx, NULL, "become dc", "do not unjoin", false)) {
 
687
                talloc_free(s);
 
688
                return ret;
 
689
        }
 
690
 
 
691
cleanup:
 
692
        ZERO_STRUCT(u);
 
693
        u.in.domain_dns_name            = torture_join_dom_dns_name(s->tj);
 
694
        u.in.domain_netbios_name        = torture_join_dom_netbios_name(s->tj);
 
695
        u.in.source_dsa_address         = torture_setting_string(torture, "host", NULL);
 
696
        u.in.dest_dsa_netbios_name      = s->netbios_name;
 
697
 
 
698
        status = libnet_UnbecomeDC(s->ctx, s, &u);
 
699
        if (!NT_STATUS_IS_OK(status)) {
 
700
                printf("libnet_UnbecomeDC() failed - %s\n", nt_errstr(status));
 
701
                ret = false;
 
702
        }
 
703
 
 
704
        /* Leave domain. */                          
 
705
        torture_leave_domain(torture, s->tj);
 
706
 
 
707
        talloc_free(s);
 
708
        return ret;
 
709
}