smbtorture: Show the list of cracknames we expect to have and the result
[mat/samba.git] / source4 / torture / rpc / drsuapi_cracknames.c
index a9a614953d674a5b1583e867215b760b24150d50..f71910a3a615ee6bf2dcdf3e206e3bde77eb123d 100644 (file)
 */
 
 #include "includes.h"
-#include "torture/torture.h"
 #include "librpc/gen_ndr/ndr_drsuapi_c.h"
-#include "torture/rpc/rpc.h"
-#include "ldb/include/ldb.h"
+#include "torture/rpc/torture_rpc.h"
+#include <ldb.h>
 #include "libcli/security/security.h"
-#include "param/param.h"
 
-static bool test_DsCrackNamesMatrix(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+struct DsCrackNamesPrivate {
+       struct DsPrivate base;
+
+       /* following names are used in Crack Names Matrix test */
+       const char *fqdn_name;
+       const char *user_principal_name;
+       const char *service_principal_name;
+};
+
+static bool test_DsCrackNamesMatrix(struct torture_context *tctx,
                                    struct DsPrivate *priv, const char *dn,
                                    const char *user_principal_name, const char *service_principal_name)
 {
-       
-
        NTSTATUS status;
-       bool ret = true;
+       const char *err_msg;
        struct drsuapi_DsCrackNames r;
+       union drsuapi_DsNameRequest req;
+       uint32_t level_out;
+       union drsuapi_DsNameCtr ctr;
+       struct dcerpc_pipe *p = priv->drs_pipe;
+       TALLOC_CTX *mem_ctx = priv;
+
        enum drsuapi_DsNameFormat formats[] = {
                DRSUAPI_DS_NAME_FORMAT_UNKNOWN,
                DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
@@ -60,71 +71,74 @@ static bool test_DsCrackNamesMatrix(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        ZERO_STRUCT(r);
        r.in.bind_handle                = &priv->bind_handle;
        r.in.level                      = 1;
-       r.in.req.req1.codepage          = 1252; /* german */
-       r.in.req.req1.language          = 0x00000407; /* german */
-       r.in.req.req1.count             = 1;
-       r.in.req.req1.names             = names;
-       r.in.req.req1.format_flags      = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
+       r.in.req                        = &req;
+       r.in.req->req1.codepage         = 1252; /* german */
+       r.in.req->req1.language         = 0x00000407; /* german */
+       r.in.req->req1.count            = 1;
+       r.in.req->req1.names            = names;
+       r.in.req->req1.format_flags     = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
+
+       r.out.level_out                 = &level_out;
+       r.out.ctr                       = &ctr;
 
        n_matrix[0][0] = dn;
 
        for (i = 0; i < ARRAY_SIZE(formats); i++) {
-               r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
-               r.in.req.req1.format_desired    = formats[i];
+               r.in.req->req1.format_offered   = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
+               r.in.req->req1.format_desired   = formats[i];
                names[0].str = dn;
-               status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+               status = dcerpc_drsuapi_DsCrackNames_r(p->binding_handle, 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("testing DsCrackNames (matrix prep) with name '%s' from format: %d desired format:%d ",
-                              names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired);
-               
-                       printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
-                       ret = false;
+                       err_msg = talloc_asprintf(mem_ctx,
+                                       "testing DsCrackNames (matrix prep) with name '%s' from format: %d desired format:%d failed - %s",
+                                       names[0].str, r.in.req->req1.format_offered, r.in.req->req1.format_desired, errstr);
+                       torture_fail(tctx, err_msg);
                } else if (!W_ERROR_IS_OK(r.out.result)) {
-                       printf("testing DsCrackNames (matrix prep) with name '%s' from format: %d desired format:%d ",
-                              names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired);
-               
-                       printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
-                       ret = false;
+                       err_msg = talloc_asprintf(mem_ctx,
+                                       "testing DsCrackNames (matrix prep) with name '%s' from format: %d desired format:%d failed - %s",
+                              names[0].str, r.in.req->req1.format_offered, r.in.req->req1.format_desired, win_errstr(r.out.result));
+                       torture_fail(tctx, err_msg);
                }
                        
-               if (!ret) {
-                       return ret;
-               }
                switch (formats[i]) {
                case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL:  
-                       if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE) {
-                               printf(__location__ ": Unexpected error (%d): This name lookup should fail\n", 
-                                      r.out.ctr.ctr1->array[0].status);
-                               return false;
+                       if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE) {
+                               err_msg = talloc_asprintf(mem_ctx,
+                                               "Unexpected error (%d): This name lookup should fail",
+                                               r.out.ctr->ctr1->array[0].status);
+                               torture_fail(tctx, err_msg);
                        }
-                       printf ("(expected) error\n");
+                       torture_comment(tctx, __location__ ": (expected) error\n");
                        break;
                case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL:
-                       if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NO_MAPPING) {
-                               printf(__location__ ": Unexpected error (%d): This name lookup should fail\n", 
-                                      r.out.ctr.ctr1->array[0].status);
-                               return false;
+                       if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_NO_MAPPING) {
+                               err_msg = talloc_asprintf(mem_ctx,
+                                               "Unexpected error (%d): This name lookup should fail",
+                                               r.out.ctr->ctr1->array[0].status);
+                               torture_fail(tctx, err_msg);
                        }
-                       printf ("(expected) error\n");
+                       torture_comment(tctx, __location__ ": (expected) error\n");
                        break;
+               case DRSUAPI_DS_NAME_FORMAT_UNKNOWN:    /* should fail as we ask server to convert to Unknown format */
                case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN: 
                case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY: 
-                       if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR) {
-                               printf(__location__ ": Unexpected error (%d): This name lookup should fail\n", 
-                                      r.out.ctr.ctr1->array[0].status);
-                               return false;
+                       if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR) {
+                               err_msg = talloc_asprintf(mem_ctx,
+                                               "Unexpected error (%d): This name lookup should fail",
+                                               r.out.ctr->ctr1->array[0].status);
+                               torture_fail(tctx, err_msg);
                        }
-                       printf ("(expected) error\n");
+                       torture_comment(tctx, __location__ ": (expected) error\n");
                        break;
                default:
-                       if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
-                               printf("Error: %d\n", r.out.ctr.ctr1->array[0].status);
-                               return false;
+                       if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
+                               err_msg = talloc_asprintf(mem_ctx,
+                                               "DsCrackNames error: %d",
+                                               r.out.ctr->ctr1->array[0].status);
+                               torture_fail(tctx, err_msg);
                        }
+                       break;
                }
 
                switch (formats[i]) {
@@ -134,46 +148,44 @@ static bool test_DsCrackNamesMatrix(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                case DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL:  
                        n_from[i] = service_principal_name;
                        break;
+               case DRSUAPI_DS_NAME_FORMAT_UNKNOWN:
                case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY: 
                case DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN: 
                        n_from[i] = NULL;
                        break;
                default:
-                       n_from[i] = r.out.ctr.ctr1->array[0].result_name;
+                       n_from[i] = r.out.ctr->ctr1->array[0].result_name;
                        printf("%s\n", n_from[i]);
+                       break;
                }
        }
 
        for (i = 0; i < ARRAY_SIZE(formats); i++) {
                for (j = 0; j < ARRAY_SIZE(formats); j++) {
-                       r.in.req.req1.format_offered    = formats[i];
-                       r.in.req.req1.format_desired    = formats[j];
+                       r.in.req->req1.format_offered   = formats[i];
+                       r.in.req->req1.format_desired   = formats[j];
                        if (!n_from[i]) {
                                n_matrix[i][j] = NULL;
                                continue;
                        }
                        names[0].str = n_from[i];
-                       status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+                       status = dcerpc_drsuapi_DsCrackNames_r(p->binding_handle, 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("testing DsCrackNames (matrix) with name '%s' from format: %d desired format:%d failed - %s",
-                                      names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired, errstr);
-                               ret = false;
+                               err_msg = talloc_asprintf(mem_ctx,
+                                               "testing DsCrackNames (matrix) with name '%s' from format: %d desired format:%d failed - %s",
+                                               names[0].str, r.in.req->req1.format_offered, r.in.req->req1.format_desired, errstr);
+                               torture_fail(tctx, err_msg);
                        } else if (!W_ERROR_IS_OK(r.out.result)) {
-                               printf("testing DsCrackNames (matrix) with name '%s' from format: %d desired format:%d failed - %s",
-                                      names[0].str, r.in.req.req1.format_offered, r.in.req.req1.format_desired, 
-                                      win_errstr(r.out.result));
-                               ret = false;
+                               err_msg = talloc_asprintf(mem_ctx,
+                                               "testing DsCrackNames (matrix) with name '%s' from format: %d desired format:%d failed - %s",
+                                               names[0].str, r.in.req->req1.format_offered, r.in.req->req1.format_desired,
+                                               win_errstr(r.out.result));
+                               torture_fail(tctx, err_msg);
                        }
                        
-                       if (!ret) {
-                               return ret;
-                       }
-                       if (r.out.ctr.ctr1->array[0].status == DRSUAPI_DS_NAME_STATUS_OK) {
-                               n_matrix[i][j] = r.out.ctr.ctr1->array[0].result_name;
+                       if (r.out.ctr->ctr1->array[0].status == DRSUAPI_DS_NAME_STATUS_OK) {
+                               n_matrix[i][j] = r.out.ctr->ctr1->array[0].result_name;
                        } else {
                                n_matrix[i][j] = NULL;
                        }
@@ -191,28 +203,37 @@ static bool test_DsCrackNamesMatrix(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                        } else if (n_matrix[i][j] == NULL && formats[j] == DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL) {
                        } else if (n_matrix[i][j] == NULL && formats[j] == DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL) {
                        } else if (n_matrix[i][j] == NULL && n_from[j] != NULL) {
-                               printf("dcerpc_drsuapi_DsCrackNames mismatch - from %d to %d: %s should be %s\n", formats[i], formats[j], n_matrix[i][j], n_from[j]);
-                               ret = false;
+                               err_msg = talloc_asprintf(mem_ctx,
+                                               "dcerpc_drsuapi_DsCrackNames mismatch - from %d to %d: %s should be %s",
+                                               formats[i], formats[j], n_matrix[i][j], n_from[j]);
+                               torture_fail(tctx, err_msg);
                        } else if (n_matrix[i][j] != NULL && n_from[j] == NULL) {
-                               printf("dcerpc_drsuapi_DsCrackNames mismatch - from %d to %d: %s should be %s\n", formats[i], formats[j], n_matrix[i][j], n_from[j]);
-                               ret = false;
+                               err_msg = talloc_asprintf(mem_ctx,
+                                               "dcerpc_drsuapi_DsCrackNames mismatch - from %d to %d: %s should be %s",
+                                               formats[i], formats[j], n_matrix[i][j], n_from[j]);
+                               torture_fail(tctx, err_msg);
                        } else if (strcmp(n_matrix[i][j], n_from[j]) != 0) {
-                               printf("dcerpc_drsuapi_DsCrackNames mismatch - from %d to %d: %s should be %s\n", formats[i], formats[j], n_matrix[i][j], n_from[j]);
-                               ret = false;
+                               err_msg = talloc_asprintf(mem_ctx,
+                                               "dcerpc_drsuapi_DsCrackNames mismatch - from %d to %d: %s should be %s",
+                                               formats[i], formats[j], n_matrix[i][j], n_from[j]);
+                               torture_fail(tctx, err_msg);
                        }
                }
        }
-       return ret;
+
+       return true;
 }
 
 bool test_DsCrackNames(struct torture_context *tctx,
-                      struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
                       struct DsPrivate *priv)
 {
        NTSTATUS status;
+       const char *err_msg;
        struct drsuapi_DsCrackNames r;
+       union drsuapi_DsNameRequest req;
+       uint32_t level_out;
+       union drsuapi_DsNameCtr ctr;
        struct drsuapi_DsNameString names[1];
-       bool ret = true;
        const char *dns_domain;
        const char *nt4_domain;
        const char *FQDN_1779_name;
@@ -229,215 +250,187 @@ bool test_DsCrackNames(struct torture_context *tctx,
        const char *canonical_ex_name;
        const char *dom_sid;
        const char *test_dc = torture_join_netbios_name(priv->join);
+       struct dcerpc_pipe *p = priv->drs_pipe;
+       TALLOC_CTX *mem_ctx = priv;
 
        ZERO_STRUCT(r);
        r.in.bind_handle                = &priv->bind_handle;
        r.in.level                      = 1;
-       r.in.req.req1.codepage          = 1252; /* german */
-       r.in.req.req1.language          = 0x00000407; /* german */
-       r.in.req.req1.count             = 1;
-       r.in.req.req1.names             = names;
-       r.in.req.req1.format_flags      = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
+       r.in.req                        = &req;
+       r.in.req->req1.codepage         = 1252; /* german */
+       r.in.req->req1.language         = 0x00000407; /* german */
+       r.in.req->req1.count            = 1;
+       r.in.req->req1.names            = names;
+       r.in.req->req1.format_flags     = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
 
-       r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY;
-       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
+       r.in.req->req1.format_offered   = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY;
+       r.in.req->req1.format_desired   = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
+
+       r.out.level_out                 = &level_out;
+       r.out.ctr                       = &ctr;
 
        dom_sid = dom_sid_string(mem_ctx, torture_join_sid(priv->join));
        
        names[0].str = dom_sid;
 
-       printf("testing DsCrackNames with name '%s' desired format:%d\n",
-                       names[0].str, r.in.req.req1.format_desired);
+       torture_comment(tctx, "Testing DsCrackNames with name '%s' desired format:%d\n",
+                       names[0].str, r.in.req->req1.format_desired);
 
-       status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+       status = dcerpc_drsuapi_DsCrackNames_r(p->binding_handle, 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_DsCrackNames failed - %s\n", errstr);
-               ret = false;
+               err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
+               torture_fail(tctx, err_msg);
        } else if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
-               ret = false;
-       } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
-               printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
-               ret = false;
+               err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
+               torture_fail(tctx, err_msg);
+       } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
+               err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d",
+                                         r.out.ctr->ctr1->array[0].status);
+               torture_fail(tctx, err_msg);
        }
 
-       if (!ret) {
-               return ret;
-       }
-
-       dns_domain = r.out.ctr.ctr1->array[0].dns_domain_name;
-       nt4_domain = r.out.ctr.ctr1->array[0].result_name;
+       dns_domain = r.out.ctr->ctr1->array[0].dns_domain_name;
+       nt4_domain = r.out.ctr->ctr1->array[0].result_name;
 
-       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_GUID;
+       r.in.req->req1.format_desired   = DRSUAPI_DS_NAME_FORMAT_GUID;
 
-       printf("testing DsCrackNames with name '%s' desired format:%d\n",
-                       names[0].str, r.in.req.req1.format_desired);
+       torture_comment(tctx, "Testing DsCrackNames with name '%s' desired format:%d\n",
+                       names[0].str, r.in.req->req1.format_desired);
 
-       status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+       status = dcerpc_drsuapi_DsCrackNames_r(p->binding_handle, 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_DsCrackNames failed - %s\n", errstr);
-               ret = false;
+               err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
+               torture_fail(tctx, err_msg);
        } else if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
-               ret = false;
-       } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
-               printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
-               ret = false;
+               err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
+               torture_fail(tctx, err_msg);
+       } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
+               err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d",
+                                         r.out.ctr->ctr1->array[0].status);
+               torture_fail(tctx, err_msg);
        }
 
-       if (!ret) {
-               return ret;
-       }
-
-       priv->domain_dns_name = r.out.ctr.ctr1->array[0].dns_domain_name;
-       priv->domain_guid_str = r.out.ctr.ctr1->array[0].result_name;
+       priv->domain_dns_name = r.out.ctr->ctr1->array[0].dns_domain_name;
+       priv->domain_guid_str = r.out.ctr->ctr1->array[0].result_name;
        GUID_from_string(priv->domain_guid_str, &priv->domain_guid);
 
-       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
+       r.in.req->req1.format_desired   = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
 
-       printf("testing DsCrackNames with name '%s' desired format:%d\n",
-                       names[0].str, r.in.req.req1.format_desired);
+       torture_comment(tctx, "Testing DsCrackNames with name '%s' desired format:%d\n",
+                       names[0].str, r.in.req->req1.format_desired);
 
-       status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+       status = dcerpc_drsuapi_DsCrackNames_r(p->binding_handle, 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_DsCrackNames failed - %s\n", errstr);
-               ret = false;
+               err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
+               torture_fail(tctx, err_msg);
        } else if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
-               ret = false;
-       } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
-               printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
-               ret = false;
-       }
-
-       if (!ret) {
-               return ret;
+               err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
+               torture_fail(tctx, err_msg);
+       } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
+               err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d",
+                                         r.out.ctr->ctr1->array[0].status);
+               torture_fail(tctx, err_msg);
        }
 
        ldb = ldb_init(mem_ctx, tctx->ev);
        
-       realm_dn_str = r.out.ctr.ctr1->array[0].result_name;
+       realm_dn_str = r.out.ctr->ctr1->array[0].result_name;
        realm_dn =  ldb_dn_new(mem_ctx, ldb, realm_dn_str);
        realm_canonical = ldb_dn_canonical_string(mem_ctx, realm_dn);
 
-       if (strcmp(realm_canonical, 
+       if (strcmp(realm_canonical,
                   talloc_asprintf(mem_ctx, "%s/", dns_domain))!= 0) {
-               printf("local Round trip on canonical name failed: %s != %s!\n",
-                      realm_canonical, 
-                      talloc_asprintf(mem_ctx, "%s/", dns_domain));
-                   return false;
+               err_msg = talloc_asprintf(mem_ctx, "local Round trip on canonical name failed: %s != %s!",
+                                         realm_canonical,
+                                         talloc_asprintf(mem_ctx, "%s/", dns_domain));
+               torture_fail(tctx, err_msg);
        };
 
        realm_canonical_ex = ldb_dn_canonical_ex_string(mem_ctx, realm_dn);
 
        if (strcmp(realm_canonical_ex, 
                   talloc_asprintf(mem_ctx, "%s\n", dns_domain))!= 0) {
-               printf("local Round trip on canonical ex name failed: %s != %s!\n",
-                      realm_canonical, 
-                      talloc_asprintf(mem_ctx, "%s\n", dns_domain));
-                   return false;
+               err_msg = talloc_asprintf(mem_ctx, "local Round trip on canonical ex name failed: %s != %s!",
+                                         realm_canonical_ex,
+                                         talloc_asprintf(mem_ctx, "%s\n", dns_domain));
+               torture_fail(tctx, err_msg);
        };
 
-       r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
-       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
+       r.in.req->req1.format_offered   = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
+       r.in.req->req1.format_desired   = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
        names[0].str = nt4_domain;
 
-       printf("testing DsCrackNames with name '%s' desired format:%d\n",
-                       names[0].str, r.in.req.req1.format_desired);
+       torture_comment(tctx, "Testing DsCrackNames with name '%s' desired format:%d\n",
+                       names[0].str, r.in.req->req1.format_desired);
 
-       status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+       status = dcerpc_drsuapi_DsCrackNames_r(p->binding_handle, 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_DsCrackNames failed - %s\n", errstr);
-               ret = false;
+               err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
+               torture_fail(tctx, err_msg);
        } else if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
-               ret = false;
-       } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
-               printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
-               ret = false;
-       }
-
-       if (!ret) {
-               return ret;
+               err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
+               torture_fail(tctx, err_msg);
+       } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
+               err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d",
+                                         r.out.ctr->ctr1->array[0].status);
+               torture_fail(tctx, err_msg);
        }
 
-       priv->domain_obj_dn = r.out.ctr.ctr1->array[0].result_name;
+       priv->domain_obj_dn = r.out.ctr->ctr1->array[0].result_name;
 
-       r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
-       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
+       r.in.req->req1.format_offered   = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
+       r.in.req->req1.format_desired   = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
        names[0].str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, test_dc);
 
-       printf("testing DsCrackNames with name '%s' desired format:%d\n",
-              names[0].str, r.in.req.req1.format_desired);
+       torture_comment(tctx, "Testing DsCrackNames with name '%s' desired format:%d\n",
+                       names[0].str, r.in.req->req1.format_desired);
 
-       status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+       status = dcerpc_drsuapi_DsCrackNames_r(p->binding_handle, 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_DsCrackNames failed - %s\n", errstr);
-               ret = false;
+               err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
+               torture_fail(tctx, err_msg);
        } else if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
-               ret = false;
-       } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
-               printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
-               ret = false;
-       }
-
-       if (!ret) {
-               return ret;
+               err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
+               torture_fail(tctx, err_msg);
+       } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
+               err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d",
+                                         r.out.ctr->ctr1->array[0].status);
+               torture_fail(tctx, err_msg);
        }
 
-       FQDN_1779_name = r.out.ctr.ctr1->array[0].result_name;
+       FQDN_1779_name = r.out.ctr->ctr1->array[0].result_name;
 
-       r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
-       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
+       r.in.req->req1.format_offered   = DRSUAPI_DS_NAME_FORMAT_GUID;
+       r.in.req->req1.format_desired   = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
        names[0].str = priv->domain_guid_str;
 
-       printf("testing DsCrackNames with name '%s' desired format:%d\n",
-              names[0].str, r.in.req.req1.format_desired);
+       torture_comment(tctx, "Testing DsCrackNames with name '%s' desired format:%d\n",
+                       names[0].str, r.in.req->req1.format_desired);
 
-       status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+       status = dcerpc_drsuapi_DsCrackNames_r(p->binding_handle, 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_DsCrackNames failed - %s\n", errstr);
-               ret = false;
+               err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
+               torture_fail(tctx, err_msg);
        } else if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
-               ret = false;
-       } else if (r.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
-               printf("DsCrackNames failed on name - %d\n", r.out.ctr.ctr1->array[0].status);
-               ret = false;
-       }
-
-       if (!ret) {
-               return ret;
+               err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
+               torture_fail(tctx, err_msg);
+       } else if (r.out.ctr->ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
+               err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed on name - %d",
+                                         r.out.ctr->ctr1->array[0].status);
+               torture_fail(tctx, err_msg);
        }
 
-       if (strcmp(priv->domain_dns_name, r.out.ctr.ctr1->array[0].dns_domain_name) != 0) {
-               printf("DsCrackNames failed to return same DNS name - expected %s got %s\n", priv->domain_dns_name, r.out.ctr.ctr1->array[0].dns_domain_name);
-               return false;
+       if (strcmp(priv->domain_dns_name, r.out.ctr->ctr1->array[0].dns_domain_name) != 0) {
+               err_msg = talloc_asprintf(mem_ctx,
+                               "DsCrackNames failed to return same DNS name - expected %s got %s",
+                               priv->domain_dns_name, r.out.ctr->ctr1->array[0].dns_domain_name);
+               torture_fail(tctx, err_msg);
        }
 
        FQDN_1779_dn = ldb_dn_new(mem_ctx, ldb, FQDN_1779_name);
@@ -919,80 +912,137 @@ bool test_DsCrackNames(struct torture_context *tctx,
                int i;
                
                for (i=0; i < ARRAY_SIZE(crack); i++) {
+                       torture_comment(tctx, "Testing DsCrackNames with name '%s' desired format:%d\n",
+                                       crack[i].str, crack[i].format_desired);
+
                        const char *comment;
-                       r.in.req.req1.format_flags   = crack[i].flags;
-                       r.in.req.req1.format_offered = crack[i].format_offered; 
-                       r.in.req.req1.format_desired = crack[i].format_desired;
+                       r.in.req->req1.format_flags   = crack[i].flags;
+                       r.in.req->req1.format_offered = crack[i].format_offered;
+                       r.in.req->req1.format_desired = crack[i].format_desired;
                        names[0].str = crack[i].str;
                        
                        if (crack[i].comment) {
                                comment = talloc_asprintf(mem_ctx, "'%s' with name '%s' desired format:%d\n",
-                                                         crack[i].comment, names[0].str, r.in.req.req1.format_desired);
+                                                         crack[i].comment, names[0].str, r.in.req->req1.format_desired);
                        } else {
                                comment = talloc_asprintf(mem_ctx, "'%s' desired format:%d\n",
-                                      names[0].str, r.in.req.req1.format_desired);
+                                      names[0].str, r.in.req->req1.format_desired);
                        }
                        if (crack[i].skip) {
-                               printf("skipping: %s", comment);
+                               torture_comment(tctx, "skipping: %s", comment);
                                continue;
                        }
-                       status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
+                       status = dcerpc_drsuapi_DsCrackNames_r(p->binding_handle, 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_DsCrackNames failed on %s - %s\n", comment, errstr);
-                               ret = false;
+                               err_msg = talloc_asprintf(mem_ctx, "dcerpc_drsuapi_DsCrackNames failed - %s", errstr);
+                               torture_fail(tctx, err_msg);
                        } else if (!W_ERROR_IS_OK(r.out.result)) {
-                               printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
-                               ret = false;
-                       } else if (r.out.ctr.ctr1->array[0].status != crack[i].status) {
+                               err_msg = talloc_asprintf(mem_ctx, "DsCrackNames failed - %s", win_errstr(r.out.result));
+                               torture_fail(tctx, err_msg);
+                       } else if (r.out.ctr->ctr1->array[0].status != crack[i].status) {
                                if (crack[i].alternate_status) {
-                                       if (r.out.ctr.ctr1->array[0].status != crack[i].alternate_status) {
-                                               printf("DsCrackNames unexpected status %d, wanted %d or %d on: %s\n", 
-                                                      r.out.ctr.ctr1->array[0].status,
-                                                      crack[i].status,
-                                                      crack[i].alternate_status,
-                                                      comment);
-                                               ret = false;
+                                       if (r.out.ctr->ctr1->array[0].status != crack[i].alternate_status) {
+                                               err_msg = talloc_asprintf(mem_ctx,
+                                                               "DsCrackNames unexpected status %d, wanted %d or %d on: %s",
+                                                               r.out.ctr->ctr1->array[0].status,
+                                                               crack[i].status,
+                                                               crack[i].alternate_status,
+                                                               comment);
+                                               torture_fail(tctx, err_msg);
                                        }
                                } else {
-                                       printf("DsCrackNames unexpected status %d, wanted %d on: %s\n", 
-                                              r.out.ctr.ctr1->array[0].status,
-                                              crack[i].status,
-                                              comment);
-                                       ret = false;
+                                       err_msg = talloc_asprintf(mem_ctx,
+                                                       "DsCrackNames unexpected status %d, wanted %d on: %s\n",
+                                                       r.out.ctr->ctr1->array[0].status,
+                                                       crack[i].status,
+                                                       comment);
+                                       torture_fail(tctx, err_msg);
+                               }
+                       } else if (crack[i].expected_str &&
+                                  (!r.out.ctr->ctr1->count ||
+                                   !r.out.ctr->ctr1->array[0].result_name))
+                       {
+                               if (!r.out.ctr->ctr1->count) {
+                                       err_msg = talloc_asprintf(mem_ctx,
+                                                                 "DsCrackNames failed - got 0 entries, expected %s on %s",
+                                                                 crack[i].expected_str, comment);
+                                       torture_fail(tctx, err_msg);
+                               } else {
+                                       err_msg = talloc_asprintf(mem_ctx,
+                                                                 "DsCrackNames failed - got NULL pointer, expected %s on %s",
+                                                                 crack[i].expected_str, comment);
+                                       torture_fail(tctx, err_msg);
                                }
                        } else if (crack[i].expected_str
-                                  && (strcmp(r.out.ctr.ctr1->array[0].result_name, 
-                                             crack[i].expected_str) != 0)) {
-                               if (strcasecmp(r.out.ctr.ctr1->array[0].result_name, 
+                                  && (strcmp(r.out.ctr->ctr1->array[0].result_name,
+                                             crack[i].expected_str) != 0))
+                       {
+                               if (strcasecmp(r.out.ctr->ctr1->array[0].result_name,
                                               crack[i].expected_str) != 0) {
-                                       printf("DsCrackNames failed - got %s, expected %s on %s\n", 
-                                              r.out.ctr.ctr1->array[0].result_name, 
-                                              crack[i].expected_str, comment);
-                                       ret = false;
+                                       err_msg = talloc_asprintf(mem_ctx,
+                                                       "DsCrackNames failed - got %s, expected %s on %s",
+                                                       r.out.ctr->ctr1->array[0].result_name,
+                                                       crack[i].expected_str, comment);
+                                       torture_fail(tctx, err_msg);
                                } else {
-                                       printf("(warning) DsCrackNames returned different case - got %s, expected %s on %s\n", 
-                                              r.out.ctr.ctr1->array[0].result_name, 
-                                              crack[i].expected_str, comment);
+                                       torture_comment(tctx,
+                                                       "(warning) DsCrackNames returned different case - got %s, expected %s on %s\n",
+                                                       r.out.ctr->ctr1->array[0].result_name,
+                                                       crack[i].expected_str, comment);
                                }
                        } else if (crack[i].expected_dns
-                                  && (strcmp(r.out.ctr.ctr1->array[0].dns_domain_name, 
+                                  && (strcmp(r.out.ctr->ctr1->array[0].dns_domain_name,
                                              crack[i].expected_dns) != 0)) {
-                               printf("DsCrackNames failed - got DNS name %s, expected %s on %s\n", 
-                                      r.out.ctr.ctr1->array[0].result_name, 
-                                      crack[i].expected_str, comment);
-                               ret = false;
+                               err_msg = talloc_asprintf(mem_ctx,
+                                               "DsCrackNames failed - got DNS name %s, expected %s on %s",
+                                               r.out.ctr->ctr1->array[0].result_name,
+                                               crack[i].expected_str, comment);
+                               torture_fail(tctx, err_msg);
                        }
+
+                       torture_comment(tctx, "Testing DsCrackNames got %s\n", r.out.ctr->ctr1->array[0].result_name);
                }
        }
 
-       if (!test_DsCrackNamesMatrix(p, mem_ctx, priv, FQDN_1779_name, 
-                                    user_principal_name, service_principal_name)) {
-               ret = false;
-       }
+       return test_DsCrackNamesMatrix(tctx, priv, FQDN_1779_name,
+                                       user_principal_name, service_principal_name);
+}
+
+/**
+ * Test case setup for CrackNames
+ */
+static bool torture_drsuapi_cracknames_setup(struct torture_context *tctx, void **data)
+{
+       struct DsCrackNamesPrivate *priv;
+
+       *data = priv = talloc_zero(tctx, struct DsCrackNamesPrivate);
+
+       return torture_drsuapi_tcase_setup_common(tctx, &priv->base);
+}
+
+/**
+ * Test case tear-down for CrackNames
+ */
+static bool torture_drsuapi_cracknames_teardown(struct torture_context *tctx, void *data)
+{
+       struct DsCrackNamesPrivate *priv = talloc_get_type(data, struct DsCrackNamesPrivate);
+
+       return torture_drsuapi_tcase_teardown_common(tctx, &priv->base);
+}
+
+/**
+ * CRACKNAMES test suite implementation
+ */
+void torture_rpc_drsuapi_cracknames_tcase(struct torture_suite *suite)
+{
+       typedef bool (*run_func) (struct torture_context *test, void *tcase_data);
+
+       struct torture_tcase *tcase = torture_suite_add_tcase(suite, "cracknames");
+
+       torture_tcase_set_fixture(tcase,
+                                 torture_drsuapi_cracknames_setup,
+                                 torture_drsuapi_cracknames_teardown);
 
-       return ret;
+       torture_tcase_add_simple_test(tcase, "cracknames-test", (run_func)test_DsCrackNames);
 }