summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2008-07-17 00:54:35 +0200
committerMichael Adam <obnox@samba.org>2008-08-01 16:04:40 +0200
commit0db26805da4f62c313237e762a81cebbe0f0357c (patch)
treec077cc34270063625ddea65a25cb75057a23e616
parent54d6ae09e268e169ee7f0f5ab02a465b030f4ba4 (diff)
downloadsamba-0db26805da4f62c313237e762a81cebbe0f0357c.tar.gz
samba-0db26805da4f62c313237e762a81cebbe0f0357c.tar.bz2
samba-0db26805da4f62c313237e762a81cebbe0f0357c.zip
dssync keytab: add support for keeping track of the up-to-date-ness vector.
The startup operation should get the old up-to-date-ness vector from the backend and the finish operation should store the new vector to the backend after replication. This adds the change of the signatures of the operations ot the dssync_ops struct and the implementation for the keytab ops. The up-to-date-ness vector is stored under the principal constructed as UTDV/$naming_context_dn@$dns_domain_name. The vector is still uninterpreted in libnet_dssync_process(). This will be the next step... This code is essentially by Metze. Michael (This used to be commit 01318fb27a1aa9e5fed0d4dd882a123ab568ac37)
-rw-r--r--source3/include/smb.h1
-rw-r--r--source3/libnet/libnet_dssync.c4
-rw-r--r--source3/libnet/libnet_dssync.h6
-rw-r--r--source3/libnet/libnet_dssync_keytab.c65
4 files changed, 68 insertions, 8 deletions
diff --git a/source3/include/smb.h b/source3/include/smb.h
index d79439f589..b8ff34f831 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -279,6 +279,7 @@ extern const DATA_BLOB data_blob_null;
#include "librpc/gen_ndr/ntsvcs.h"
#include "librpc/gen_ndr/nbt.h"
#include "librpc/gen_ndr/drsuapi.h"
+#include "librpc/gen_ndr/drsblobs.h"
struct lsa_dom_info {
bool valid;
diff --git a/source3/libnet/libnet_dssync.c b/source3/libnet/libnet_dssync.c
index f33369ee4b..9801ec76d0 100644
--- a/source3/libnet/libnet_dssync.c
+++ b/source3/libnet/libnet_dssync.c
@@ -355,7 +355,7 @@ static NTSTATUS libnet_dssync_process(TALLOC_CTX *mem_ctx,
nc.guid = GUID_zero();
nc.sid = null_sid;
- status = ctx->ops->startup(ctx, mem_ctx);
+ status = ctx->ops->startup(ctx, mem_ctx, NULL);
if (!NT_STATUS_IS_OK(status)) {
ctx->error_message = talloc_asprintf(mem_ctx,
"Failed to call startup operation: %s",
@@ -489,7 +489,7 @@ static NTSTATUS libnet_dssync_process(TALLOC_CTX *mem_ctx,
}
}
- status = ctx->ops->finish(ctx, mem_ctx);
+ status = ctx->ops->finish(ctx, mem_ctx, NULL);
if (!NT_STATUS_IS_OK(status)) {
ctx->error_message = talloc_asprintf(mem_ctx,
"Failed to call finishing operation: %s",
diff --git a/source3/libnet/libnet_dssync.h b/source3/libnet/libnet_dssync.h
index 9b18dae4f5..16b84ad32c 100644
--- a/source3/libnet/libnet_dssync.h
+++ b/source3/libnet/libnet_dssync.h
@@ -20,12 +20,14 @@
struct dssync_context;
struct dssync_ops {
- NTSTATUS (*startup)(struct dssync_context *ctx, TALLOC_CTX *mem_ctx);
+ NTSTATUS (*startup)(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
+ struct replUpToDateVectorBlob **pold_utdv);
NTSTATUS (*process_objects)(struct dssync_context *ctx,
TALLOC_CTX *mem_ctx,
struct drsuapi_DsReplicaObjectListItemEx *objects,
struct drsuapi_DsReplicaOIDMapping_Ctr *mappings);
- NTSTATUS (*finish)(struct dssync_context *ctx, TALLOC_CTX *mem_ctx);
+ NTSTATUS (*finish)(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
+ struct replUpToDateVectorBlob *new_utdv);
};
struct dssync_context {
diff --git a/source3/libnet/libnet_dssync_keytab.c b/source3/libnet/libnet_dssync_keytab.c
index b1f0a35d8b..37a4a4e88e 100644
--- a/source3/libnet/libnet_dssync_keytab.c
+++ b/source3/libnet/libnet_dssync_keytab.c
@@ -19,6 +19,7 @@
#include "includes.h"
#include "libnet/libnet.h"
+#include "librpc/gen_ndr/ndr_drsblobs.h"
#if defined(HAVE_ADS) && defined(ENCTYPE_ARCFOUR_HMAC)
@@ -49,10 +50,14 @@ static NTSTATUS add_to_keytab_entries(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
-static NTSTATUS keytab_startup(struct dssync_context *ctx, TALLOC_CTX *mem_ctx)
+static NTSTATUS keytab_startup(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
+ struct replUpToDateVectorBlob **pold_utdv)
{
krb5_error_code ret = 0;
struct libnet_keytab_context *keytab_ctx;
+ struct libnet_keytab_entry *entry;
+ struct replUpToDateVectorBlob *old_utdv = NULL;
+ char *principal;
ret = libnet_keytab_init(mem_ctx, ctx->output_filename, &keytab_ctx);
if (ret) {
@@ -62,16 +67,66 @@ static NTSTATUS keytab_startup(struct dssync_context *ctx, TALLOC_CTX *mem_ctx)
keytab_ctx->dns_domain_name = ctx->dns_domain_name;
ctx->private_data = keytab_ctx;
+ principal = talloc_asprintf(mem_ctx, "UTDV/%s@%s",
+ ctx->nc_dn, ctx->dns_domain_name);
+ NT_STATUS_HAVE_NO_MEMORY(principal);
+
+ entry = libnet_keytab_search(keytab_ctx, principal, 0, mem_ctx);
+ if (entry) {
+ enum ndr_err_code ndr_err;
+ old_utdv = talloc(mem_ctx, struct replUpToDateVectorBlob);
+
+ ndr_err = ndr_pull_struct_blob(&entry->password, old_utdv,
+ old_utdv,
+ (ndr_pull_flags_fn_t)ndr_pull_replUpToDateVectorBlob);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+ ctx->error_message = talloc_asprintf(mem_ctx,
+ "Failed to pull UpToDateVector: %s",
+ nt_errstr(status));
+ return status;
+ }
+
+ NDR_PRINT_DEBUG(replUpToDateVectorBlob, old_utdv);
+ }
+
+ if (pold_utdv) {
+ *pold_utdv = old_utdv;
+ }
+
return NT_STATUS_OK;
}
-static NTSTATUS keytab_finish(struct dssync_context *ctx, TALLOC_CTX *mem_ctx)
+static NTSTATUS keytab_finish(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
+ struct replUpToDateVectorBlob *new_utdv)
{
NTSTATUS status = NT_STATUS_OK;
krb5_error_code ret = 0;
struct libnet_keytab_context *keytab_ctx =
(struct libnet_keytab_context *)ctx->private_data;
+ if (new_utdv) {
+ enum ndr_err_code ndr_err;
+ DATA_BLOB blob;
+
+ NDR_PRINT_DEBUG(replUpToDateVectorBlob, new_utdv);
+ ndr_err = ndr_push_struct_blob(&blob, mem_ctx, new_utdv,
+ (ndr_push_flags_fn_t)ndr_push_replUpToDateVectorBlob);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ status = ndr_map_error2ntstatus(ndr_err);
+ ctx->error_message = talloc_asprintf(mem_ctx,
+ "Failed to push UpToDateVector: %s",
+ nt_errstr(status));
+ goto done;
+ }
+
+ status = add_to_keytab_entries(mem_ctx, keytab_ctx, 0,
+ ctx->nc_dn, "UTDV", blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+ }
+
ret = libnet_keytab_add(keytab_ctx);
if (ret) {
status = krb5_to_nt_status(ret);
@@ -249,12 +304,14 @@ static NTSTATUS keytab_process_objects(struct dssync_context *ctx,
#else
-static NTSTATUS keytab_startup(struct dssync_context *ctx, TALLOC_CTX *mem_ctx)
+static NTSTATUS keytab_startup(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
+ struct replUpToDateVectorBlob **pold_utdv)
{
return NT_STATUS_NOT_SUPPORTED;
}
-static NTSTATUS keytab_finish(struct dssync_context *ctx, TALLOC_CTX *mem_ctx)
+static NTSTATUS keytab_finish(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
+ struct replUpToDateVectorBlob *new_utdv)
{
return NT_STATUS_NOT_SUPPORTED;
}