Use the cldap reply to avoid segfaulting in RPC-DSSYNC
[metze/samba/wip.git] / source / torture / rpc / dssync.c
index 9c07e5f532e2051d2186f0f718bc65e0c8cd7e4f..e8c67b46c107c1d60807874a5d46eb6b4fed3040 100644 (file)
@@ -23,6 +23,7 @@
 #include "includes.h"
 #include "lib/cmdline/popt_common.h"
 #include "librpc/gen_ndr/ndr_drsuapi_c.h"
+#include "librpc/gen_ndr/ndr_drsblobs.h"
 #include "libcli/cldap/cldap.h"
 #include "libcli/ldap/ldap_client.h"
 #include "torture/torture.h"
@@ -33,6 +34,7 @@
 #include "libcli/auth/libcli_auth.h"
 #include "auth/gensec/gensec.h"
 #include "param/param.h"
+#include "dsdb/samdb/samdb.h"
 
 struct DsSyncBindInfo {
        struct dcerpc_pipe *pipe;
@@ -104,7 +106,7 @@ static struct DsSyncTest *test_create_context(struct torture_context *tctx)
        our_bind_info28->supported_extensions   = 0xFFFFFFFF;
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3;
        our_bind_info28->site_guid              = GUID_zero();
-       our_bind_info28->u1                     = 0;
+       our_bind_info28->pid                    = 0;
        our_bind_info28->repl_epoch             = 1;
 
        our_bind_info_ctr                       = &ctx->admin.drsuapi.our_bind_info_ctr;
@@ -153,7 +155,7 @@ static struct DsSyncTest *test_create_context(struct torture_context *tctx)
                our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS;
        }
        our_bind_info28->site_guid              = GUID_zero();
-       our_bind_info28->u1                     = 508;
+       our_bind_info28->pid                    = 0;
        our_bind_info28->repl_epoch             = 0;
 
        our_bind_info_ctr                       = &ctx->new_dc.drsuapi.our_bind_info_ctr;
@@ -210,13 +212,25 @@ static bool _test_DsBind(struct torture_context *tctx,
                        info24 = &b->req.out.bind_info->info.info24;
                        b->peer_bind_info28.supported_extensions= info24->supported_extensions;
                        b->peer_bind_info28.site_guid           = info24->site_guid;
-                       b->peer_bind_info28.u1                  = info24->u1;
+                       b->peer_bind_info28.pid                 = info24->pid;
                        b->peer_bind_info28.repl_epoch          = 0;
                        break;
                }
+               case 48: {
+                       struct drsuapi_DsBindInfo48 *info48;
+                       info48 = &b->req.out.bind_info->info.info48;
+                       b->peer_bind_info28.supported_extensions= info48->supported_extensions;
+                       b->peer_bind_info28.site_guid           = info48->site_guid;
+                       b->peer_bind_info28.pid                 = info48->pid;
+                       b->peer_bind_info28.repl_epoch          = info48->repl_epoch;
+                       break;
+               }
                case 28:
                        b->peer_bind_info28 = b->req.out.bind_info->info.info28;
                        break;
+               default:
+                       printf("DsBind - warning: unknown BindInfo length: %u\n",
+                              b->req.out.bind_info->length);
                }
        }
 
@@ -301,6 +315,14 @@ static bool test_GetInfo(struct torture_context *tctx, struct DsSyncTest *ctx)
                printf("cldap_netlogon() returned Server Site-Name: %s.\n",search.out.netlogon.nt5_ex.server_site);
        }
 
+       if (!ctx->domain_dn) {
+               struct ldb_context *ldb = ldb_init(ctx, tctx->ev);
+               struct ldb_dn *dn = samdb_dns_domain_to_dn(ldb, ctx, search.out.netlogon.nt5_ex.dns_domain);
+               ctx->domain_dn = ldb_dn_alloc_linearized(ctx, dn);
+               talloc_free(dn);
+               talloc_free(ldb);
+       }
+
        return ret;
 }
 
@@ -514,6 +536,8 @@ static void test_analyse_objects(struct torture_context *tctx,
                        DEBUGADD(0,("ATTR: %s enc.length=%lu plain.length=%lu\n",
                                    name, (long)enc_data->length, (long)plain_data.length));
                        if (plain_data.length) {
+                               enum ndr_err_code ndr_err;
+                               struct supplementalCredentialsBlob scb;
                                dump_data(0, plain_data.data, plain_data.length);
                                if (save_values_dir) {
                                        char *fname;
@@ -529,6 +553,13 @@ static void test_analyse_objects(struct torture_context *tctx,
                                        }
                                        talloc_free(fname);
                                }
+
+                               ndr_err = ndr_pull_struct_blob_all(&plain_data, tctx,
+                                          lp_iconv_convenience(tctx->lp_ctx), &scb,
+                                          (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob);
+                               if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                                       NDR_PRINT_DEBUG(supplementalCredentialsBlob, &scb);
+                               }
                        } else {
                                dump_data(0, enc_data->data, enc_data->length);
                        }
@@ -711,7 +742,7 @@ static bool test_FetchData(struct torture_context *tctx, struct DsSyncTest *ctx)
 
                                test_analyse_objects(tctx, ctx, &gensec_skey, ctr1->first_object);
 
-                               if (ctr1->new_highwatermark.tmp_highest_usn > ctr1->new_highwatermark.highest_usn) {
+                               if (ctr1->more_data) {
                                        r.in.req.req5.highwatermark = ctr1->new_highwatermark;
                                        continue;
                                }
@@ -739,7 +770,7 @@ static bool test_FetchData(struct torture_context *tctx, struct DsSyncTest *ctx)
 
                                test_analyse_objects(tctx, ctx, &gensec_skey, ctr6->first_object);
 
-                               if (ctr6->new_highwatermark.tmp_highest_usn > ctr6->new_highwatermark.highest_usn) {
+                               if (ctr6->more_data) {
                                        r.in.req.req8.highwatermark = ctr6->new_highwatermark;
                                        continue;
                                }
@@ -778,7 +809,10 @@ static bool test_FetchNT4Data(struct torture_context *tctx,
                r.in.req.req1.data      = cookie.data;
 
                status = dcerpc_drsuapi_DsGetNT4ChangeLog(ctx->new_dc.drsuapi.pipe, ctx, &r);
-               if (!NT_STATUS_IS_OK(status)) {
+               if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
+                       printf("DsGetNT4ChangeLog not supported by target server\n");
+                       break;
+               } else if (!NT_STATUS_IS_OK(status)) {
                        const char *errstr = nt_errstr(status);
                        if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
                                errstr = dcerpc_errstr(ctx, ctx->new_dc.drsuapi.pipe->last_fault_code);