Changeset 745 for trunk/server/source4/libnet/libnet_vampire.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source4/libnet/libnet_vampire.c
r414 r745 28 28 #include "dsdb/samdb/samdb.h" 29 29 #include "../lib/util/dlinklist.h" 30 #include "lib/ldb/include/ldb.h"31 #include "lib/ldb/include/ldb_errors.h"30 #include <ldb.h> 31 #include <ldb_errors.h> 32 32 #include "librpc/ndr/libndr.h" 33 33 #include "librpc/gen_ndr/ndr_drsuapi.h" … … 35 35 #include "librpc/gen_ndr/ndr_misc.h" 36 36 #include "system/time.h" 37 #include "l ib/ldb_wrap.h"37 #include "ldb_wrap.h" 38 38 #include "auth/auth.h" 39 #include "auth/credentials/credentials.h" 39 40 #include "param/param.h" 40 41 #include "param/provision.h" 41 #include "libcli/security/dom_sid.h" 42 #include "libcli/security/security.h" 43 #include "dsdb/common/util.h" 42 44 43 45 /* … … 54 56 55 57 */ 56 struct vampire_state {58 struct libnet_vampire_cb_state { 57 59 const char *netbios_name; 58 struct libnet_JoinDomain *join; 60 const char *domain_name; 61 const char *realm; 59 62 struct cli_credentials *machine_account; 63 64 /* Schema loaded from local LDIF files */ 65 struct dsdb_schema *provision_schema; 66 67 /* 1st pass, with some OIDs/attribute names/class names not 68 * converted, because we may not know them yet */ 60 69 struct dsdb_schema *self_made_schema; 70 71 /* prefixMap in LDB format, from the remote DRS server */ 72 DATA_BLOB prefixmap_blob; 61 73 const struct dsdb_schema *schema; 62 74 … … 75 87 unsigned total_objects; 76 88 char *last_partition; 89 const char *server_dn_str; 77 90 }; 78 91 79 static NTSTATUS vampire_prepare_db(void *private_data, 80 const struct libnet_BecomeDC_PrepareDB *p) 81 { 82 struct vampire_state *s = talloc_get_type(private_data, struct vampire_state); 92 /* initialise a state structure ready for replication of chunks */ 93 void *libnet_vampire_replicate_init(TALLOC_CTX *mem_ctx, 94 struct ldb_context *samdb, 95 struct loadparm_context *lp_ctx) 96 { 97 struct libnet_vampire_cb_state *s = talloc_zero(mem_ctx, struct libnet_vampire_cb_state); 98 if (!s) { 99 return NULL; 100 } 101 102 s->ldb = samdb; 103 s->lp_ctx = lp_ctx; 104 s->provision_schema = dsdb_get_schema(s->ldb, s); 105 s->schema = s->provision_schema; 106 s->netbios_name = lpcfg_netbios_name(lp_ctx); 107 s->domain_name = lpcfg_workgroup(lp_ctx); 108 s->realm = lpcfg_realm(lp_ctx); 109 110 return s; 111 } 112 113 /* Caller is expected to keep supplied pointers around for the lifetime of the structure */ 114 void *libnet_vampire_cb_state_init(TALLOC_CTX *mem_ctx, 115 struct loadparm_context *lp_ctx, struct tevent_context *event_ctx, 116 const char *netbios_name, const char *domain_name, const char *realm, 117 const char *targetdir) 118 { 119 struct libnet_vampire_cb_state *s = talloc_zero(mem_ctx, struct libnet_vampire_cb_state); 120 if (!s) { 121 return NULL; 122 } 123 124 s->lp_ctx = lp_ctx; 125 s->event_ctx = event_ctx; 126 s->netbios_name = netbios_name; 127 s->domain_name = domain_name; 128 s->realm = realm; 129 s->targetdir = targetdir; 130 return s; 131 } 132 133 struct ldb_context *libnet_vampire_cb_ldb(struct libnet_vampire_cb_state *state) 134 { 135 state = talloc_get_type_abort(state, struct libnet_vampire_cb_state); 136 return state->ldb; 137 } 138 139 struct loadparm_context *libnet_vampire_cb_lp_ctx(struct libnet_vampire_cb_state *state) 140 { 141 state = talloc_get_type_abort(state, struct libnet_vampire_cb_state); 142 return state->lp_ctx; 143 } 144 145 NTSTATUS libnet_vampire_cb_prepare_db(void *private_data, 146 const struct libnet_BecomeDC_PrepareDB *p) 147 { 148 struct libnet_vampire_cb_state *s = talloc_get_type(private_data, struct libnet_vampire_cb_state); 83 149 struct provision_settings settings; 84 150 struct provision_result result; … … 92 158 settings.schema_dn_str = p->forest->schema_dn_str; 93 159 settings.netbios_name = p->dest_dsa->netbios_name; 94 settings.realm = s-> join->out.realm;95 settings.domain = s-> join->out.domain_name;160 settings.realm = s->realm; 161 settings.domain = s->domain_name; 96 162 settings.server_dn_str = p->dest_dsa->server_dn_str; 97 settings.machine_password = generate_random_ str(s, 16);163 settings.machine_password = generate_random_password(s, 16, 255); 98 164 settings.targetdir = s->targetdir; 99 165 … … 104 170 } 105 171 106 s->ldb = result.samdb; 107 s->lp_ctx = result.lp_ctx; 172 s->ldb = talloc_steal(s, result.samdb); 173 s->lp_ctx = talloc_reparent(talloc_parent(result.lp_ctx), s, result.lp_ctx); 174 s->provision_schema = dsdb_get_schema(s->ldb, s); 175 s->server_dn_str = talloc_steal(s, p->dest_dsa->server_dn_str); 108 176 109 177 /* wrap the entire vapire operation in a transaction. This … … 125 193 } 126 194 127 static NTSTATUS vampire_check_options(void *private_data,128 129 { 130 struct vampire_state *s = talloc_get_type(private_data, struct vampire_state);195 NTSTATUS libnet_vampire_cb_check_options(void *private_data, 196 const struct libnet_BecomeDC_CheckOptions *o) 197 { 198 struct libnet_vampire_cb_state *s = talloc_get_type(private_data, struct libnet_vampire_cb_state); 131 199 132 200 DEBUG(0,("Become DC [%s] of Domain[%s]/[%s]\n", … … 149 217 } 150 218 151 static NTSTATUS vampire_apply_schema(struct vampire_state *s, 152 const struct libnet_BecomeDC_StoreChunk *c) 153 { 219 static NTSTATUS libnet_vampire_cb_apply_schema(struct libnet_vampire_cb_state *s, 220 const struct libnet_BecomeDC_StoreChunk *c) 221 { 222 struct schema_list { 223 struct schema_list *next, *prev; 224 const struct drsuapi_DsReplicaObjectListItemEx *obj; 225 }; 226 154 227 WERROR status; 228 struct dsdb_schema_prefixmap *pfm_remote; 155 229 const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr; 156 uint32_t object_count; 230 struct schema_list *schema_list = NULL, *schema_list_item, *schema_list_next_item; 231 struct dsdb_schema *working_schema; 232 struct dsdb_schema *provision_schema; 233 uint32_t object_count = 0; 157 234 struct drsuapi_DsReplicaObjectListItemEx *first_object; 158 struct drsuapi_DsReplicaObjectListItemEx *cur;235 const struct drsuapi_DsReplicaObjectListItemEx *cur; 159 236 uint32_t linked_attributes_count; 160 237 struct drsuapi_DsReplicaLinkedAttribute *linked_attributes; 161 238 const struct drsuapi_DsReplicaCursor2CtrEx *uptodateness_vector; 162 struct dsdb_extended_replicated_objects * objs;239 struct dsdb_extended_replicated_objects *schema_objs; 163 240 struct repsFromTo1 *s_dsa; 164 241 char *tmp_dns_name; 242 struct ldb_context *schema_ldb; 165 243 struct ldb_message *msg; 166 struct ldb_val prefixMap_val;167 244 struct ldb_message_element *prefixMap_el; 168 struct ldb_val schemaInfo_val;169 245 uint32_t i; 170 int ret ;246 int ret, pass_no; 171 247 bool ok; 172 248 uint64_t seq_num; 249 uint32_t ignore_attids[] = { 250 DRSUAPI_ATTID_auxiliaryClass, 251 DRSUAPI_ATTID_mayContain, 252 DRSUAPI_ATTID_mustContain, 253 DRSUAPI_ATTID_possSuperiors, 254 DRSUAPI_ATTID_systemPossSuperiors, 255 DRSUAPI_ATTID_INVALID 256 }; 173 257 174 258 DEBUG(0,("Analyze and apply schema objects\n")); … … 206 290 } 207 291 208 s_dsa->replica_flags = DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE 209 | DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP 210 | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS; 292 status = dsdb_schema_pfm_from_drsuapi_pfm(mapping_ctr, true, 293 s, &pfm_remote, NULL); 294 if (!W_ERROR_IS_OK(status)) { 295 DEBUG(0,(__location__ ": Failed to decode remote prefixMap: %s", 296 win_errstr(status))); 297 return werror_to_ntstatus(status); 298 } 299 300 s_dsa->replica_flags = DRSUAPI_DRS_WRIT_REP 301 | DRSUAPI_DRS_INIT_SYNC 302 | DRSUAPI_DRS_PER_SYNC; 211 303 memset(s_dsa->schedule, 0x11, sizeof(s_dsa->schedule)); 212 304 … … 217 309 s_dsa->other_info->dns_name = tmp_dns_name; 218 310 311 schema_ldb = provision_get_schema(s, s->lp_ctx, &s->prefixmap_blob); 312 if (!schema_ldb) { 313 DEBUG(0,("Failed to re-load from local provision using remote prefixMap. " 314 "Will continue with local prefixMap\n")); 315 provision_schema = dsdb_get_schema(s->ldb, s); 316 } else { 317 provision_schema = dsdb_get_schema(schema_ldb, s); 318 ret = dsdb_reference_schema(s->ldb, provision_schema, false); 319 if (ret != LDB_SUCCESS) { 320 DEBUG(0,("Failed to attach schema from local provision using remote prefixMap.")); 321 return NT_STATUS_UNSUCCESSFUL; 322 } 323 talloc_free(schema_ldb); 324 } 325 326 /* create a list of objects yet to be converted */ 219 327 for (cur = first_object; cur; cur = cur->next_object) { 220 bool is_attr = false; 221 bool is_class = false; 222 223 for (i=0; i < cur->object.attribute_ctr.num_attributes; i++) { 224 struct drsuapi_DsReplicaAttribute *a; 225 uint32_t j; 226 const char *oid = NULL; 227 228 a = &cur->object.attribute_ctr.attributes[i]; 229 status = dsdb_map_int2oid(s->self_made_schema, a->attid, s, &oid); 328 schema_list_item = talloc(s, struct schema_list); 329 schema_list_item->obj = cur; 330 DLIST_ADD_END(schema_list, schema_list_item, struct schema_list); 331 } 332 333 /* resolve objects until all are resolved and in local schema */ 334 pass_no = 1; 335 working_schema = provision_schema; 336 337 while (schema_list) { 338 uint32_t converted_obj_count = 0; 339 uint32_t failed_obj_count = 0; 340 TALLOC_CTX *tmp_ctx = talloc_new(s); 341 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); 342 343 for (schema_list_item = schema_list; schema_list_item; schema_list_item=schema_list_next_item) { 344 struct dsdb_extended_replicated_object object; 345 346 cur = schema_list_item->obj; 347 348 /* Save the next item, now we have saved out 349 * the current one, so we can DLIST_REMOVE it 350 * safely */ 351 schema_list_next_item = schema_list_item->next; 352 353 /* 354 * Convert the objects into LDB messages using the 355 * schema we have so far. It's ok if we fail to convert 356 * an object. We should convert more objects on next pass. 357 */ 358 status = dsdb_convert_object_ex(s->ldb, working_schema, pfm_remote, 359 cur, c->gensec_skey, 360 ignore_attids, 361 tmp_ctx, &object); 230 362 if (!W_ERROR_IS_OK(status)) { 231 return werror_to_ntstatus(status); 363 DEBUG(1,("Warning: Failed to convert schema object %s into ldb msg\n", 364 cur->object.identifier->dn)); 365 366 failed_obj_count++; 367 } else { 368 /* 369 * Convert the schema from ldb_message format 370 * (OIDs as OID strings) into schema, using 371 * the remote prefixMap 372 */ 373 status = dsdb_schema_set_el_from_ldb_msg(s->ldb, 374 s->self_made_schema, 375 object.msg); 376 if (!W_ERROR_IS_OK(status)) { 377 DEBUG(1,("Warning: failed to convert object %s into a schema element: %s\n", 378 ldb_dn_get_linearized(object.msg->dn), 379 win_errstr(status))); 380 failed_obj_count++; 381 } else { 382 DLIST_REMOVE(schema_list, schema_list_item); 383 converted_obj_count++; 384 } 232 385 } 233 234 switch (a->attid) { 235 case DRSUAPI_ATTRIBUTE_objectClass: 236 for (j=0; j < a->value_ctr.num_values; j++) { 237 uint32_t val = 0xFFFFFFFF; 238 239 if (a->value_ctr.values[j].blob 240 && a->value_ctr.values[j].blob->length == 4) { 241 val = IVAL(a->value_ctr.values[j].blob->data,0); 242 } 243 244 if (val == DRSUAPI_OBJECTCLASS_attributeSchema) { 245 is_attr = true; 246 } 247 if (val == DRSUAPI_OBJECTCLASS_classSchema) { 248 is_class = true; 249 } 250 } 251 252 break; 253 default: 254 break; 386 } 387 talloc_free(tmp_ctx); 388 389 DEBUG(4,("Schema load pass %d: %d/%d of %d objects left to be converted.\n", 390 pass_no, failed_obj_count, converted_obj_count, object_count)); 391 pass_no++; 392 393 /* check if we converted any objects in this pass */ 394 if (converted_obj_count == 0) { 395 DEBUG(0,("Can't continue Schema load: didn't manage to convert any objects: all %d remaining of %d objects failed to convert\n", failed_obj_count, object_count)); 396 return NT_STATUS_INTERNAL_ERROR; 397 } 398 399 if (schema_list) { 400 /* prepare for another cycle */ 401 working_schema = s->self_made_schema; 402 403 ret = dsdb_setup_sorted_accessors(s->ldb, working_schema); 404 if (LDB_SUCCESS != ret) { 405 DEBUG(0,("Failed to create schema-cache indexes!\n")); 406 return NT_STATUS_INTERNAL_ERROR; 255 407 } 256 408 } 257 258 if (is_attr) { 259 struct dsdb_attribute *sa; 260 261 sa = talloc_zero(s->self_made_schema, struct dsdb_attribute); 262 NT_STATUS_HAVE_NO_MEMORY(sa); 263 264 status = dsdb_attribute_from_drsuapi(s->ldb, s->self_made_schema, &cur->object, s, sa); 265 if (!W_ERROR_IS_OK(status)) { 266 return werror_to_ntstatus(status); 267 } 268 269 DLIST_ADD_END(s->self_made_schema->attributes, sa, struct dsdb_attribute *); 270 } 271 272 if (is_class) { 273 struct dsdb_class *sc; 274 275 sc = talloc_zero(s->self_made_schema, struct dsdb_class); 276 NT_STATUS_HAVE_NO_MEMORY(sc); 277 278 status = dsdb_class_from_drsuapi(s->self_made_schema, &cur->object, s, sc); 279 if (!W_ERROR_IS_OK(status)) { 280 return werror_to_ntstatus(status); 281 } 282 283 DLIST_ADD_END(s->self_made_schema->classes, sc, struct dsdb_class *); 284 } 285 } 286 287 /* attach the schema to the ldb */ 409 }; 410 411 /* free temp objects for 1st conversion phase */ 412 talloc_unlink(s, provision_schema); 413 TALLOC_FREE(schema_list); 414 415 /* 416 * attach the schema we just brought over DRS to the ldb, 417 * so we can use it in dsdb_convert_object_ex below 418 */ 288 419 ret = dsdb_set_schema(s->ldb, s->self_made_schema); 289 420 if (ret != LDB_SUCCESS) { 421 DEBUG(0,("Failed to attach working schema from DRS.\n")); 290 422 return NT_STATUS_FOOBAR; 291 423 } 424 292 425 /* we don't want to access the self made schema anymore */ 426 s->schema = s->self_made_schema; 293 427 s->self_made_schema = NULL; 294 s->schema = dsdb_get_schema(s->ldb); 295 296 status = dsdb_extended_replicated_objects_commit(s->ldb, 297 c->partition->nc.dn, 298 mapping_ctr, 299 object_count, 300 first_object, 301 linked_attributes_count, 302 linked_attributes, 303 s_dsa, 304 uptodateness_vector, 305 c->gensec_skey, 306 s, &objs, &seq_num); 428 429 /* Now convert the schema elements again, using the schema we finalised, ready to actually import */ 430 status = dsdb_replicated_objects_convert(s->ldb, 431 s->schema, 432 c->partition->nc.dn, 433 mapping_ctr, 434 object_count, 435 first_object, 436 linked_attributes_count, 437 linked_attributes, 438 s_dsa, 439 uptodateness_vector, 440 c->gensec_skey, 441 s, &schema_objs); 442 if (!W_ERROR_IS_OK(status)) { 443 DEBUG(0,("Failed to convert objects when trying to import over DRS (2nd pass, to store remote schema): %s\n", win_errstr(status))); 444 return werror_to_ntstatus(status); 445 } 446 447 if (lpcfg_parm_bool(s->lp_ctx, NULL, "become dc", "dump objects", false)) { 448 for (i=0; i < schema_objs->num_objects; i++) { 449 struct ldb_ldif ldif; 450 fprintf(stdout, "#\n"); 451 ldif.changetype = LDB_CHANGETYPE_NONE; 452 ldif.msg = schema_objs->objects[i].msg; 453 ldb_ldif_write_file(s->ldb, stdout, &ldif); 454 NDR_PRINT_DEBUG(replPropertyMetaDataBlob, schema_objs->objects[i].meta_data); 455 } 456 } 457 458 status = dsdb_replicated_objects_commit(s->ldb, NULL, schema_objs, &seq_num); 307 459 if (!W_ERROR_IS_OK(status)) { 308 460 DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status))); … … 310 462 } 311 463 312 if (lp_parm_bool(s->lp_ctx, NULL, "become dc", "dump objects", false)) { 313 for (i=0; i < objs->num_objects; i++) { 314 struct ldb_ldif ldif; 315 fprintf(stdout, "#\n"); 316 ldif.changetype = LDB_CHANGETYPE_NONE; 317 ldif.msg = objs->objects[i].msg; 318 ldb_ldif_write_file(s->ldb, stdout, &ldif); 319 NDR_PRINT_DEBUG(replPropertyMetaDataBlob, objs->objects[i].meta_data); 320 } 321 } 322 323 msg = ldb_msg_new(objs); 464 msg = ldb_msg_new(schema_objs); 324 465 NT_STATUS_HAVE_NO_MEMORY(msg); 325 msg->dn = objs->partition_dn; 326 327 status = dsdb_get_oid_mappings_ldb(s->schema, msg, &prefixMap_val, &schemaInfo_val); 328 if (!W_ERROR_IS_OK(status)) { 329 DEBUG(0,("Failed dsdb_get_oid_mappings_ldb(%s)\n", win_errstr(status))); 330 return werror_to_ntstatus(status); 331 } 332 333 /* we only add prefixMap here, because schemaInfo is a replicated attribute and already applied */ 334 ret = ldb_msg_add_value(msg, "prefixMap", &prefixMap_val, &prefixMap_el); 466 msg->dn = schema_objs->partition_dn; 467 468 /* We must ensure a prefixMap has been written. Unlike other 469 * attributes (including schemaInfo), it is not replicated in 470 * the normal replication stream. We can use the one from 471 * s->prefixmap_blob because we operate with one, unchanging 472 * prefixMap for this entire operation. */ 473 ret = ldb_msg_add_value(msg, "prefixMap", &s->prefixmap_blob, &prefixMap_el); 335 474 if (ret != LDB_SUCCESS) { 336 475 return NT_STATUS_FOOBAR; 337 476 } 338 prefixMap_el->flags = LDB_FLAG_MOD_REPLACE; 477 /* We want to know if a prefixMap was written already, as it 478 * would mean that the above comment was not true, and we have 479 * somehow updated the prefixMap during this transaction */ 480 prefixMap_el->flags = LDB_FLAG_MOD_ADD; 339 481 340 482 ret = ldb_modify(s->ldb, msg); 341 483 if (ret != LDB_SUCCESS) { 342 DEBUG(0,("Failed to add prefixMap and schemaInfo %s\n", ldb_strerror(ret)));484 DEBUG(0,("Failed to add prefixMap: %s\n", ldb_errstring(s->ldb))); 343 485 return NT_STATUS_FOOBAR; 344 486 } 345 487 346 488 talloc_free(s_dsa); 347 talloc_free( objs);489 talloc_free(schema_objs); 348 490 349 491 /* We must set these up to ensure the replMetaData is written … … 360 502 } 361 503 362 s->schema = dsdb_get_schema(s->ldb );504 s->schema = dsdb_get_schema(s->ldb, s); 363 505 if (!s->schema) { 364 506 DEBUG(0,("Failed to get loaded dsdb_schema\n")); … … 369 511 } 370 512 371 static NTSTATUS vampire_schema_chunk(void *private_data,372 373 { 374 struct vampire_state *s = talloc_get_type(private_data, struct vampire_state);513 NTSTATUS libnet_vampire_cb_schema_chunk(void *private_data, 514 const struct libnet_BecomeDC_StoreChunk *c) 515 { 516 struct libnet_vampire_cb_state *s = talloc_get_type(private_data, struct libnet_vampire_cb_state); 375 517 WERROR status; 376 518 const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr; … … 415 557 } 416 558 417 if (!s->schema) { 418 s->self_made_schema = dsdb_new_schema(s, lp_iconv_convenience(s->lp_ctx)); 419 559 if (!s->self_made_schema) { 560 WERROR werr; 561 struct drsuapi_DsReplicaOIDMapping_Ctr mapping_ctr_without_schema_info; 562 /* Put the DRS prefixmap aside for the schema we are 563 * about to load in the provision, and into the one we 564 * are making with the help of DRS */ 565 566 mapping_ctr_without_schema_info = *mapping_ctr; 567 568 /* This strips off the 0xFF schema info from the end, 569 * because we don't want it in the blob */ 570 if (mapping_ctr_without_schema_info.num_mappings > 0) { 571 mapping_ctr_without_schema_info.num_mappings--; 572 } 573 werr = dsdb_get_drsuapi_prefixmap_as_blob(&mapping_ctr_without_schema_info, s, &s->prefixmap_blob); 574 if (!W_ERROR_IS_OK(werr)) { 575 return werror_to_ntstatus(werr); 576 } 577 578 /* Set up two manually-constructed schema - the local 579 * schema from the provision will be used to build 580 * one, which will then in turn be used to build the 581 * other. */ 582 s->self_made_schema = dsdb_new_schema(s); 420 583 NT_STATUS_HAVE_NO_MEMORY(s->self_made_schema); 421 584 422 status = dsdb_load_ oid_mappings_drsuapi(s->self_made_schema, mapping_ctr);585 status = dsdb_load_prefixmap_from_drsuapi(s->self_made_schema, mapping_ctr); 423 586 if (!W_ERROR_IS_OK(status)) { 424 587 return werror_to_ntstatus(status); 425 588 } 426 427 s->schema = s->self_made_schema;428 589 } else { 429 status = dsdb_ verify_oid_mappings_drsuapi(s->schema, mapping_ctr);590 status = dsdb_schema_pfm_contains_drsuapi_pfm(s->self_made_schema->prefixmap, mapping_ctr); 430 591 if (!W_ERROR_IS_OK(status)) { 431 592 return werror_to_ntstatus(status); … … 445 606 446 607 if (!c->partition->more_data) { 447 return vampire_apply_schema(s, c);608 return libnet_vampire_cb_apply_schema(s, c); 448 609 } 449 610 … … 451 612 } 452 613 453 static NTSTATUS vampire_store_chunk(void *private_data,454 455 { 456 struct vampire_state *s = talloc_get_type(private_data, struct vampire_state);614 NTSTATUS libnet_vampire_cb_store_chunk(void *private_data, 615 const struct libnet_BecomeDC_StoreChunk *c) 616 { 617 struct libnet_vampire_cb_state *s = talloc_get_type(private_data, struct libnet_vampire_cb_state); 457 618 WERROR status; 619 struct dsdb_schema *schema; 458 620 const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr; 459 621 uint32_t nc_object_count; … … 506 668 } 507 669 508 s_dsa->replica_flags = DRSUAPI_D S_REPLICA_NEIGHBOUR_WRITEABLE509 | DRSUAPI_D S_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP510 | DRSUAPI_D S_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS;670 s_dsa->replica_flags = DRSUAPI_DRS_WRIT_REP 671 | DRSUAPI_DRS_INIT_SYNC 672 | DRSUAPI_DRS_PER_SYNC; 511 673 memset(s_dsa->schedule, 0x11, sizeof(s_dsa->schedule)); 512 674 … … 535 697 536 698 537 status = dsdb_extended_replicated_objects_commit(s->ldb, 538 c->partition->nc.dn, 539 mapping_ctr, 540 object_count, 541 first_object, 542 linked_attributes_count, 543 linked_attributes, 544 s_dsa, 545 uptodateness_vector, 546 c->gensec_skey, 547 s, &objs, &seq_num); 699 schema = dsdb_get_schema(s->ldb, NULL); 700 if (!schema) { 701 DEBUG(0,(__location__ ": Schema is not loaded yet!\n")); 702 return NT_STATUS_INTERNAL_ERROR; 703 } 704 705 status = dsdb_replicated_objects_convert(s->ldb, 706 schema, 707 c->partition->nc.dn, 708 mapping_ctr, 709 object_count, 710 first_object, 711 linked_attributes_count, 712 linked_attributes, 713 s_dsa, 714 uptodateness_vector, 715 c->gensec_skey, 716 s, &objs); 548 717 if (!W_ERROR_IS_OK(status)) { 549 DEBUG(0,("Failed to co mmit objects: %s\n", win_errstr(status)));718 DEBUG(0,("Failed to convert objects: %s\n", win_errstr(status))); 550 719 return werror_to_ntstatus(status); 551 720 } 552 721 553 if (lp _parm_bool(s->lp_ctx, NULL, "become dc", "dump objects", false)) {722 if (lpcfg_parm_bool(s->lp_ctx, NULL, "become dc", "dump objects", false)) { 554 723 for (i=0; i < objs->num_objects; i++) { 555 724 struct ldb_ldif ldif; … … 561 730 } 562 731 } 732 status = dsdb_replicated_objects_commit(s->ldb, NULL, objs, &seq_num); 733 if (!W_ERROR_IS_OK(status)) { 734 DEBUG(0,("Failed to commit objects: %s\n", win_errstr(status))); 735 return werror_to_ntstatus(status); 736 } 737 563 738 talloc_free(s_dsa); 564 739 talloc_free(objs); … … 581 756 } 582 757 583 if (lp _parm_bool(s->lp_ctx, NULL, "become dc", "dump objects", false)) {758 if (lpcfg_parm_bool(s->lp_ctx, NULL, "become dc", "dump objects", false)) { 584 759 DEBUG(0,("# %s\n", sa->lDAPDisplayName)); 585 760 NDR_PRINT_DEBUG(drsuapi_DsReplicaLinkedAttribute, &linked_attributes[i]); … … 593 768 } 594 769 770 static NTSTATUS update_dnshostname_for_server(TALLOC_CTX *mem_ctx, 771 struct ldb_context *ldb, 772 const char *server_dn_str, 773 const char *netbios_name, 774 const char *realm) 775 { 776 int ret; 777 struct ldb_message *msg; 778 struct ldb_message_element *el; 779 struct ldb_dn *server_dn; 780 const char *dNSHostName = strlower_talloc(mem_ctx, 781 talloc_asprintf(mem_ctx, 782 "%s.%s", 783 netbios_name, 784 realm)); 785 msg = ldb_msg_new(mem_ctx); 786 if (msg == NULL) { 787 return NT_STATUS_NO_MEMORY; 788 } 789 790 server_dn = ldb_dn_new(mem_ctx, ldb, server_dn_str); 791 if (!server_dn) { 792 return NT_STATUS_INTERNAL_ERROR; 793 } 794 795 msg->dn = server_dn; 796 ret = ldb_msg_add_empty(msg, "dNSHostName", LDB_FLAG_MOD_ADD, &el); 797 if (ret != LDB_SUCCESS) { 798 return NT_STATUS_INTERNAL_ERROR; 799 } 800 801 ret = ldb_msg_add_steal_string(msg, 802 "dNSHostName", 803 talloc_asprintf(el->values, "%s", dNSHostName)); 804 if (ret != LDB_SUCCESS) { 805 return NT_STATUS_INTERNAL_ERROR; 806 } 807 808 ret = dsdb_modify(ldb, msg, DSDB_MODIFY_PERMISSIVE); 809 if (ret != LDB_SUCCESS) { 810 DEBUG(0,(__location__ ": Failed to add dnsHostName to the Server object: %s\n", 811 ldb_errstring(ldb))); 812 return NT_STATUS_INTERNAL_ERROR; 813 } 814 815 return NT_STATUS_OK; 816 } 817 818 595 819 NTSTATUS libnet_Vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, 596 820 struct libnet_Vampire *r) 597 821 { 598 822 struct libnet_JoinDomain *join; 599 struct provision_store_self_join_settings *set_secrets; 600 struct libnet_BecomeDC b; 601 struct vampire_state *s; 602 struct ldb_message *msg; 603 const char *error_string; 604 int ldb_ret; 605 uint32_t i; 823 struct libnet_Replicate rep; 606 824 NTSTATUS status; 607 825 … … 611 829 r->out.error_string = NULL; 612 830 613 s = talloc_zero(mem_ctx, struct vampire_state); 614 if (!s) { 615 return NT_STATUS_NO_MEMORY; 616 } 617 618 s->lp_ctx = ctx->lp_ctx; 619 s->event_ctx = ctx->event_ctx; 620 621 join = talloc_zero(s, struct libnet_JoinDomain); 831 join = talloc_zero(mem_ctx, struct libnet_JoinDomain); 622 832 if (!join) { 623 833 return NT_STATUS_NO_MEMORY; … … 627 837 netbios_name = r->in.netbios_name; 628 838 } else { 629 netbios_name = talloc_reference(join, lp _netbios_name(ctx->lp_ctx));839 netbios_name = talloc_reference(join, lpcfg_netbios_name(ctx->lp_ctx)); 630 840 if (!netbios_name) { 841 talloc_free(join); 631 842 r->out.error_string = NULL; 632 talloc_free(s);633 843 return NT_STATUS_NO_MEMORY; 634 844 } … … 637 847 account_name = talloc_asprintf(join, "%s$", netbios_name); 638 848 if (!account_name) { 849 talloc_free(join); 639 850 r->out.error_string = NULL; 640 talloc_free(s);641 851 return NT_STATUS_NO_MEMORY; 642 852 } 643 853 854 /* Re-use the domain we are joining as the domain for the user 855 * to be authenticated with, unless they specified 856 * otherwise */ 857 cli_credentials_set_domain(ctx->cred, r->in.domain_name, CRED_GUESS_ENV); 858 644 859 join->in.domain_name = r->in.domain_name; 645 860 join->in.account_name = account_name; … … 651 866 if (!NT_STATUS_IS_OK(status)) { 652 867 r->out.error_string = talloc_steal(mem_ctx, join->out.error_string); 653 talloc_free( s);868 talloc_free(join); 654 869 return status; 655 870 } 871 872 rep.in.domain_name = join->out.domain_name; 873 rep.in.netbios_name = netbios_name; 874 rep.in.targetdir = r->in.targetdir; 875 rep.in.domain_sid = join->out.domain_sid; 876 rep.in.realm = join->out.realm; 877 rep.in.server = join->out.samr_binding->host; 878 rep.in.join_password = join->out.join_password; 879 rep.in.kvno = join->out.kvno; 880 881 status = libnet_Replicate(ctx, mem_ctx, &rep); 882 883 r->out.domain_sid = join->out.domain_sid; 884 r->out.domain_name = join->out.domain_name; 885 r->out.error_string = rep.out.error_string; 886 887 return status; 888 } 889 890 891 892 NTSTATUS libnet_Replicate(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, 893 struct libnet_Replicate *r) 894 { 895 struct provision_store_self_join_settings *set_secrets; 896 struct libnet_BecomeDC b; 897 struct libnet_vampire_cb_state *s; 898 struct ldb_message *msg; 899 const char *error_string; 900 int ldb_ret; 901 uint32_t i; 902 NTSTATUS status; 903 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 904 const char *account_name; 905 const char *netbios_name; 906 907 r->out.error_string = NULL; 908 909 netbios_name = r->in.netbios_name; 910 account_name = talloc_asprintf(tmp_ctx, "%s$", netbios_name); 911 if (!account_name) { 912 talloc_free(tmp_ctx); 913 r->out.error_string = NULL; 914 return NT_STATUS_NO_MEMORY; 915 } 656 916 657 s->join = join; 658 659 s->targetdir = r->in.targetdir; 917 /* Re-use the domain we are joining as the domain for the user 918 * to be authenticated with, unless they specified 919 * otherwise */ 920 cli_credentials_set_domain(ctx->cred, r->in.domain_name, CRED_GUESS_ENV); 921 922 s = libnet_vampire_cb_state_init(mem_ctx, ctx->lp_ctx, ctx->event_ctx, 923 netbios_name, r->in.domain_name, r->in.realm, 924 r->in.targetdir); 925 if (!s) { 926 return NT_STATUS_NO_MEMORY; 927 } 928 talloc_steal(s, tmp_ctx); 660 929 661 930 ZERO_STRUCT(b); 662 b.in.domain_dns_name = join->out.realm; 663 b.in.domain_netbios_name = join->out.domain_name; 664 b.in.domain_sid = join->out.domain_sid; 665 b.in.source_dsa_address = join->out.samr_binding->host; 931 932 /* Be more robust: 933 * We now know the domain and realm for sure - if they didn't 934 * put one on the command line, use this for the rest of the 935 * join */ 936 cli_credentials_set_realm(ctx->cred, r->in.realm, CRED_GUESS_ENV); 937 cli_credentials_set_domain(ctx->cred, r->in.domain_name, CRED_GUESS_ENV); 938 939 /* Now set these values into the smb.conf - we probably had 940 * empty or useless defaults here from whatever smb.conf we 941 * started with */ 942 lpcfg_set_cmdline(s->lp_ctx, "realm", r->in.realm); 943 lpcfg_set_cmdline(s->lp_ctx, "workgroup", r->in.domain_name); 944 945 b.in.domain_dns_name = r->in.realm; 946 b.in.domain_netbios_name = r->in.domain_name; 947 b.in.domain_sid = r->in.domain_sid; 948 b.in.source_dsa_address = r->in.server; 666 949 b.in.dest_dsa_netbios_name = netbios_name; 667 950 668 951 b.in.callbacks.private_data = s; 669 b.in.callbacks.check_options = vampire_check_options; 670 b.in.callbacks.prepare_db = vampire_prepare_db; 671 b.in.callbacks.schema_chunk = vampire_schema_chunk; 672 b.in.callbacks.config_chunk = vampire_store_chunk; 673 b.in.callbacks.domain_chunk = vampire_store_chunk; 952 b.in.callbacks.check_options = libnet_vampire_cb_check_options; 953 b.in.callbacks.prepare_db = libnet_vampire_cb_prepare_db; 954 b.in.callbacks.schema_chunk = libnet_vampire_cb_schema_chunk; 955 b.in.callbacks.config_chunk = libnet_vampire_cb_store_chunk; 956 b.in.callbacks.domain_chunk = libnet_vampire_cb_store_chunk; 957 958 b.in.rodc_join = lpcfg_parm_bool(s->lp_ctx, NULL, "repl", "RODC", false); 674 959 675 960 status = libnet_BecomeDC(ctx, s, &b); … … 707 992 ldb_ret = ldb_modify(s->ldb, msg); 708 993 if (ldb_ret != LDB_SUCCESS) { 709 printf("ldb_modify() failed: %d \n", ldb_ret);994 printf("ldb_modify() failed: %d : %s\n", ldb_ret, ldb_errstring(s->ldb)); 710 995 talloc_free(s); 711 996 return NT_STATUS_INTERNAL_DB_ERROR; 712 997 } 713 998 /* during dcpromo the 2nd computer adds dNSHostName attribute to his Server object 999 * the attribute appears on the original DC after replication 1000 */ 1001 status = update_dnshostname_for_server(s, s->ldb, s->server_dn_str, s->netbios_name, s->realm); 1002 if (!NT_STATUS_IS_OK(status)) { 1003 printf("Failed to update dNSHostName on Server object - %s\n", nt_errstr(status)); 1004 talloc_free(s); 1005 return status; 1006 } 714 1007 /* prepare the transaction - this prepares to commit all the changes in 715 1008 the ldb from the whole vampire. Note that this … … 717 1010 */ 718 1011 if (ldb_transaction_prepare_commit(s->ldb) != LDB_SUCCESS) { 719 printf("Failed to prepare_commit vampire transaction \n");1012 printf("Failed to prepare_commit vampire transaction: %s\n", ldb_errstring(s->ldb)); 720 1013 return NT_STATUS_INTERNAL_DB_ERROR; 721 1014 } … … 729 1022 730 1023 ZERO_STRUCTP(set_secrets); 731 set_secrets->domain_name = join->out.domain_name; 732 set_secrets->realm = join->out.realm; 733 set_secrets->account_name = account_name; 1024 set_secrets->domain_name = r->in.domain_name; 1025 set_secrets->realm = r->in.realm; 734 1026 set_secrets->netbios_name = netbios_name; 735 1027 set_secrets->secure_channel_type = SEC_CHAN_BDC; 736 set_secrets->machine_password = join->out.join_password;737 set_secrets->key_version_number = join->out.kvno;738 set_secrets->domain_sid = join->out.domain_sid;1028 set_secrets->machine_password = r->in.join_password; 1029 set_secrets->key_version_number = r->in.kvno; 1030 set_secrets->domain_sid = r->in.domain_sid; 739 1031 740 status = provision_store_self_join(ctx, ctx->lp_ctx, ctx->event_ctx, set_secrets, &error_string);1032 status = provision_store_self_join(ctx, s->lp_ctx, ctx->event_ctx, set_secrets, &error_string); 741 1033 if (!NT_STATUS_IS_OK(status)) { 742 1034 r->out.error_string = talloc_steal(mem_ctx, error_string); … … 745 1037 } 746 1038 747 r->out.domain_name = talloc_steal(r, join->out.domain_name);748 r->out.domain_sid = dom_sid_dup(r, join->out.domain_sid);749 750 1039 /* commit the transaction now we know the secrets were written 751 1040 * out properly … … 759 1048 760 1049 return NT_STATUS_OK; 761 762 } 1050 }
Note:
See TracChangeset
for help on using the changeset viewer.