dssync keytab: add support for keeping track of the up-to-date-ness vector.
authorMichael Adam <obnox@samba.org>
Wed, 16 Jul 2008 22:54:35 +0000 (00:54 +0200)
committerMichael Adam <obnox@samba.org>
Fri, 1 Aug 2008 14:04:40 +0000 (16:04 +0200)
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)

source3/include/smb.h
source3/libnet/libnet_dssync.c
source3/libnet/libnet_dssync.h
source3/libnet/libnet_dssync_keytab.c

index d79439f5894a32f1d08a04d6b998c47ca99b5222..b8ff34f8313fcbf4497dbd5cc115405dc75589a6 100644 (file)
@@ -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;
index f33369ee4b86182c1360202f8b4734203d9ac89b..9801ec76d099a862d73fe15f837378e6cc7cc9d4 100644 (file)
@@ -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",
index 9b18dae4f5772998e6fd8497916ff51dff034a1d..16b84ad32ca8b612257d7445fe40390ca087781a 100644 (file)
 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 {
index b1f0a35d8b964bfb2e3128eeb34efa4dc36821f9..37a4a4e88ed8d2b5934a8de1e7077d4bc41aceaa 100644 (file)
@@ -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;
 }