root/source4/torture/libnet/libnet_BecomeDC.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. test_become_dc_prepare_db
  2. test_become_dc_check_options
  3. test_apply_schema
  4. test_become_dc_schema_chunk
  5. test_become_dc_store_chunk
  6. torture_net_become_dc

   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,
     /* [<][>][^][v][top][bottom][index][help] */
  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,
     /* [<][>][^][v][top][bottom][index][help] */
  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,
     /* [<][>][^][v][top][bottom][index][help] */
 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,
     /* [<][>][^][v][top][bottom][index][help] */
 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,
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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 }

/* [<][>][^][v][top][bottom][index][help] */