r25026: Move param/param.h out of includes.h
[jelmer/samba4-debian.git] / source / torture / rpc / drsuapi.c
index 75efff89b3ba8528e660ff48c3f8d9eef2a1f9e5..c3ec54cbcdbe6ac5b6eaad921e2ad4ac767d365d 100644 (file)
@@ -5,11 +5,11 @@
 
    Copyright (C) Andrew Tridgell 2003
    Copyright (C) Stefan (metze) Metzmacher 2004
-   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2006
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 #include "torture/torture.h"
-#include "librpc/gen_ndr/ndr_drsuapi.h"
 #include "librpc/gen_ndr/ndr_drsuapi_c.h"
 #include "torture/rpc/rpc.h"
+#include "dlinklist.h"
+#include "param/param.h"
 
-BOOL test_DsBind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+#define TEST_MACHINE_NAME "torturetest"
+
+bool test_DsBind(struct dcerpc_pipe *p, struct torture_context *tctx,
                 struct DsPrivate *priv)
 {
        NTSTATUS status;
        struct drsuapi_DsBind r;
-       BOOL ret = True;
+       struct torture_rpc_tcase_data *rpc_tcase;
 
        GUID_from_string(DRSUAPI_DS_BIND_GUID, &priv->bind_guid);
 
@@ -41,213 +43,245 @@ BOOL test_DsBind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        r.in.bind_info = NULL;
        r.out.bind_handle = &priv->bind_handle;
 
-       printf("testing DsBind\n");
+       status = dcerpc_drsuapi_DsBind(p, tctx, &r);
+       torture_assert_ntstatus_ok(tctx, status, "DsBind");
+       torture_assert_werr_ok(tctx, r.out.result, "DsBind");
 
-       status = dcerpc_drsuapi_DsBind(p, mem_ctx, &r);
-       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(mem_ctx, p->last_fault_code);
-               }
-               printf("dcerpc_drsuapi_DsBind failed - %s\n", errstr);
-               ret = False;
-       } else if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("DsBind failed - %s\n", win_errstr(r.out.result));
-               ret = False;
-       }
+       rpc_tcase = (struct torture_rpc_tcase_data *)tctx->active_tcase->data;
 
-       return ret;
+       priv->join = rpc_tcase->join_ctx;
+
+       return true;
 }
 
-static BOOL test_DsGetDCInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
-                     struct DsPrivate *priv)
+bool test_DsUnbind(struct dcerpc_pipe *p, struct torture_context *tctx,
+                  struct DsPrivate *priv)
 {
        NTSTATUS status;
-       struct drsuapi_DsGetDomainControllerInfo r;
-       BOOL ret = True;
+       struct drsuapi_DsUnbind r;
 
        r.in.bind_handle = &priv->bind_handle;
-       r.in.level = 1;
+       r.out.bind_handle = &priv->bind_handle;
 
-       r.in.req.req1.domain_name = talloc_strdup(mem_ctx, lp_realm());
-       r.in.req.req1.level = 1;
+       status = dcerpc_drsuapi_DsUnbind(p, tctx, &r);
+       torture_assert_ntstatus_ok(tctx, status,
+                       "dcerpc_drsuapi_DsUnbind failed");
+       torture_assert_werr_ok(tctx, r.out.result, "DsBind failed");
 
-       printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
-                       r.in.req.req1.level, r.in.req.req1.domain_name);
+       return true;
+}
 
-       status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
-       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(mem_ctx, p->last_fault_code);
-               }
-               printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
-                       "    with dns domain failed - %s\n",
-                       r.in.req.req1.level, errstr);
-               ret = False;
-       } else if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("DsGetDomainControllerInfo level %d\n"
-                       "    with dns domain failed - %s\n",
-                       r.in.req.req1.level, win_errstr(r.out.result));
-               ret = False;
-       }
+static bool wrap_test_drsuapi(struct torture_context *tctx, 
+                             struct torture_tcase *tcase,
+                             struct torture_test *test)
+{
+       bool (*fn) (struct torture_context *, struct dcerpc_pipe *, struct DsPrivate *);
+       struct torture_rpc_tcase_data *tcase_data = 
+               (struct torture_rpc_tcase_data *)tcase->data;
+       bool ret;
+       struct DsPrivate priv;
 
-       r.in.req.req1.level = 2;
+       ZERO_STRUCT(priv);
 
-       printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
-                       r.in.req.req1.level, r.in.req.req1.domain_name);
+       fn = test->fn;
 
-       status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
-       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(mem_ctx, p->last_fault_code);
-               }
-               printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
-                       "    with dns domain failed - %s\n",
-                       r.in.req.req1.level, errstr);
-               ret = False;
-       } else if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("DsGetDomainControllerInfo level %d\n"
-                       "    with dns domain failed - %s\n",
-                       r.in.req.req1.level, win_errstr(r.out.result));
-               ret = False;
-       } else {
-               if (r.out.ctr.ctr2.count > 0) {
-                       priv->dcinfo    = r.out.ctr.ctr2.array[0];
-               }
-       }
+       if (!test_DsBind(tcase_data->pipe, tctx, &priv))
+               return false;
 
-       r.in.req.req1.level = -1;
+       ret = fn(tctx, tcase_data->pipe, &priv);
+       
+       if (!test_DsUnbind(tcase_data->pipe, tctx, &priv))
+               return false;
 
-       printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
-                       r.in.req.req1.level, r.in.req.req1.domain_name);
+       return ret;
+}
 
-       status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
-       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(mem_ctx, p->last_fault_code);
-               }
-               printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
-                       "    with dns domain failed - %s\n",
-                       r.in.req.req1.level, errstr);
-               ret = False;
-       } else if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("DsGetDomainControllerInfo level %d\n"
-                       "    with dns domain failed - %s\n",
-                       r.in.req.req1.level, win_errstr(r.out.result));
-               ret = False;
-       }
+static struct torture_test *torture_rpc_tcase_add_drsuapi_test(
+                                       struct torture_rpc_tcase *tcase, 
+                                       const char *name, 
+                                       bool (*fn) (struct torture_context *, struct dcerpc_pipe *, struct DsPrivate *priv))
+{
+       struct torture_test *test;
 
-       r.in.req.req1.domain_name = talloc_strdup(mem_ctx, lp_workgroup());
-       r.in.req.req1.level = 2;
+       test = talloc(tcase, struct torture_test);
 
-       printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
-                       r.in.req.req1.level, r.in.req.req1.domain_name);
+       test->name = talloc_strdup(test, name);
+       test->description = NULL;
+       test->run = wrap_test_drsuapi;
+       test->dangerous = false;
+       test->data = NULL;
+       test->fn = fn;
 
-       status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
-       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(mem_ctx, p->last_fault_code);
-               }
-               printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
-                       "    with netbios domain failed - %s\n",
-                       r.in.req.req1.level, errstr);
-               ret = False;
-       } else if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("DsGetDomainControllerInfo level %d\n"
-                       "    with netbios domain failed - %s\n",
-                       r.in.req.req1.level, win_errstr(r.out.result));
-               ret = False;
-       }
+       DLIST_ADD(tcase->tcase.tests, test);
 
-       r.in.req.req1.domain_name = "__UNKNOWN_DOMAIN__";
-       r.in.req.req1.level = 2;
+       return test;
+}
 
-       printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
-                       r.in.req.req1.level, r.in.req.req1.domain_name);
+static bool test_DsGetDomainControllerInfo(struct torture_context *torture, 
+                                          struct dcerpc_pipe *p, 
+                                          struct DsPrivate *priv)
+{
+       NTSTATUS status;
+       struct drsuapi_DsGetDomainControllerInfo r;
+       bool found = false;
+       int i, j, k;
+       
+       struct {
+               const char *name;
+               WERROR expected;
+       } names[] = { 
+               {       
+                       .name = torture_join_dom_netbios_name(priv->join),
+                       .expected = WERR_OK
+               },
+               {
+                       .name = torture_join_dom_dns_name(priv->join),
+                       .expected = WERR_OK
+               },
+               {
+                       .name = "__UNKNOWN_DOMAIN__",
+                       .expected = WERR_DS_OBJ_NOT_FOUND
+               },
+               {
+                       .name = "unknown.domain.samba.example.com",
+                       .expected = WERR_DS_OBJ_NOT_FOUND
+               },
+       };
+       int levels[] = {1, 2};
+       int level;
+
+       for (i=0; i < ARRAY_SIZE(levels); i++) {
+               for (j=0; j < ARRAY_SIZE(names); j++) {
+                       level = levels[i];
+                       r.in.bind_handle = &priv->bind_handle;
+                       r.in.level = 1;
+                       
+                       r.in.req.req1.domain_name = names[j].name;
+                       r.in.req.req1.level = level;
+                       
+                       torture_comment(torture,
+                                  "testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
+                              r.in.req.req1.level, r.in.req.req1.domain_name);
+               
+                       status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, torture, &r);
+                       torture_assert_ntstatus_ok(torture, status,
+                                  "dcerpc_drsuapi_DsGetDomainControllerInfo with dns domain failed");
+                       torture_assert_werr_equal(torture, 
+                                                                         r.out.result, names[j].expected, 
+                                          "DsGetDomainControllerInfo level with dns domain failed");
+               
+                       if (!W_ERROR_IS_OK(r.out.result)) {
+                               /* If this was an error, we can't read the result structure */
+                               continue;
+                       }
 
-       status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
-       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(mem_ctx, p->last_fault_code);
+                       torture_assert_int_equal(torture, 
+                                                r.in.req.req1.level, r.out.level_out, 
+                                                "dcerpc_drsuapi_DsGetDomainControllerInfo level"); 
+
+                       switch (level) {
+                       case 1:
+                               for (k=0; k < r.out.ctr.ctr1.count; k++) {
+                                       if (strcasecmp_m(r.out.ctr.ctr1.array[k].netbios_name, 
+                                                        torture_join_netbios_name(priv->join)) == 0) {
+                                               found = true;
+                                               break;
+                                       }
+                               }
+                               break;
+                       case 2:
+                               for (k=0; k < r.out.ctr.ctr2.count; k++) {
+                                       if (strcasecmp_m(r.out.ctr.ctr2.array[k].netbios_name, 
+                                                        torture_join_netbios_name(priv->join)) == 0) {
+                                               found = true;
+                                               priv->dcinfo    = r.out.ctr.ctr2.array[k];
+                                               break;
+                                       }
+                               }
+                               break;
+                       }
+                       torture_assert(torture, found,
+                                "dcerpc_drsuapi_DsGetDomainControllerInfo: Failed to find the domain controller we just created during the join");
                }
-               printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
-                       "    with invalid domain failed - %s\n",
-                       r.in.req.req1.level, errstr);
-               ret = False;
-       } else if (!W_ERROR_EQUAL(r.out.result, WERR_DS_OBJ_NOT_FOUND)) {
-               printf("DsGetDomainControllerInfo level %d\n"
-                       "    with invalid domain not expected error (WERR_DS_OBJ_NOT_FOUND) - %s\n",
-                       r.in.req.req1.level, win_errstr(r.out.result));
-               ret = False;
        }
 
-       return ret;
+       r.in.bind_handle = &priv->bind_handle;
+       r.in.level = 1;
+       
+       r.in.req.req1.domain_name = "__UNKNOWN_DOMAIN__"; /* This is clearly ignored for this level */
+       r.in.req.req1.level = -1;
+       
+       torture_comment(torture,
+               "testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
+              r.in.req.req1.level, r.in.req.req1.domain_name);
+       
+       status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, torture, &r);
+
+       torture_assert_ntstatus_ok(torture, status, 
+                       "dcerpc_drsuapi_DsGetDomainControllerInfo with dns domain failed");
+       torture_assert_werr_ok(torture, r.out.result, 
+                          "DsGetDomainControllerInfo with dns domain failed");
+       
+       {
+               const char *dc_account = talloc_asprintf(torture, "%s\\%s$",
+                                                        torture_join_dom_netbios_name(priv->join), 
+                                                        priv->dcinfo.netbios_name);
+               for (k=0; k < r.out.ctr.ctr01.count; k++) {
+                       if (strcasecmp_m(r.out.ctr.ctr01.array[k].client_account, 
+                                        dc_account)) {
+                               found = true;
+                               break;
+                       }
+               }
+               torture_assert(torture, found,
+                       "dcerpc_drsuapi_DsGetDomainControllerInfo level: Failed to find the domain controller in last logon records");
+       }
+
+
+       return true;
 }
 
-static BOOL test_DsWriteAccountSpn(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
-                       struct DsPrivate *priv)
+static bool test_DsWriteAccountSpn(struct torture_context *tctx, 
+                                  struct dcerpc_pipe *p, 
+                                  struct DsPrivate *priv)
 {
        NTSTATUS status;
        struct drsuapi_DsWriteAccountSpn r;
        struct drsuapi_DsNameString names[2];
-       BOOL ret = True;
 
        r.in.bind_handle                = &priv->bind_handle;
        r.in.level                      = 1;
 
-       printf("testing DsWriteAccountSpn\n");
-
        r.in.req.req1.operation = DRSUAPI_DS_SPN_OPERATION_ADD;
        r.in.req.req1.unknown1  = 0;
        r.in.req.req1.object_dn = priv->dcinfo.computer_dn;
        r.in.req.req1.count     = 2;
        r.in.req.req1.spn_names = names;
-       names[0].str = talloc_asprintf(mem_ctx, "smbtortureSPN/%s",priv->dcinfo.netbios_name);
-       names[1].str = talloc_asprintf(mem_ctx, "smbtortureSPN/%s",priv->dcinfo.dns_name);
-
-       status = dcerpc_drsuapi_DsWriteAccountSpn(p, mem_ctx, &r);
-       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(mem_ctx, p->last_fault_code);
-               }
-               printf("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr);
-               ret = False;
-       } else if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("DsWriteAccountSpn failed - %s\n", win_errstr(r.out.result));
-               ret = False;
-       }
+       names[0].str = talloc_asprintf(tctx, "smbtortureSPN/%s",priv->dcinfo.netbios_name);
+       names[1].str = talloc_asprintf(tctx, "smbtortureSPN/%s",priv->dcinfo.dns_name);
+
+       status = dcerpc_drsuapi_DsWriteAccountSpn(p, tctx, &r);
+       torture_assert_ntstatus_ok(tctx, status, 
+               "dcerpc_drsuapi_DsWriteAccountSpn failed");
+       torture_assert_werr_ok(tctx, r.out.result, "DsWriteAccountSpn failed");
 
        r.in.req.req1.operation = DRSUAPI_DS_SPN_OPERATION_DELETE;
        r.in.req.req1.unknown1  = 0;
 
-       status = dcerpc_drsuapi_DsWriteAccountSpn(p, mem_ctx, &r);
-       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(mem_ctx, p->last_fault_code);
-               }
-               printf("dcerpc_drsuapi_DsWriteAccountSpn failed - %s\n", errstr);
-               ret = False;
-       } else if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("DsWriteAccountSpn failed - %s\n", win_errstr(r.out.result));
-               ret = False;
-       }
+       status = dcerpc_drsuapi_DsWriteAccountSpn(p, tctx, &r);
+       torture_assert_ntstatus_ok(tctx, status, 
+               "dcerpc_drsuapi_DsWriteAccountSpn failed");
+       torture_assert_werr_ok(tctx, r.out.result, "DsWriteAccountSpn failed");
 
-       return ret;
+       return true;
 }
 
-static BOOL test_DsReplicaGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
-                       struct DsPrivate *priv)
+static bool test_DsReplicaGetInfo(struct torture_context *tctx, 
+                                 struct dcerpc_pipe *p, 
+                                 struct DsPrivate *priv)
 {
        NTSTATUS status;
        struct drsuapi_DsReplicaGetInfo r;
-       BOOL ret = True;
        int i;
        struct {
                int32_t level;
@@ -308,7 +342,7 @@ static BOOL test_DsReplicaGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                        "__IGNORED__"
                },{
                        DRSUAPI_DS_REPLICA_GET_INFO2,
-                       DRSUAPI_DS_REPLICA_INFO_CURSURS05,
+                       DRSUAPI_DS_REPLICA_INFO_CURSORS05,
                        NULL
                },{
                        DRSUAPI_DS_REPLICA_GET_INFO2,
@@ -322,7 +356,8 @@ static BOOL test_DsReplicaGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        for (i=0; i < ARRAY_SIZE(array); i++) {
                const char *object_dn;
 
-               printf("testing DsReplicaGetInfo level %d infotype %d\n",
+               torture_comment(tctx, 
+                       "testing DsReplicaGetInfo level %d infotype %d\n",
                        array[i].level, array[i].infotype);
 
                object_dn = (array[i].obj_dn ? array[i].obj_dn : priv->domain_obj_dn);
@@ -345,33 +380,21 @@ static BOOL test_DsReplicaGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                        break;
                }
 
-               status = dcerpc_drsuapi_DsReplicaGetInfo(p, mem_ctx, &r);
-               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(mem_ctx, p->last_fault_code);
-                       }
-                       if (p->last_fault_code != DCERPC_FAULT_INVALID_TAG) {
-                               printf("dcerpc_drsuapi_DsReplicaGetInfo failed - %s\n", errstr);
-                               ret = False;
-                       } else {
-                               printf("DsReplicaGetInfo level %d and/or infotype %d not supported by server\n",
-                                       array[i].level, array[i].infotype);
-                       }
-               } else if (!W_ERROR_IS_OK(r.out.result)) {
-                       printf("DsReplicaGetInfo failed - %s\n", win_errstr(r.out.result));
-                       ret = False;
-               }
+               status = dcerpc_drsuapi_DsReplicaGetInfo(p, tctx, &r);
+               torture_assert_ntstatus_ok(tctx, status, 
+                       "dcerpc_drsuapi_DsReplicaGetInfo failed");
+               torture_assert_werr_ok(tctx, r.out.result, 
+                                      "DsReplicaGetInfo failed");
        }
 
-       return ret;
+       return true;
 }
 
-static BOOL test_DsReplicaSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
-                       struct DsPrivate *priv)
+static bool test_DsReplicaSync(struct torture_context *tctx,
+                              struct dcerpc_pipe *p, 
+                              struct DsPrivate *priv)
 {
        NTSTATUS status;
-       BOOL ret = True;
        int i;
        struct drsuapi_DsReplicaSync r;
        struct drsuapi_DsReplicaObjectIdentifier nc;
@@ -385,19 +408,14 @@ static BOOL test_DsReplicaSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                }
        };
 
-       if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
-               printf("DsReplicaSync disabled - enable dangerous tests to use\n");
-               return True;
-       }
-
        ZERO_STRUCT(null_guid);
        ZERO_STRUCT(null_sid);
 
        r.in.bind_handle        = &priv->bind_handle;
 
        for (i=0; i < ARRAY_SIZE(array); i++) {
-               printf("testing DsReplicaSync level %d\n",
-                       array[i].level);
+               torture_comment(tctx, "testing DsReplicaSync level %d\n",
+                               array[i].level);
 
                r.in.level = array[i].level;
                switch(r.in.level) {
@@ -407,34 +425,27 @@ static BOOL test_DsReplicaSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                        nc.dn                                   = priv->domain_obj_dn?priv->domain_obj_dn:"";
 
                        r.in.req.req1.naming_context            = &nc;
-                       r.in.req.req1.guid1                     = priv->dcinfo.ntds_guid;
-                       r.in.req.req1.string1                   = NULL;
+                       r.in.req.req1.source_dsa_guid           = priv->dcinfo.ntds_guid;
+                       r.in.req.req1.other_info                = NULL;
                        r.in.req.req1.options                   = 16;
                        break;
                }
 
-               status = dcerpc_drsuapi_DsReplicaSync(p, mem_ctx, &r);
-               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(mem_ctx, p->last_fault_code);
-                       }
-                       printf("dcerpc_drsuapi_DsReplicaSync failed - %s\n", errstr);
-                       ret = False;
-               } else if (!W_ERROR_IS_OK(r.out.result)) {
-                       printf("DsReplicaSync failed - %s\n", win_errstr(r.out.result));
-                       ret = False;
-               }
+               status = dcerpc_drsuapi_DsReplicaSync(p, tctx, &r);
+               torture_assert_ntstatus_ok(tctx, status, 
+                       "dcerpc_drsuapi_DsReplicaSync failed");
+               torture_assert_werr_ok(tctx, r.out.result, 
+                                      "DsReplicaSync failed");
        }
 
-       return ret;
+       return true;
 }
 
-static BOOL test_DsReplicaUpdateRefs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
-                       struct DsPrivate *priv)
+static bool test_DsReplicaUpdateRefs(struct torture_context *tctx, 
+                                    struct dcerpc_pipe *p, 
+                                    struct DsPrivate *priv)
 {
        NTSTATUS status;
-       BOOL ret = True;
        int i;
        struct drsuapi_DsReplicaUpdateRefs r;
        struct drsuapi_DsReplicaObjectIdentifier nc;
@@ -454,7 +465,7 @@ static BOOL test_DsReplicaUpdateRefs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        r.in.bind_handle        = &priv->bind_handle;
 
        for (i=0; i < ARRAY_SIZE(array); i++) {
-               printf("testing DsReplicaUpdateRefs level %d\n",
+               torture_comment(tctx, "testing DsReplicaUpdateRefs level %d\n",
                        array[i].level);
 
                r.in.level = array[i].level;
@@ -465,35 +476,28 @@ static BOOL test_DsReplicaUpdateRefs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                        nc.dn                           = priv->domain_obj_dn?priv->domain_obj_dn:"";
 
                        r.in.req.req1.naming_context    = &nc;
-                       r.in.req.req1.dest_dsa_dns_name = talloc_asprintf(mem_ctx, "__some_dest_dsa_guid_string._msdn.%s",
+                       r.in.req.req1.dest_dsa_dns_name = talloc_asprintf(tctx, "__some_dest_dsa_guid_string._msdn.%s",
                                                                                priv->domain_dns_name);
                        r.in.req.req1.dest_dsa_guid     = null_guid;
                        r.in.req.req1.options           = 0;
                        break;
                }
 
-               status = dcerpc_drsuapi_DsReplicaUpdateRefs(p, mem_ctx, &r);
-               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(mem_ctx, p->last_fault_code);
-                       }
-                       printf("dcerpc_drsuapi_DsReplicaUpdateRefs failed - %s\n", errstr);
-                       ret = False;
-               } else if (!W_ERROR_IS_OK(r.out.result)) {
-                       printf("DsReplicaUpdateRefs failed - %s\n", win_errstr(r.out.result));
-                       ret = False;
-               }
+               status = dcerpc_drsuapi_DsReplicaUpdateRefs(p, tctx, &r);
+               torture_assert_ntstatus_ok(tctx, status, 
+                       "dcerpc_drsuapi_DsReplicaUpdateRefs failed");
+               torture_assert_werr_ok(tctx, r.out.result, 
+                       "DsReplicaUpdateRefs failed");
        }
 
-       return ret;
+       return true;
 }
 
-static BOOL test_DsGetNCChanges(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
-                       struct DsPrivate *priv)
+static bool test_DsGetNCChanges(struct torture_context *tctx, 
+                               struct dcerpc_pipe *p, 
+                               struct DsPrivate *priv)
 {
        NTSTATUS status;
-       BOOL ret = True;
        int i;
        struct drsuapi_DsGetNCChanges r;
        struct drsuapi_DsReplicaObjectIdentifier nc;
@@ -514,31 +518,31 @@ static BOOL test_DsGetNCChanges(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        ZERO_STRUCT(null_sid);
 
        for (i=0; i < ARRAY_SIZE(array); i++) {
-               printf("testing DsGetNCChanges level %d\n",
+               torture_comment(tctx, "testing DsGetNCChanges level %d\n",
                        array[i].level);
 
                r.in.bind_handle        = &priv->bind_handle;
-               r.in.level              = array[i].level;
+               r.in.level              = &array[i].level;
 
-               switch (r.in.level) {
+               switch (*r.in.level) {
                case 5:
                        nc.guid = null_guid;
                        nc.sid  = null_sid;
                        nc.dn   = priv->domain_obj_dn?priv->domain_obj_dn:"";
 
                        r.in.req.req5.destination_dsa_guid              = GUID_random();
-                       r.in.req.req5.source_dsa_guid                   = null_guid;
+                       r.in.req.req5.source_dsa_invocation_id          = null_guid;
                        r.in.req.req5.naming_context                    = &nc;
                        r.in.req.req5.highwatermark.tmp_highest_usn     = 0;
                        r.in.req.req5.highwatermark.reserved_usn        = 0;
                        r.in.req.req5.highwatermark.highest_usn         = 0;
                        r.in.req.req5.uptodateness_vector               = NULL;
                        r.in.req.req5.replica_flags                     = 0;
-                       if (lp_parm_bool(-1, "drsuapi","compression", False)) {
+                       if (lp_parm_bool(-1, "drsuapi", "compression", false)) {
                                r.in.req.req5.replica_flags             |= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES;
                        }
-                       r.in.req.req5.unknown2                          = 0;
-                       r.in.req.req5.unknown3                          = 0;
+                       r.in.req.req5.max_object_count                  = 0;
+                       r.in.req.req5.max_ndr_size                      = 0;
                        r.in.req.req5.unknown4                          = 0;
                        r.in.req.req5.h1                                = 0;
 
@@ -549,17 +553,17 @@ static BOOL test_DsGetNCChanges(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                        nc.dn   = priv->domain_obj_dn?priv->domain_obj_dn:"";
 
                        r.in.req.req8.destination_dsa_guid              = GUID_random();
-                       r.in.req.req8.source_dsa_guid                   = null_guid;
+                       r.in.req.req8.source_dsa_invocation_id          = null_guid;
                        r.in.req.req8.naming_context                    = &nc;
                        r.in.req.req8.highwatermark.tmp_highest_usn     = 0;
                        r.in.req.req8.highwatermark.reserved_usn        = 0;
                        r.in.req.req8.highwatermark.highest_usn         = 0;
                        r.in.req.req8.uptodateness_vector               = NULL;
                        r.in.req.req8.replica_flags                     = 0;
-                       if (lp_parm_bool(-1,"drsuapi","compression",False)) {
+                       if (lp_parm_bool(-1, "drsuapi", "compression", false)) {
                                r.in.req.req8.replica_flags             |= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES;
                        }
-                       if (lp_parm_bool(-1,"drsuapi","neighbour_writeable",True)) {
+                       if (lp_parm_bool(-1, "drsuapi", "neighbour_writeable",true)) {
                                r.in.req.req8.replica_flags             |= DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE;
                        }
                        r.in.req.req8.replica_flags                     |= DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
@@ -567,105 +571,94 @@ static BOOL test_DsGetNCChanges(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                                                        | DRSUAPI_DS_REPLICA_NEIGHBOUR_RETURN_OBJECT_PARENTS
                                                                        | DRSUAPI_DS_REPLICA_NEIGHBOUR_NEVER_SYNCED
                                                                        ;
-                       r.in.req.req8.unknown2                          = 402;
-                       r.in.req.req8.unknown3                          = 402116;
+                       r.in.req.req8.max_object_count                  = 402;
+                       r.in.req.req8.max_ndr_size                      = 402116;
                        r.in.req.req8.unknown4                          = 0;
                        r.in.req.req8.h1                                = 0;
                        r.in.req.req8.unique_ptr1                       = 0;
                        r.in.req.req8.unique_ptr2                       = 0;
-                       r.in.req.req8.ctr12.count                       = 0;
-                       r.in.req.req8.ctr12.array                       = NULL;
+                       r.in.req.req8.mapping_ctr.num_mappings          = 0;
+                       r.in.req.req8.mapping_ctr.mappings              = NULL;
 
                        break;
                }
 
-               status = dcerpc_drsuapi_DsGetNCChanges(p, mem_ctx, &r);
-               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(mem_ctx, p->last_fault_code);
-                       }
-                       printf("dcerpc_drsuapi_DsGetNCChanges failed - %s\n", errstr);
-                       ret = False;
-               } else if (!W_ERROR_IS_OK(r.out.result)) {
-                       printf("DsGetNCChanges failed - %s\n", win_errstr(r.out.result));
-                       ret = False;
-               }
+               status = dcerpc_drsuapi_DsGetNCChanges(p, tctx, &r);
+               torture_assert_ntstatus_ok(tctx, status, 
+                       "dcerpc_drsuapi_DsGetNCChanges failed");
+               torture_assert_werr_ok(tctx, r.out.result, 
+                                      "DsGetNCChanges failed");
        }
 
-       return ret;
+       return true;
 }
 
-BOOL test_DsUnbind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx
-                  struct DsPrivate *priv)
+bool test_QuerySitesByCost(struct torture_context *tctx, struct dcerpc_pipe *p
+                          struct DsPrivate *priv)
 {
        NTSTATUS status;
-       struct drsuapi_DsUnbind r;
-       BOOL ret = True;
-
-       r.in.bind_handle = &priv->bind_handle;
-       r.out.bind_handle = &priv->bind_handle;
-
-       printf("testing DsUnbind\n");
+       struct drsuapi_QuerySitesByCost r;
 
-       status = dcerpc_drsuapi_DsUnbind(p, mem_ctx, &r);
-       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(mem_ctx, p->last_fault_code);
-               }
-               printf("dcerpc_drsuapi_DsUnbind failed - %s\n", errstr);
-               ret = False;
-       } else if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("DsBind failed - %s\n", win_errstr(r.out.result));
-               ret = False;
-       }
+       const char *my_site = "Default-First-Site-Name";
+       const char *remote_site1 = "smbtorture-nonexisting-site1";
+       const char *remote_site2 = "smbtorture-nonexisting-site2";
 
-       return ret;
+       r.in.bind_handle = &priv->bind_handle;
+       r.in.level = 1;
+       r.in.req.req1.site_from = talloc_strdup(tctx, my_site);
+       r.in.req.req1.num_req = 2;
+       r.in.req.req1.site_to = talloc_zero_array(tctx, const char *, r.in.req.req1.num_req);
+       r.in.req.req1.site_to[0] = talloc_strdup(tctx, remote_site1);
+       r.in.req.req1.site_to[1] = talloc_strdup(tctx, remote_site2);
+       r.in.req.req1.flags = 0;
+
+       status = dcerpc_drsuapi_QuerySitesByCost(p, tctx, &r);
+       torture_assert_ntstatus_ok(tctx, status, "drsuapi_QuerySitesByCost");
+       torture_assert_werr_ok(tctx, r.out.result, "QuerySitesByCost failed");
+
+       torture_assert_werr_equal(tctx, r.out.ctr.ctr1.info[0].error_code, 
+                                 WERR_DS_OBJ_NOT_FOUND, "expected not found error");
+       torture_assert_werr_equal(tctx, r.out.ctr.ctr1.info[1].error_code, 
+                                 WERR_DS_OBJ_NOT_FOUND, "expected not found error");
+
+       torture_assert_int_equal(tctx, r.out.ctr.ctr1.info[0].site_cost,
+                                (uint32_t) -1, "unexpected site cost");
+         
+       torture_assert_int_equal(tctx, r.out.ctr.ctr1.info[1].site_cost, 
+                                (uint32_t) -1, "unexpected site cost");
+
+       return true;
 }
 
-BOOL torture_rpc_drsuapi(void)
+struct torture_suite *torture_rpc_drsuapi(TALLOC_CTX *mem_ctx)
 {
-        NTSTATUS status;
-        struct dcerpc_pipe *p;
-       TALLOC_CTX *mem_ctx;
-       BOOL ret = True;
-       struct DsPrivate priv;
-
-       mem_ctx = talloc_init("torture_rpc_drsuapi");
-
-       status = torture_rpc_connection(mem_ctx, 
-                                       &p, 
-                                       &dcerpc_table_drsuapi);
-       if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(mem_ctx);
-               return False;
-       }
-
-       printf("Connected to DRAUAPI pipe\n");
-
-       ZERO_STRUCT(priv);
-
-       ret &= test_DsBind(p, mem_ctx, &priv);
-
-       ret &= test_DsGetDCInfo(p, mem_ctx, &priv);
-
-       ret &= test_DsCrackNames(p, mem_ctx, &priv, priv.dcinfo.netbios_name);
-
-       ret &= test_DsWriteAccountSpn(p, mem_ctx, &priv);
-
-       ret &= test_DsReplicaGetInfo(p, mem_ctx, &priv);
-
-       ret &= test_DsReplicaSync(p, mem_ctx, &priv);
-
-       ret &= test_DsReplicaUpdateRefs(p, mem_ctx, &priv);
-
-       ret &= test_DsGetNCChanges(p, mem_ctx, &priv);
+       struct torture_suite *suite = torture_suite_create(mem_ctx, "DRSUAPI");
+       struct torture_test *test;
+       struct torture_rpc_tcase *tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "drsuapi", 
+                                                                           &ndr_table_drsuapi, TEST_MACHINE_NAME);
+
+       torture_rpc_tcase_add_drsuapi_test(tcase, "QuerySitesByCost", test_QuerySitesByCost);
+       torture_rpc_tcase_add_drsuapi_test(tcase, "DsGetDomainControllerInfo", test_DsGetDomainControllerInfo);
+       torture_rpc_tcase_add_drsuapi_test(tcase, "DsCrackNames", test_DsCrackNames);
+       torture_rpc_tcase_add_drsuapi_test(tcase, "DsWriteAccountSpn", test_DsWriteAccountSpn);
+       torture_rpc_tcase_add_drsuapi_test(tcase, "DsReplicaGetInfo", test_DsReplicaGetInfo);
+       test = torture_rpc_tcase_add_drsuapi_test(tcase, "DsReplicaSync", test_DsReplicaSync);
+       test->dangerous = true;
+       torture_rpc_tcase_add_drsuapi_test(tcase, "DsReplicaUpdateRefs", test_DsReplicaUpdateRefs);
+       torture_rpc_tcase_add_drsuapi_test(tcase, "DsGetNCChange", test_DsGetNCChanges);
+
+       return suite;
+}
 
-       ret &= test_DsUnbind(p, mem_ctx, &priv);
+struct torture_suite *torture_rpc_drsuapi_cracknames(TALLOC_CTX *mem_ctx)
+{
+       struct torture_suite *suite = torture_suite_create(mem_ctx, "CRACKNAMES");
+       struct torture_rpc_tcase *tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "drsuapi", 
+                                                                           &ndr_table_drsuapi, TEST_MACHINE_NAME);
 
-       talloc_free(mem_ctx);
+       torture_rpc_tcase_add_drsuapi_test(tcase, "DsGetDomainControllerInfo", test_DsGetDomainControllerInfo);
+       torture_rpc_tcase_add_drsuapi_test(tcase, "DsCrackNames", test_DsCrackNames);
 
-       return ret;
+       return suite;
 }