DEBUG s4:torture/dssync: ...
[metze/samba/wip.git] / source4 / torture / drs / rpc / dssync.c
index cd9a733492b2a3b462777dc6c47a6da443ecaa0f..024b6773269aaad9ac5d4d7576e128f1f06aa840 100644 (file)
@@ -88,6 +88,7 @@ static struct DsSyncTest *test_create_context(struct torture_context *tctx)
        struct drsuapi_DsBindInfo28 *our_bind_info28;
        struct drsuapi_DsBindInfoCtr *our_bind_info_ctr;
        const char *binding = torture_setting_string(tctx, "binding", NULL);
+       const char *host;
        struct nbt_name name;
 
        ctx = talloc_zero(tctx, struct DsSyncTest);
@@ -98,15 +99,23 @@ static struct DsSyncTest *test_create_context(struct torture_context *tctx)
                printf("Bad binding string %s\n", binding);
                return NULL;
        }
-       ctx->drsuapi_binding->flags |= DCERPC_SIGN | DCERPC_SEAL;
+       status = dcerpc_binding_set_flags(ctx->drsuapi_binding,
+                                         DCERPC_SIGN | DCERPC_SEAL, 0);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("dcerpc_binding_set_flags - %s\n", nt_errstr(status));
+               return NULL;
+       }
 
-       ctx->ldap_url = talloc_asprintf(ctx, "ldap://%s", ctx->drsuapi_binding->host);
+       host = dcerpc_binding_get_string_option(ctx->drsuapi_binding, "host");
 
-       make_nbt_name_server(&name, ctx->drsuapi_binding->host);
+       ctx->ldap_url = talloc_asprintf(ctx, "ldap://%s", host);
+
+       make_nbt_name_server(&name, host);
 
        /* do an initial name resolution to find its IP */
-       status = resolve_name(lpcfg_resolve_context(tctx->lp_ctx), &name, tctx,
-                             &ctx->dest_address, tctx->ev);
+       status = resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx),
+                                0, 0, &name, tctx,
+                                &ctx->dest_address, tctx->ev);
        if (!NT_STATUS_IS_OK(status)) {
                printf("Failed to resolve %s - %s\n",
                       name.name, nt_errstr(status));
@@ -228,6 +237,19 @@ static bool _test_DsBind(struct torture_context *tctx,
                        b->peer_bind_info28.repl_epoch          = 0;
                        break;
                }
+               case 28: {
+                       b->peer_bind_info28 = b->req.out.bind_info->info.info28;
+                       break;
+               }
+               case 32: {
+                       struct drsuapi_DsBindInfo32 *info32;
+                       info32 = &b->req.out.bind_info->info.info32;
+                       b->peer_bind_info28.supported_extensions= info32->supported_extensions;
+                       b->peer_bind_info28.site_guid           = info32->site_guid;
+                       b->peer_bind_info28.pid                 = info32->pid;
+                       b->peer_bind_info28.repl_epoch          = info32->repl_epoch;
+                       break;
+               }
                case 48: {
                        struct drsuapi_DsBindInfo48 *info48;
                        info48 = &b->req.out.bind_info->info.info48;
@@ -237,9 +259,15 @@ static bool _test_DsBind(struct torture_context *tctx,
                        b->peer_bind_info28.repl_epoch          = info48->repl_epoch;
                        break;
                }
-               case 28:
-                       b->peer_bind_info28 = b->req.out.bind_info->info.info28;
+               case 52: {
+                       struct drsuapi_DsBindInfo52 *info52;
+                       info52 = &b->req.out.bind_info->info.info52;
+                       b->peer_bind_info28.supported_extensions= info52->supported_extensions;
+                       b->peer_bind_info28.site_guid           = info52->site_guid;
+                       b->peer_bind_info28.pid                 = info52->pid;
+                       b->peer_bind_info28.repl_epoch          = info52->repl_epoch;
                        break;
+               }
                default:
                        printf("DsBind - warning: unknown BindInfo length: %u\n",
                               b->req.out.bind_info->length);
@@ -270,10 +298,7 @@ static bool test_LDAPBind(struct torture_context *tctx, struct DsSyncTest *ctx,
                return NULL;
        }
 
-       ldb_set_modules_dir(ldb,
-                           talloc_asprintf(ldb,
-                                           "%s/ldb",
-                                           lpcfg_modulesdir(tctx->lp_ctx)));
+       ldb_set_modules_dir(ldb, modules_path(ldb, "ldb"));
 
        if (ldb_set_opaque(ldb, "credentials", credentials)) {
                talloc_free(ldb);
@@ -321,6 +346,8 @@ static bool test_analyse_objects(struct torture_context *tctx,
                                 const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr,
                                 uint32_t object_count,
                                 const struct drsuapi_DsReplicaObjectListItemEx *first_object,
+                                uint32_t linked_attributes_count,
+                                const struct drsuapi_DsReplicaLinkedAttribute *linked_attributes,
                                 const DATA_BLOB *gensec_skey)
 {
        static uint32_t object_id;
@@ -333,6 +360,9 @@ static bool test_analyse_objects(struct torture_context *tctx,
        struct dsdb_extended_replicated_objects *objs;
        struct ldb_extended_dn_control *extended_dn_ctrl;
        struct dsdb_schema *ldap_schema;
+       struct ldb_dn *partition_dn = ldb_dn_new(tctx, ldb, partition);
+
+       torture_assert_not_null(tctx, partition_dn, "Failed to parse partition DN as as DN");
 
        /* load dsdb_schema using remote prefixMap */
        torture_assert(tctx,
@@ -342,13 +372,15 @@ static bool test_analyse_objects(struct torture_context *tctx,
 
        status = dsdb_replicated_objects_convert(ldb,
                                                 ldap_schema,
-                                                partition,
+                                                partition_dn,
                                                 mapping_ctr,
                                                 object_count,
                                                 first_object,
-                                                0, NULL,
+                                                linked_attributes_count,
+                                                linked_attributes,
                                                 NULL, NULL,
                                                 gensec_skey,
+                                                0,
                                                 ctx, &objs);
        torture_assert_werr_ok(tctx, status, "dsdb_extended_replicated_objects_convert() failed!");
 
@@ -358,14 +390,17 @@ static bool test_analyse_objects(struct torture_context *tctx,
        deleted_dn = ldb_dn_new(objs, ldb, partition);
        ldb_dn_add_child_fmt(deleted_dn, "CN=Deleted Objects");
 
-       for (i=0; i < object_count; i++) {
+       for (i=0; i < objs->num_objects; i++) {
                struct ldb_request *search_req;
                struct ldb_result *res;
                struct ldb_message *new_msg, *drs_msg, *ldap_msg;
-               const char **attrs = talloc_array(objs, const char *, objs->objects[i].msg->num_elements+1);
+               size_t num_attrs = objs->objects[i].msg->num_elements+1+1;
+               const char **attrs = talloc_array(objs, const char *, num_attrs);
                for (j=0; j < objs->objects[i].msg->num_elements; j++) {
                        attrs[j] = objs->objects[i].msg->elements[j].name;
                }
+               attrs[j] = "uSNChanged";
+               j++;
                attrs[j] = NULL;
                res = talloc_zero(objs, struct ldb_result);
                if (!res) {
@@ -389,6 +424,11 @@ static bool test_analyse_objects(struct torture_context *tctx,
                        return false;
                }
 
+               ret = ldb_request_add_control(search_req, LDB_CONTROL_SHOW_RECYCLED_OID, false, NULL);
+               if (ret != LDB_SUCCESS) {
+                       return false;
+               }
+
                ret = ldb_request_add_control(search_req, LDB_CONTROL_EXTENDED_DN_OID, true, extended_dn_ctrl);
                if (ret != LDB_SUCCESS) {
                        return false;
@@ -405,6 +445,16 @@ static bool test_analyse_objects(struct torture_context *tctx,
                                                         ldb_errstring(ldb)));
                torture_assert_int_equal(tctx, res->count, 1, "Could not re-fetch object just delivered over DRS");
                ldap_msg = res->msgs[0];
+
+{
+uint64_t usn = ldb_msg_find_attr_as_int64(ldap_msg, "uSNChanged", 0);
+struct GUID g;
+GUID_from_ndr_blob(&objs->objects[i].guid_value, &g);
+torture_comment(tctx, "o[%d] usn_changed[%llu]: %s - %s\n", i, (unsigned long long)usn,
+       GUID_string(objs, &g),
+               ldb_dn_get_linearized(objs->objects[i].msg->dn));
+continue;
+}
                for (j=0; j < ldap_msg->num_elements; j++) {
                        ldap_msg->elements[j].flags = LDB_FLAG_MOD_ADD;
                        /* For unknown reasons, there is no nTSecurityDescriptor on cn=deleted objects over LDAP, but there is over DRS!  Skip it on both transports for now here so */
@@ -435,6 +485,7 @@ static bool test_analyse_objects(struct torture_context *tctx,
                                j--;
                        } else if (ldb_attr_cmp(drs_msg->elements[j].name, "unicodePwd") == 0 ||
                                   ldb_attr_cmp(drs_msg->elements[j].name, "dBCSPwd") == 0 ||
+                                  ldb_attr_cmp(drs_msg->elements[j].name, "userPassword") == 0 ||
                                   ldb_attr_cmp(drs_msg->elements[j].name, "ntPwdHistory") == 0 ||
                                   ldb_attr_cmp(drs_msg->elements[j].name, "lmPwdHistory") == 0 ||
                                   ldb_attr_cmp(drs_msg->elements[j].name, "supplementalCredentials") == 0 ||
@@ -511,6 +562,12 @@ static bool test_analyse_objects(struct torture_context *tctx,
                talloc_free(search_req);
        }
 
+       for (i=0; i < objs->linked_attributes_count; i++) {
+torture_comment(tctx, "l[%d] usn_changed[%llu]: attid[%u] %s\n", i,
+       (unsigned long long)objs->linked_attributes[i].meta_data.originating_usn,
+       objs->linked_attributes[i].attid,
+       GUID_string(objs, &objs->linked_attributes[i].identifier->guid));
+       }
        if (!lpcfg_parm_bool(tctx->lp_ctx, NULL, "dssync", "print_pwd_blobs", false)) {
                talloc_free(objs);
                return true;
@@ -520,17 +577,11 @@ static bool test_analyse_objects(struct torture_context *tctx,
 
        for (cur = first_object; cur; cur = cur->next_object) {
                const char *dn;
-               struct dom_sid *sid = NULL;
-               uint32_t rid = 0;
                bool dn_printed = false;
 
                if (!cur->object.identifier) continue;
 
                dn = cur->object.identifier->dn;
-               if (cur->object.identifier->sid.num_auths > 0) {
-                       sid = &cur->object.identifier->sid;
-                       rid = sid->sub_auths[sid->num_auths - 1];
-               }
 
                for (i=0; i < cur->object.attribute_ctr.num_attributes; i++) {
                        const char *name = NULL;
@@ -665,6 +716,29 @@ static bool test_GetNCChanges(struct torture_context *tctx,
                }
        };
 
+       struct drsuapi_DsReplicaCursorCtrEx utdv;
+       struct drsuapi_DsReplicaCursor cursors[1];
+
+       ZERO_STRUCT(utdv);
+       utdv.version = 1;
+       utdv.count = ARRAY_SIZE(cursors);
+       utdv.cursors = cursors;
+       ZERO_STRUCT(cursors);
+       GUID_from_string("0d36ca05-5507-4e62-aca3-354bab0d39e1",
+                       &cursors[0].source_dsa_invocation_id);
+       cursors[0].highest_usn = 12755;
+/*
+                    uptodateness_vector      : *
+                        uptodateness_vector: struct drsuapi_DsReplicaCursorCtrEx
+                            version                  : 0x00000001 (1)
+                            reserved1                : 0x00000000 (0)
+                            count                    : 0x00000001 (1)
+                            reserved2                : 0x00000000 (0)
+                            cursors: ARRAY(1)
+                                cursors: struct drsuapi_DsReplicaCursor
+                                    source_dsa_invocation_id : 0d36ca05-5507-4e62-aca3-354bab0d39e1
+                                    highest_usn              : 0x00000000000031d3 (12755)
+*/
        ZERO_STRUCT(null_guid);
        ZERO_STRUCT(null_sid);
 
@@ -680,7 +754,7 @@ static bool test_GetNCChanges(struct torture_context *tctx,
                }
        }
        status = gensec_session_key(ctx->new_dc.drsuapi.drs_pipe->conn->security_state.generic_state,
-                                   &gensec_skey);
+                                   ctx, &gensec_skey);
        if (!NT_STATUS_IS_OK(status)) {
                printf("failed to get gensec session key: %s\n", nt_errstr(status));
                return false;
@@ -738,7 +812,7 @@ static bool test_GetNCChanges(struct torture_context *tctx,
                        r.in.req->req8.highwatermark.tmp_highest_usn    = highest_usn;
                        r.in.req->req8.highwatermark.reserved_usn       = 0;
                        r.in.req->req8.highwatermark.highest_usn        = highest_usn;
-                       r.in.req->req8.uptodateness_vector              = NULL;
+                       r.in.req->req8.uptodateness_vector              = NULL;//&utdv;
                        r.in.req->req8.replica_flags                    = 0;
                        if (lpcfg_parm_bool(tctx->lp_ctx, NULL, "dssync", "compression", false)) {
                                r.in.req->req8.replica_flags            |= DRSUAPI_DRS_USE_COMPRESSION;
@@ -751,6 +825,8 @@ static bool test_GetNCChanges(struct torture_context *tctx,
                                                                        | DRSUAPI_DRS_GET_ANC
                                                                        | DRSUAPI_DRS_NEVER_SYNCED
                                                                        ;
+                       r.in.req->req8.replica_flags = 0x00201074;
+                       //r.in.req->req8.replica_flags |= DRSUAPI_DRS_GET_ANC;
                        r.in.req->req8.max_object_count                 = 402;
                        r.in.req->req8.max_ndr_size                     = 402116;
 
@@ -810,7 +886,7 @@ static bool test_GetNCChanges(struct torture_context *tctx,
                                                (unsigned long long) ctr1->new_highwatermark.highest_usn);
 
                                if (!test_analyse_objects(tctx, ctx, nc_dn_str, &ctr1->mapping_ctr,  ctr1->object_count,
-                                                         ctr1->first_object, &gensec_skey)) {
+                                                         ctr1->first_object, 0, NULL, &gensec_skey)) {
                                        return false;
                                }
 
@@ -845,7 +921,10 @@ static bool test_GetNCChanges(struct torture_context *tctx,
                                                (unsigned long long) ctr6->new_highwatermark.highest_usn);
 
                                if (!test_analyse_objects(tctx, ctx, nc_dn_str, &ctr6->mapping_ctr,  ctr6->object_count,
-                                                         ctr6->first_object, &gensec_skey)) {
+                                                         ctr6->first_object,
+                                                         ctr6->linked_attributes_count,
+                                                         ctr6->linked_attributes,
+                                                         &gensec_skey)) {
                                        return false;
                                }
 
@@ -1036,15 +1115,13 @@ static bool torture_dssync_tcase_teardown(struct torture_context *tctx, void *da
 void torture_drs_rpc_dssync_tcase(struct torture_suite *suite)
 {
        typedef bool (*run_func) (struct torture_context *test, void *tcase_data);
-
-       struct torture_test *test;
-       struct torture_tcase *tcase = torture_suite_add_tcase(suite, "DSSYNC");
+       struct torture_tcase *tcase = torture_suite_add_tcase(suite, "dssync");
 
        torture_tcase_set_fixture(tcase,
                                  torture_dssync_tcase_setup,
                                  torture_dssync_tcase_teardown);
 
-       test = torture_tcase_add_simple_test(tcase, "DC_FetchData", (run_func)test_FetchData);
-       test = torture_tcase_add_simple_test(tcase, "FetchNT4Data", (run_func)test_FetchNT4Data);
+       torture_tcase_add_simple_test(tcase, "DC_FetchData", (run_func)test_FetchData);
+       torture_tcase_add_simple_test(tcase, "FetchNT4Data", (run_func)test_FetchNT4Data);
 }