summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
}