root/source4/libnet/libnet_vampire.c

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

DEFINITIONS

This source file includes following definitions.
  1. vampire_prepare_db
  2. vampire_check_options
  3. vampire_apply_schema
  4. vampire_schema_chunk
  5. vampire_store_chunk
  6. libnet_Vampire

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

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