diff options
-rw-r--r-- | source3/include/smb.h | 1 | ||||
-rw-r--r-- | source3/libnet/libnet_dssync.c | 4 | ||||
-rw-r--r-- | source3/libnet/libnet_dssync.h | 6 | ||||
-rw-r--r-- | source3/libnet/libnet_dssync_keytab.c | 65 |
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; } |