summaryrefslogtreecommitdiff
path: root/source3/libnet/libnet_dssync_keytab.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libnet/libnet_dssync_keytab.c')
-rw-r--r--source3/libnet/libnet_dssync_keytab.c65
1 files changed, 61 insertions, 4 deletions
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;
}