s4-smbtorture: strip trailing whitespace in RPC-SAMR.
[ira/wip.git] / source4 / torture / rpc / drsuapi_cracknames.c
index 9ebeab2a8b49341e90b5c6ffad050c29b8786012..dad0d918ca67eb101a2d3fb90ce5ef4d8c2ae0f7 100644 (file)
@@ -9,7 +9,7 @@
 
    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 "librpc/gen_ndr/ndr_drsuapi.h"
-#include "torture/rpc/drsuapi.h"
+#include "librpc/gen_ndr/ndr_drsuapi_c.h"
+#include "torture/rpc/rpc.h"
+#include "ldb/include/ldb.h"
+#include "libcli/security/security.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;
-       struct drsuapi_DsNameString names[1];
+       union drsuapi_DsNameRequest req;
+       int32_t level_out;
+       union drsuapi_DsNameCtr ctr;
+       struct dcerpc_pipe *p = priv->pipe;
+       TALLOC_CTX *mem_ctx = priv;
+
        enum drsuapi_DsNameFormat formats[] = {
+               DRSUAPI_DS_NAME_FORMAT_UNKNOWN,
                DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
                DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
                DRSUAPI_DS_NAME_FORMAT_DISPLAY,
@@ -48,6 +62,7 @@ static BOOL test_DsCrackNamesMatrix(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
                DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN
        };
+       struct drsuapi_DsNameString names[ARRAY_SIZE(formats)];
        int i, j;
 
        const char *n_matrix[ARRAY_SIZE(formats)][ARRAY_SIZE(formats)];
@@ -56,68 +71,77 @@ 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.unknown1          = 0x000004e4;
-       r.in.req.req1.unknown2          = 0x00000407;
-       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;
-               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);
-               
                status = dcerpc_drsuapi_DsCrackNames(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_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("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]) {
@@ -127,20 +151,22 @@ 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;
@@ -152,21 +178,20 @@ static BOOL test_DsCrackNamesMatrix(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                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;
                        }
@@ -184,50 +209,78 @@ 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 dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
-                             struct DsPrivate *priv, const char *test_dc)
+bool test_DsCrackNames(struct torture_context *tctx,
+                      struct DsPrivate *priv)
 {
        NTSTATUS status;
+       const char *err_msg;
        struct drsuapi_DsCrackNames r;
+       union drsuapi_DsNameRequest req;
+       int32_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;
+       struct ldb_context *ldb;
+       struct ldb_dn *FQDN_1779_dn;
+       struct ldb_dn *realm_dn;
+       const char *realm_dn_str;
+       const char *realm_canonical;
+       const char *realm_canonical_ex;
        const char *user_principal_name;
+       char *user_principal_name_short;
        const char *service_principal_name;
        const char *canonical_name;
        const char *canonical_ex_name;
+       const char *dom_sid;
+       const char *test_dc = torture_join_netbios_name(priv->join);
+       struct dcerpc_pipe *p = priv->pipe;
+       TALLOC_CTX *mem_ctx = priv;
 
        ZERO_STRUCT(r);
        r.in.bind_handle                = &priv->bind_handle;
        r.in.level                      = 1;
-       r.in.req.req1.unknown1          = 0x000004e4;
-       r.in.req.req1.unknown2          = 0x00000407;
-       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_CANONICAL;
-       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
-       names[0].str = talloc_asprintf(mem_ctx, "%s/", lp_realm());
+       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);
        if (!NT_STATUS_IS_OK(status)) {
@@ -235,27 +288,24 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                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);
        if (!NT_STATUS_IS_OK(status)) {
@@ -263,28 +313,25 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                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);
        if (!NT_STATUS_IS_OK(status)) {
@@ -292,55 +339,47 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                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);
        }
 
-       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);
+       ldb = ldb_init(mem_ctx, tctx->ev);
+       
+       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);
 
-       status = dcerpc_drsuapi_DsCrackNames(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_DsCrackNames failed - %s\n", errstr);
-               ret = False;
-       } 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 (strcmp(realm_canonical,
+                  talloc_asprintf(mem_ctx, "%s/", dns_domain))!= 0) {
+               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);
+       };
 
-       if (!ret) {
-               return ret;
-       }
+       realm_canonical_ex = ldb_dn_canonical_ex_string(mem_ctx, realm_dn);
 
-       priv->domain_obj_dn = r.out.ctr.ctr1->array[0].result_name;
+       if (strcmp(realm_canonical_ex, 
+                  talloc_asprintf(mem_ctx, "%s\n", dns_domain))!= 0) {
+               err_msg = talloc_asprintf(mem_ctx, "local Round trip on canonical ex name failed: %s != %s!",
+                                         realm_canonical,
+                                         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;
-       names[0].str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, test_dc);
+       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);
        if (!NT_STATUS_IS_OK(status)) {
@@ -348,28 +387,25 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                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;
-       }
-
-       FQDN_1779_name = 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_CANONICAL;
+       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);
        if (!NT_STATUS_IS_OK(status)) {
@@ -377,28 +413,25 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                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;
-       }
+       FQDN_1779_name = r.out.ctr->ctr1->array[0].result_name;
 
-       canonical_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;
+       names[0].str = priv->domain_guid_str;
 
-       r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
-       r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX;
-       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);
        if (!NT_STATUS_IS_OK(status)) {
@@ -406,23 +439,36 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                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;
+       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);
        }
 
-       canonical_ex_name = r.out.ctr.ctr1->array[0].result_name;
+       FQDN_1779_dn = ldb_dn_new(mem_ctx, ldb, FQDN_1779_name);
+
+       canonical_name = ldb_dn_canonical_string(mem_ctx, FQDN_1779_dn);
+       canonical_ex_name = ldb_dn_canonical_ex_string(mem_ctx, FQDN_1779_dn);
 
        user_principal_name = talloc_asprintf(mem_ctx, "%s$@%s", test_dc, dns_domain);
+
+       /* form up a user@DOMAIN */
+       user_principal_name_short = talloc_asprintf(mem_ctx, "%s$@%s", test_dc, nt4_domain);
+       /* variable nt4_domain includs a trailing \ */
+       user_principal_name_short[strlen(user_principal_name_short) - 1] = '\0';
+       
        service_principal_name = talloc_asprintf(mem_ctx, "HOST/%s", test_dc);
        {
                
@@ -432,8 +478,11 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                        const char *comment;
                        const char *str;
                        const char *expected_str;
+                       const char *expected_dns;
                        enum drsuapi_DsNameStatus status;
+                       enum drsuapi_DsNameStatus alternate_status;
                        enum drsuapi_DsNameFlags flags;
+                       bool skip;
                } crack[] = {
                        {
                                .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
@@ -442,6 +491,19 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                .expected_str = FQDN_1779_name,
                                .status = DRSUAPI_DS_NAME_STATUS_OK
                        },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .str = user_principal_name_short,
+                               .expected_str = FQDN_1779_name,
+                               .status = DRSUAPI_DS_NAME_STATUS_OK
+                       },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
+                               .str = FQDN_1779_name,
+                               .status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING
+                       },
                        {
                                .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
                                .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
@@ -464,6 +526,13 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                .expected_str = canonical_name,
                                .status = DRSUAPI_DS_NAME_STATUS_OK
                        },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_CANONICAL, 
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .str = canonical_name,
+                               .expected_str = FQDN_1779_name,
+                               .status = DRSUAPI_DS_NAME_STATUS_OK
+                       },
                        {
                                .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
                                .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX,
@@ -471,6 +540,13 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                .expected_str = canonical_ex_name,
                                .status = DRSUAPI_DS_NAME_STATUS_OK
                        },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX, 
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .str = canonical_ex_name,
+                               .expected_str = FQDN_1779_name,
+                               .status = DRSUAPI_DS_NAME_STATUS_OK
+                       },
                        {
                                .format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
                                .format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL,
@@ -530,6 +606,24 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
                                .str = "CN=Microsoft Corporation,L=Redmond,S=Washington,C=US",
                                .comment = "display name for Microsoft Support Account",
+                               .status = DRSUAPI_DS_NAME_STATUS_OK,
+                               .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE,
+                               .skip = torture_setting_bool(tctx, "samba4", false)
+                       },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .str = GUID_string2(mem_ctx, torture_join_user_guid(priv->join)),
+                               .comment = "Account GUID -> DN",
+                               .expected_str = FQDN_1779_name,
+                               .status = DRSUAPI_DS_NAME_STATUS_OK
+                       },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
+                               .str = GUID_string2(mem_ctx, torture_join_user_guid(priv->join)),
+                               .comment = "Account GUID -> NT4 Account",
+                               .expected_str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, test_dc),
                                .status = DRSUAPI_DS_NAME_STATUS_OK
                        },
                        {               
@@ -537,12 +631,22 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
                                .str = GUID_string2(mem_ctx, &priv->dcinfo.site_guid),
                                .comment = "Site GUID",
+                               .expected_str = priv->dcinfo.site_dn,
                                .status = DRSUAPI_DS_NAME_STATUS_OK
                        },
                        {
-                               .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
                                .str = GUID_string2(mem_ctx, &priv->dcinfo.computer_guid),
                                .comment = "Computer GUID",
+                               .expected_str = priv->dcinfo.computer_dn,
+                               .status = DRSUAPI_DS_NAME_STATUS_OK
+                       },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
+                               .str = GUID_string2(mem_ctx, &priv->dcinfo.computer_guid),
+                               .comment = "Computer GUID -> NT4 Account",
                                .status = DRSUAPI_DS_NAME_STATUS_OK
                        },
                        {
@@ -550,6 +654,7 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
                                .str = GUID_string2(mem_ctx, &priv->dcinfo.server_guid),
                                .comment = "Server GUID",
+                               .expected_str = priv->dcinfo.server_dn,
                                .status = DRSUAPI_DS_NAME_STATUS_OK
                        },
                        {
@@ -557,20 +662,15 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
                                .str = GUID_string2(mem_ctx, &priv->dcinfo.ntds_guid),
                                .comment = "NTDS GUID",
-                               .status = DRSUAPI_DS_NAME_STATUS_OK
-                       },
-                       {
-                               .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
-                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
-                               .str = SID_BUILTIN,
-                               .comment = "BUILTIN domain SID",
-                               .status = DRSUAPI_DS_NAME_STATUS_OK
+                               .expected_str = priv->dcinfo.ntds_dn,
+                               .status = DRSUAPI_DS_NAME_STATUS_OK,
+                               .skip = GUID_all_zero(&priv->dcinfo.ntds_guid)
                        },
                        {
                                .format_offered = DRSUAPI_DS_NAME_FORMAT_DISPLAY,
                                .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
                                .str = test_dc,
-                               .comment = "DISPAY NAME search for DC short name",
+                               .comment = "DISLPAY NAME search for DC short name",
                                .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
                        },
                        {
@@ -578,7 +678,24 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
                                .str = talloc_asprintf(mem_ctx, "krbtgt/%s", dns_domain),
                                .comment = "Looking for KRBTGT as a serivce principal",
-                               .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
+                               .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
+                               .expected_dns = dns_domain
+                       },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .str = talloc_asprintf(mem_ctx, "bogus/%s", dns_domain),
+                               .comment = "Looking for bogus serivce principal",
+                               .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
+                               .expected_dns = dns_domain
+                       },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .str = talloc_asprintf(mem_ctx, "bogus/%s.%s", test_dc, dns_domain),
+                               .comment = "Looking for bogus serivce on test DC",
+                               .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
+                               .expected_dns = talloc_asprintf(mem_ctx, "%s.%s", test_dc, dns_domain)
                        },
                        { 
                                .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
@@ -586,6 +703,15 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                .str = talloc_asprintf(mem_ctx, "krbtgt"),
                                .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
                        },
+                       { 
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .comment = "Looking for the kadmin/changepw service as a serivce principal",
+                               .str = talloc_asprintf(mem_ctx, "kadmin/changepw"),
+                               .status = DRSUAPI_DS_NAME_STATUS_OK,
+                               .expected_str = talloc_asprintf(mem_ctx, "CN=krbtgt,CN=Users,%s", realm_dn_str),
+                               .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
+                       },
                        {
                                .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
                                .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
@@ -594,6 +720,38 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                                       dns_domain),
                                .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
                        },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s", 
+                                                      test_dc, dns_domain,
+                                                      "BOGUS"),
+                               .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
+                               .expected_dns = "BOGUS"
+                       },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .str = talloc_asprintf(mem_ctx, "cifs/%s.%s@%s", 
+                                                      test_dc, "REALLY",
+                                                      "BOGUS"),
+                               .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
+                               .expected_dns = "BOGUS"
+                       },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .str = talloc_asprintf(mem_ctx, "cifs/%s.%s", 
+                                                      test_dc, dns_domain),
+                               .status = DRSUAPI_DS_NAME_STATUS_OK
+                       },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .str = talloc_asprintf(mem_ctx, "cifs/%s", 
+                                                      test_dc),
+                               .status = DRSUAPI_DS_NAME_STATUS_OK
+                       },
                        {
                                .format_offered = DRSUAPI_DS_NAME_FORMAT_GUID,
                                .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
@@ -654,11 +812,46 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                .str = talloc_asprintf(mem_ctx, "%s$", test_dc),
                                .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
                        },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .comment = "Full Machine account as service principal",
+                               .str = user_principal_name,
+                               .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
+                       },
                        {
                                .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
                                .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
                                .comment = "Realm as an NT4 domain lookup",
-                               .str = talloc_asprintf(mem_ctx, "%s\\", lp_realm()),
+                               .str = talloc_asprintf(mem_ctx, "%s\\", dns_domain),
+                               .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
+                       }, 
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .comment = "BUILTIN\\ -> DN",
+                               .str = "BUILTIN\\",
+                               .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
+                       }, 
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .comment = "NT AUTHORITY\\ -> DN",
+                               .str = "NT AUTHORITY\\",
+                               .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
+                       }, 
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .comment = "NT AUTHORITY\\ANONYMOUS LOGON -> DN",
+                               .str = "NT AUTHORITY\\ANONYMOUS LOGON",
+                               .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
+                       }, 
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .comment = "NT AUTHORITY\\SYSTEM -> DN",
+                               .str = "NT AUTHORITY\\SYSTEM",
                                .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
                        }, 
                        {
@@ -666,41 +859,99 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
                                .comment = "BUITIN SID -> NT4 account",
                                .str = SID_BUILTIN,
-                               .status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING
+                               .status = DRSUAPI_DS_NAME_STATUS_NO_MAPPING,
+                               .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
                        }, 
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .str = SID_BUILTIN,
+                               .comment = "Builtin Domain SID -> DN",
+                               .status = DRSUAPI_DS_NAME_STATUS_OK,
+                               .expected_str = talloc_asprintf(mem_ctx, "CN=Builtin,%s", realm_dn_str),
+                               .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
+                       },
                        {
                                .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
                                .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
                                .str = SID_BUILTIN_ADMINISTRATORS,
-                               .status = DRSUAPI_DS_NAME_STATUS_OK
+                               .comment = "Builtin Administrors SID -> DN",
+                               .status = DRSUAPI_DS_NAME_STATUS_OK,
+                               .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
                        },
                        {
                                .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
                                .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
                                .str = SID_BUILTIN_ADMINISTRATORS,
+                               .comment = "Builtin Administrors SID -> NT4 Account",
+                               .status = DRSUAPI_DS_NAME_STATUS_OK,
+                               .alternate_status = DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
+                       },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
+                               .str = SID_NT_ANONYMOUS,
+                               .comment = "NT Anonymous SID -> NT4 Account",
+                               .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
+                       },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
+                               .str = SID_NT_SYSTEM,
+                               .comment = "NT SYSTEM SID -> NT4 Account",
+                               .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
+                       },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .comment = "Domain SID -> DN",
+                               .str = dom_sid,
+                               .expected_str = realm_dn_str,
+                               .status = DRSUAPI_DS_NAME_STATUS_OK
+                       },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
+                               .comment = "Domain SID -> NT4 account",
+                               .str = dom_sid,
+                               .expected_str = nt4_domain,
                                .status = DRSUAPI_DS_NAME_STATUS_OK
                        },
                        {
                                .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
                                .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .comment = "invalid user principal name",
                                .str = "foo@bar",
-                               .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
+                               .status = DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY,
+                               .expected_dns = "bar"
                        },
+                       {
+                               .format_offered = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
+                               .format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+                               .comment = "invalid user principal name in valid domain",
+                               .str = talloc_asprintf(mem_ctx, "invalidusername@%s", dns_domain),
+                               .status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND
+                       }
                };
                int i;
                
                for (i=0; i < ARRAY_SIZE(crack); i++) {
-                       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;
+                       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;
                        names[0].str = crack[i].str;
                        
                        if (crack[i].comment) {
-                               printf("testing DsCrackNames '%s' with name '%s' desired format:%d\n",
-                                      crack[i].comment, names[0].str, r.in.req.req1.format_desired);
+                               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);
                        } else {
-                               printf("testing DsCrackNames with name '%s' desired format:%d\n",
-                                      names[0].str, r.in.req.req1.format_desired);
+                               comment = talloc_asprintf(mem_ctx, "'%s' desired format:%d\n",
+                                      names[0].str, r.in.req->req1.format_desired);
+                       }
+                       if (crack[i].skip) {
+                               torture_comment(tctx, "skipping: %s", comment);
+                               continue;
                        }
                        status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
                        if (!NT_STATUS_IS_OK(status)) {
@@ -708,68 +959,97 @@ BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                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 != crack[i].status) {
-                               printf("DsCrackNames unexpected error %d, wanted %d on name: %s\n", 
-                                      r.out.ctr.ctr1->array[0].status,
-                                      crack[i].status,
-                                      crack[i].str);
-                               ret = False;
-                       }
-                       if (crack[i].expected_str 
-                               && (strcmp(r.out.ctr.ctr1->array[0].result_name, 
-                                          crack[i].expected_str) != 0)) {
-                               printf("DsCrackNames failed - got %s, expected %s\n", 
-                                      r.out.ctr.ctr1->array[0].result_name, 
-                                      crack[i].expected_str);
-                               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 != crack[i].status) {
+                               if (crack[i].alternate_status) {
+                                       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 {
+                                       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
+                                  && (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) {
+                                       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 {
+                                       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,
+                                             crack[i].expected_dns) != 0)) {
+                               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);
                        }
                }
        }
 
-       if (!test_DsCrackNamesMatrix(p, mem_ctx, priv, FQDN_1779_name, 
-                                    user_principal_name, service_principal_name)) {
-               ret = False;
-       }
-
-       return ret;
+       return test_DsCrackNamesMatrix(tctx, priv, FQDN_1779_name,
+                                       user_principal_name, service_principal_name);
 }
 
-BOOL torture_rpc_drsuapi_cracknames(void)
+/**
+ * Test case setup for CrackNames
+ */
+static bool torture_drsuapi_cracknames_setup(struct torture_context *tctx, void **data)
 {
-        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_DRSUAPI_NAME,
-                                       DCERPC_DRSUAPI_UUID,
-                                       DCERPC_DRSUAPI_VERSION);
-       if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(mem_ctx);
-               return False;
-       }
+       struct DsCrackNamesPrivate *priv;
+
+       *data = priv = talloc_zero(tctx, struct DsCrackNamesPrivate);
 
-       printf("Connected to DRAUAPI pipe\n");
+       return torture_drsuapi_tcase_setup_common(tctx, &priv->base);
+}
 
-       ZERO_STRUCT(priv);
+/**
+ * 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);
 
-       ret &= test_DsBind(p, mem_ctx, &priv);
+       return torture_drsuapi_tcase_teardown_common(tctx, &priv->base);
+}
 
-       ret &= test_DsCrackNames(p, mem_ctx, &priv, lp_parm_string(-1, "torture", "host"));
+/**
+ * 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);
 
-       ret &= test_DsUnbind(p, mem_ctx, &priv);
+       struct torture_test *test;
+       struct torture_tcase *tcase = torture_suite_add_tcase(suite, "CRACKNAMES");
 
-       talloc_free(mem_ctx);
+       torture_tcase_set_fixture(tcase,
+                                 torture_drsuapi_cracknames_setup,
+                                 torture_drsuapi_cracknames_teardown);
 
-       return ret;
+       test = torture_tcase_add_simple_test(tcase, "CRACKNAMES-TEST", (run_func)test_DsCrackNames);
 }