From 69802b3a3b934407d898088c8b3fbee64919b668 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 2 Sep 2009 16:57:25 +1000 Subject: wrap the entire vampire operation in a transaction We want to grab the whole database, or none of it. This is also needed to get linked attributes right --- source4/libnet/libnet_vampire.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'source4/libnet/libnet_vampire.c') diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 3265a04c77..d8b890e5b4 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -103,6 +103,19 @@ static NTSTATUS vampire_prepare_db(void *private_data, s->ldb = result.samdb; s->lp_ctx = result.lp_ctx; + /* wrap the entire vapire operation in a transaction. This + isn't just cosmetic - we use this to ensure that linked + attribute back links are added at the end by relying on a + transaction commit hook in the linked attributes module. We + need to do this as the order of objects coming from the + server is not sufficiently deterministic to know that the + record that a backlink needs to be created in has itself + been created before the object containing the forward link + has come over the wire */ + if (ldb_transaction_start(s->ldb) != LDB_SUCCESS) { + return NT_STATUS_FOOBAR; + } + return NT_STATUS_OK; @@ -329,19 +342,8 @@ static NTSTATUS vampire_apply_schema(struct vampire_state *s, talloc_free(s_dsa); talloc_free(objs); - /* reopen the ldb */ - talloc_free(s->ldb); /* this also free's the s->schema, because dsdb_set_schema() steals it */ - s->schema = NULL; - - DEBUG(0,("Reopen the SAM LDB with system credentials and a already stored schema\n")); - s->ldb = samdb_connect(s, s->event_ctx, s->lp_ctx, - system_session(s, s->lp_ctx)); - if (!s->ldb) { - DEBUG(0,("Failed to reopen sam.ldb\n")); - return NT_STATUS_INTERNAL_DB_ERROR; - } - - /* We must set these up to ensure the replMetaData is written correctly, before our NTDS Settings entry is replicated */ + /* We must set these up to ensure the replMetaData is written + * correctly, before our NTDS Settings entry is replicated */ ok = samdb_set_ntds_invocation_id(s->ldb, &c->dest_dsa->invocation_id); if (!ok) { DEBUG(0,("Failed to set cached ntds invocationId\n")); @@ -691,6 +693,15 @@ NTSTATUS libnet_Vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, return NT_STATUS_INTERNAL_DB_ERROR; } + /* commit the transaction - this commits all the changes in + the ldb from the whole vampire. Note that this commit + triggers the writing of the linked attribute backlinks. + */ + if (ldb_transaction_commit(s->ldb) != LDB_SUCCESS) { + printf("Failed to commit vampire transaction\n"); + return NT_STATUS_INTERNAL_DB_ERROR; + } + set_secrets = talloc_zero(s, struct libnet_set_join_secrets); if (!set_secrets) { return NT_STATUS_NO_MEMORY; -- cgit